About neohope

一直在努力,还没想过要放弃...

使用WebBrower修改网页iFrame中的内容

由于很变态的中国式需求,我们需要在自己的网站中,嵌入第三方厂商的网站。
而这个第三方的网站中,使用了几层的iFrame,同时使用了基于IE的Activex控件。
由于双方的控件风格差距太大,所以需要替换CSS样式,同时要删掉部分与我们网站冲突的内容。

想了几种方法:
1、说服对方进行调整,但经过接触,了解到其超级不靠谱,只能靠自己了。
2、直接通过iFrame嵌入对方网站,用JS进行修改。可是跨站修改,浏览器不同意啊。
3、自己写个控件,嵌入到自己网页中,在控件中调用对方URL,并通过WebBrowser控件修改CSS及HTML。问题是,IE中,不能再直接嵌入一个WebBrowser控件,主要出于安全考虑。(如果IE允许这样操作的话,我只需要在WebBrowser中指向同一个URL,就可以无限调用,耗光资源,其他的事情,有太多可以做了)自己用很挫的方法实现了这个功能,后来考虑到稳定性,放弃了。
4、使用非基于IE的Web插件,在控件中调用对方URL,并通过控件修改CSS及HTML。比如Flash或者CefSharp,但问题是,非IE核心如何调用Activex控件啊。
5、限制入口,基于WebBrowser定制IE浏览器

最后使用了方法5,说实话,真烦。

这里把通过WebBrowser修改CSS及HTML的方法说一下,下面是我写的一段测试用代码,请按自己的实际情况修改:

        //替换样式
        //webMain是WebBrowser控件的名称
        //NewStyle.css中是要替换的样式
        private void modifyStyle()
        {
            int frameNum = webMain.Document.Window.Frames.Count;
            if (frameNum == 2)
            {
                IHTMLDocument2 leftIFrame = webMain.Document.Window.Frames[0].Document.DomDocument as IHTMLDocument2;

                int length = leftIFrame.styleSheets.length;
                IHTMLStyleSheet styleSheet = leftIFrame.createStyleSheet(@"", length + 1);

                TextReader reader = new StreamReader(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "NewStyle.css"));
                string style = reader.ReadToEnd();
                styleSheet.cssText = style;
            }
        }

        //删除tree节点下的div,只保留特定的一个节点
        private void delDiv(String flowid)
        {
            int frameNum = webMain.Document.Window.Frames.Count;
            if (frameNum == 2)
            {
                IHTMLDocument3 leftIFrame = webMain.Document.Window.Frames[0].Document.DomDocument as IHTMLDocument3;
                foreach (dynamic e in leftIFrame.getElementById("tree").children)
                {
                    String ret = e.InnerText;
                    if (!ret.Contains(flowid))
                    {
                        e.parentNode.removeChild(e);
                    }
                }
            }
        }

我可怜的Nexus7平板啊

想来Nexus7已经挂了4、5个月了吧,今年我的电子产品挂得真是干脆,各种悲剧啊。

其实起因很简单,我从广州回上海时,没有带Nexus7。

当我重新回到广州后,发现没什么电了,但可以更新,于是点击了更新。

更新后,无论如何,Nexus7都会卡在Google的启动界面。

当时心情正郁闷而且Nexus7很久没有Root过了,于是准备开始Root。

网上下了最新的Root工具,然后开始Root。

但过了好久都没有任何反应。

立即清楚,这次悲剧了。

重启后,发现Bootloader已经没有了。

网上各种查找资料,发现Nexus7的1代,这个问题我不是第一个遇到,但大家的解决方法,都是“返厂”。

老子代购的,怎么“返厂”啊。

于是在广州、上海找了不少人帮忙看,发现,我的刷机水平,比他们中95%的人都强。
要是能进入fastboot,我找你干吗?

后来,有人说刷字库可以解决问题,找了两家试试,甚至发快递到深圳修,发现都搞不定。

唉。。。

非主流的悲剧啊。。。

估计是没什么希望了。。。

刷机有风险,入行需谨慎。。。

如何在WinForm程序中测试C#写的COM控件

在网上查了一下,应该是不能直接在WinForm中使用C#写的COM控件。
但可以用变通的方法测试COM控件中的方法,比如,下面的例子中,就可以测试addTest方法:

Type comType = null;
object comObject = null;

//这个无效,不知道为什么
//comType = Type.GetTypeFromProgID("XX.CSControl.TestControl");
if (comType == null)
{
    Guid guid = new Guid("4B4D1D4C-16CA-48E0-87A4-AFF3C6CB6E26");
    comType = Type.GetTypeFromCLSID(guid);
}

try
{
    comObject = Activator.CreateInstance(comType);
}
catch(Exception e)
{
    MessageBox.Show(e.Message);
    return;
}

object[] args = new object[2];
args[0] = 1;
args[1] = 2;

int ret = (int)comType.InvokeMember("addTest", BindingFlags.InvokeMethod, null, comObject, args);
if(ret==3)
{
    MessageBox.Show("TestOK");
}

C#开发COM组件(Web)

这两天由于一个很挫的需求,准备开发一个COM组件,由于所有用户的客户端都安装有.Net Framework 4.0,加上工期紧的很,就准备用C#上了。

1、首先,建立一个Windows Forms Control Library项目

2、项目属性,Build,选中,Register for COM interop

3、项目属性,Signing,选中,Sign the assembly,并生成一个签名文件

4、编辑AssemblyInfo.cs,查看是否有下面两行,没有要添加

using System.Security;

[assembly: AllowPartiallyTrustedCallers()] 
[assembly: ComVisible(true)]

5、添加接口文件IObjectSafety.cs

using System;
using System.Runtime.InteropServices;

namespace CSControl
{
    //不要修改GUID
    [ComImport]
    [Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectSafety
    {
        [PreserveSig]
        int GetInterfaceSafetyOptions(ref Guid riid,
                      [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions,
                      [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);

        [PreserveSig()]
        int SetInterfaceSafetyOptions(ref Guid riid,
                      [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask,
                      [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
    }
}

6、控件类要同时实现UserControl, IObjectSafety两个接口

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Security;

namespace CSControl
{
    //更改为你自己的UUID
    [ComVisible(true)]
    [Guid("4B4D1D4C-16CA-48E0-87A4-AFF3C6CB6E26")]
    [ProgId("XX.CSControl.TestControl")]
    public partial class TestControl : UserControl, IObjectSafety
    {
        //===================================================
        //实现IObjectSafety接口
        //不要修改下面的GUID
        private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
        private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
        private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
        private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
        private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";

        private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
        private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
        private const int S_OK = 0;
        private const int E_FAIL = unchecked((int)0x80004005);
        private const int E_NOINTERFACE = unchecked((int)0x80004002);

        private bool _fSafeForScripting = true;
        private bool _fSafeForInitializing = true;

        public int GetInterfaceSafetyOptions(ref Guid riid,
                             ref int pdwSupportedOptions,
                             ref int pdwEnabledOptions)
        {
            int Rslt = E_FAIL;

            string strGUID = riid.ToString("B");
            pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForScripting == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForInitializing == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        public int SetInterfaceSafetyOptions(ref Guid riid,
                             int dwOptionSetMask,
                             int dwEnabledOptions)
        {
            int Rslt = E_FAIL;

            string strGUID = riid.ToString("B");
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) &&
                         (_fSafeForScripting == true))
                        Rslt = S_OK;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) &&
                         (_fSafeForInitializing == true))
                        Rslt = S_OK;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        //===================================================
        //实现UserControl接口
        ......
    }
}

7、编译,控件会自动注册

8、写个网页,测试一下

<!--CSControl-->
<object id="testControl" width="500" height="500" classid ="clsid:4B4D1D4C-16CA-48E0-87A4-AFF3C6CB6E26"&#93;</object>

9、打CAB包,发布到网站
由于是自己生产的签名文件,所以会有安全提示。最简单的方法是从靠谱的CA那里买一个证书,还有办法就是将证书导入到IE的信任列表中,再就是将IE的安全级别降为最低。

10、当然也可以通过命令行本地注册

rem 注册
regtlibv12 %PATH_TO_DLL_AND_TLB_FOLDER%\CSControl.tlb

rem 反注册
regtlibv12 -u %PATH_TO_DLL_AND_TLB_FOLDER%\CSControl.tlb

C#开发COM组件(本地)

本篇文章介绍了如何用C#写一个简单的COM组件(Dll)。

1、新建一个C# Class Library项目“CSCOMTest”

2、项目中,新增一个接口文件IJustATestCOM.cs,Guid要自己生成

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace CSCOMTest
{
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [Guid("A5377871-3334-4679-A3CD-84312B1DCD3E")]
    public interface IJustATestCOM
    {
        int Add(int a, int b);
        String SayHiTo(String someOne);
    }
}

3、项目中,新增一个类文件JustATestCOM.cs,Guid要自己生成

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace CSCOMTest
{
    [ComVisible(true)]
    [Guid("A6E4F456-32C1-4C8E-9171-D616B5DA1E20")]
    [ProgId("CSCOMTest.JustATestCOM")]
    public class JustATestCOM : IJustATestCOM
    {
        public int Add(int a, int b)
        {
            return a + b;
        }

        public String SayHiTo(String someOne)
        {
            return "Hi " + someOne + "!";
        }
    }
}

4、项目属性->Application->Assembly Infomation->Make Assembly COM-Visible->打勾

5、项目属性->Signing->Sign the assembly->打勾
项目属性->Signing->Choose a strong name key file->New

6、编译

7、注册

#这里一定要用正确版本的gacutil及RegAsm
C:\VBS\DNFW4\gacutil.exe /i CSCOMTest.dll
C:\VBS\DNFW4\RegAsm.exe CSCOMTest.dll

8、反注册

#这里一定要用正确版本的gacutil及RegAsm
C:\VBS\DNFW4\gacutil.exe /u CSCOMTest
C:\VBS\DNFW4\RegAsm.exe /u CSCOMTest.dll

9、调用测试

'发生错误时,继续运行
On Error Resume Next

'清除错误状态
Err.Clear

Set Obj=CreateObject("CSCOMTest.JustATestCOM")

'输出错误信息
If Err.Number <> 0 Then
    WScript.Echo "Error: " & Err.Number
    WScript.Echo "Error (Hex): " & Hex(Err.Number)
    WScript.Echo "Source: " &  Err.Source
    WScript.Echo "Description: " &  Err.Description
    'Err.Clear
    '退出程序
    WScript.Quit(Err.Number)
End If

'On Error Goto 0

WScript.Echo obj.Add(1,2)
WScript.Echo obj.SayHiTo("dcom")


set obj=Nothing

10、生成tlb文件

regasm CSCOMTest.dll /tlb:CSCOMTest.tlb

iPhone4数据备份成功

//=========================================================
上周在天津,找了个iPhone的修理店,里面的小师傅说我的iPhone4主板短路了,不能修。

我和他们商量,帮我换块电池吧,结果被一大三小四个师傅一起鄙视,说是会引起火灾。

估计到最后他们也没明白,我只是想备份数据,手机不打算用了。

但人家说就是不可能开机了,靠,鄙视,有电明明能开机的。

没办法,自己X宝买了个电池。

//=========================================================
昨天,终于回到上海。

电池早就到了,于是下班的时候,换上新电池,开始了手机数据备份。。。

换了电池,开机,成功了!

哈哈哈哈哈。。。

马上备份。。。

然后手机开始发烫,关到飞行模式也不行。。。

只好备份一部分就关机散热,中途自己一顿人工降温。。。

弄了半个小时,终于备份完成了。。。

//=========================================================
后记:
昨天晚上去买5S,晚上去中山公园的永乐买,结果没32G的,就跑到了陆家嘴Apple旗舰店。
买是买到了,但发现,卡必须是nano的,没有卡没法激活。
靠。。。
再等等吧。。。

//=========================================================
卡激活了,还是去联通剪的卡,还在下雨,好坑的说
终于用上了:)

//=========================================================
鄙视Apple,刚买了不到一个月,降价了1200,一张机票没了:(

获取Eclipse执行文件根目录

Eclipse插件获取Eclipse的根目录

String eclipseRoot = Platform.getInstallLocation().getURL().toString();
eclipseRoot = eclipseRoot.replace("file:/", "");

Eclipse插件获取Workspace根目录

//方法1
String workspaceRoot= Platform.getInstanceLocation().getURL().toString();
workspaceRoot = workspaceRoot.replace("file:/", "");

//方法2
String path = Activator.getDefault().getStateLocation().makeAbsolute().toFile().getAbsolutePath();

Eclipse插件获取User根目录

String userHome = Platform.getUserLocation().getURL().toString();
userHome = userHome.replace("file:/", "");

Elclipse插件获取Bundle的OSGI路径

//方法1
String bundlePath = Activator.getDefault().getBundle().getLocation();
String pathBundle = bundlePath.replace("reference:file:/","");

//方法2
Bundle bundle = Platform.getBundle("bundle id");
URL urlentry = bundle.getEntry("bundle resource path");
String strEntry = FileLocator.toFileURL(urlentry).getPath();

//方法3
String pathClass = KeyHandler.class.getResource("resource path").getFile();	

Build Jetty Lesson101

1. Download source code from Eclipse.
For example, I used this one:

From here: http://download.eclipse.org/jetty/
Get this one: jetty-8.1.15.v20140411

2. Read this:

http://docs.codehaus.org/display/JETTY/Building+from+Source

3. Prepare JDK and Maven:

SET JAVA_HOME=C:\Languages\Java\JDK\jdk_x86_1.6.0_34
SET MAVEN_HOME=C:\Languages\Java\JavaTools\apache-maven-3.0.4
SET PATH=%MAVEN_HOME%\bin;%JAVA_HOME%\bin;%PATH%
CMD

4. Run “mvn install”

5. Use eclipse to import maven project

JS钩子示例

// JS钩子示例
// JS对于不同消息类型,实现了不同的调用链
// 事件触发的时候,根据消息类型,调用对应的调用链
// 同一个钩子函数,安装多次,会根据安装顺序,调用多次
// 可以对比Windows API的钩子如SetWindowsHookEx等,原理上很相似

// 储存全部事件的调用链函数列表
function hooks() {
    this.queue = new Array();
}

// 通过addAction,生成调用链
hooks.prototype.addAction = function (hook, func) {
    // 某一个事件的调用链函数列表
    if(this.queue[hook]==undefined){
        this.queue[hook] = new Array(); 
    }
    
    if (typeof func == 'function') {
        this.queue[hook].push(func);
    } else if (typeof func == 'string') {
        this.queue[hook].push(this.window[func]);
    }
}

// 通过doAction,实现调用链
hooks.prototype.doAction = function (hook) {
    var parameters = Array.prototype.slice.call(arguments, 1); 
    var functions = this.queue[hook]; 
    for (var i = 0; i < functions.length; i++) {
        this.call_user_func_array(functions[i], parameters);
    }
    return true;
}

// 实现具体钩子函数调用
hooks.prototype.call_user_func_array = function(cb, parameters) {
    if (typeof cb === 'string') {
        func = (typeof this[cb] === 'function') ? this[cb] : func = (newFunction(null, 'return ' + cb))();
    } else if (cb instanceof Array) {
        func = (typeof cb[0] == 'string') ? eval(cb[0] + "['" + cb[1] + "']") : func = cb[0][cb[1]];
    } else if (typeof cb === 'function') {
        func = cb;
    } if (typeof func != 'function') {
        throw new Error(func + ' is not a valid function');
    } if (typeof parameters == 'undefined') {
        var tmp_ary = [];
        var parameters = Array.prototype.slice.call(tmp_ary, 1);
    } return (typeof cb[0] === 'string') ? func.apply(eval(cb[0]), parameters) : (typeof cb[0] !== 'object') ? func.apply(null, parameters) : func.apply(cb[0], parameters);
}

function func1() {
    console.log("func1");
}

function func2() {
    console.log("func2");
}

function func3() {
    console.log("func3");
}

// 使用示例
var myhook = new hooks();
myhook.addAction("loaded", func3);
myhook.addAction("loaded", func2);
myhook.addAction("loaded", func1);
myhook.addAction("loaded", func3);
myhook.doAction("loaded")