ActiveX,安装不起作用

我想创build和部署一个ActiveX插件,一些小小的东西。 我只想显示一个消息框。

我已经为它创build了一个库项目并将其编译到一个DLL中。 当我通过命令行( regasm )在一台机器上注册dll时,该插件工作。

所以我现在需要创build一个安装程序,把它放在一个CAB文件并签名。

我已经安装了Visual Studio 2008来使用安装项目项目(但是如果有人可以解释怎么做的话,我可以使用2010年以后的InstallShield)。 我将我的DLL添加到应用程序文件夹,并将其标记为Register = vsdrpCOM ,我build立它,我得到.msi和.exe。

我想我只需要msi文件,而不是exe。 我用下面的内容创build了一个setup.inf文件:

 [version] signature="$CHICAGO$" AdvancedINF=2.0 [Setup Hooks] hook1=hook1 [hook1] run=msiexec.exe /i "%EXTRACT_DIR%\ActiveInstaller.msi" /qn 

要生成.cab文件,我使用makecab / f build.ddf命令。 这是我的.ddf文件:

 .Set DiskDirectoryTemplate=; .Set CabinetNameTemplate=ActiveInstaller.cab ../ActiveInstaller.msi ../setup.inf 

这生成了cab文件。 现在我需要签字。 目前,我使用自己签署的证书,我生成并安装在我的电脑(当我检查标志的文件,窗户说它是安全的)。 我使用另一个命令行是signtool signwizard (我也尝试从这里手动签名)。 然后文件签名,我上传到我的网站,我启动网站,我提示安装插件,我安装它。

但是,这不起作用,我不知道为什么。 我已经尝试了很多东西,包括不同的安装程序,不同的选项,不同的inf文件,不同的签名方法等等。

我发现的唯一的教程至less三岁,我不知道自从他们写了什么以来有什么改变。 以下是我使用的主要链接: http : //blogs.msdn.com/b/asiatech/archive/2011/12/05/how-to-develop-and-deploy-activex-control-in-c.aspx和另一个http://www.codeproject.com/Articles/24089/Create-ActiveX-in-NET-Step-by-Step

scheme:

所以,Pepo说的一切都是真实的,所以我把他的答案标记为接受。 我也在这里find了整个源代码(包括如何创build运行msi的.exe)的人。

问题可能是您尝试运行msiexec.exe,而这个exe文件不在cab文件中。 看到这个问题 (一定要向下滚动到由Roey 2009年8月5日张贴的令人难以置信的有用的示例代码)。 尝试创建一个setup.exe来运行msiexec.exe进程并安装你的msi,或者使用bootstrap setup.exe文件创建一个安装程序,并将其包含在cab中。

另外,您可能想要了解非管理员的activex安装 。

你的ActiveX DLL必须签名,你的ActiveX应该实现这个接口

 /// <summary> /// Options supported for the IObjectSafety interface /// </summary> [Serializable] [ComVisible(true)] public enum ObjectSafetyOptions { /// <summary> /// Indicates that the caller of the interface identified by riid might be untrusted. /// </summary> INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001, /// <summary> /// Indicates that the data passed into the interface identified by riid might be untrusted. /// </summary> INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002, /// <summary> /// Indicates that the caller of the interface identified by riid knows to use IDispatchEx. /// </summary> INTERFACE_USES_DISPEX = 0x00000004, /// <summary> /// Indicates that the data passed into the interface identified by riid knows to use IInternetHostSecurityManager. /// </summary> INTERFACE_USES_SECURITY_MANAGER = 0x00000008 }; /// <summary> /// Provides methods to get and set safety options. /// The IObjectSafety interface should be implemented by objects that have interfaces which support "untrusted" clients, such as scripts. /// It allows the owner of the object to specify which interfaces must be protected from "untrusted" use. /// </summary> [ComImport()] [Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IObjectSafety { /// <summary> /// Gets the safety options supported by an object and the safety options that are currently set for that object. /// </summary> /// <param name="iid">An interface identifier for a given object</param> /// <param name="pdwSupportedOptions">Receives the address of a DWORD representing all the options supported for the interface identified by riid.</param> /// <param name="pdwEnabledOptions">Receives the address of a DWORD representing all the options currently enabled for the interface identified by riid.</param> /// <returns>Returns one of the following values: /// S_OK - the object is safe for loading /// E_NOINTERFACE - the riid parameter specifies an interface that is unknown to the object</returns> [PreserveSig] long GetInterfaceSafetyOptions(ref Guid iid, out int pdwSupportedOptions, out int pdwEnabledOptions); /// <summary> /// Returns whether an object is safe for initialization or scripting, as specified. /// </summary> /// <param name="iid">An iInterface identifier for the object to be made safe.</param> /// <param name="dwOptionSetMask">A mask representing the options to be validated.</param> /// <param name="dwEnabledOptions">A DWORD representing all the options currently enabled for the interface identified by riid. </param> /// <returns>Returns one of the following values: /// S_OK - the object is safe for loading /// E_NOINTERFACE - the riid parameter specifies an interface that is unknown to the object /// E_FAIL - the dwOptionSetMask parameter specifies an option that is not supported by the object</returns> [PreserveSig] long SetInterfaceSafetyOptions(ref Guid iid, int dwOptionSetMask, int dwEnabledOptions); }; 

我使用高级安装程序来创建msi安装程序,我设置了DLL注册 。 高级安装程序然后生成所有必要的注册表项。

在我的测试中,最终的inf文件是

 [version] signature="$CHICAGO$" AdvancedINF=2.0 [Deployment] InstallScope=user|machine [Setup Hooks] install=install [install] run="""%EXTRACT_DIR%\runmsi.exe""" """%EXTRACT_DIR%\simpleactivex.msi""" 

请注意三重引号。 他们很重要。

我用这个ddl

 .Set DiskDirectoryTemplate=. .Set CabinetNameTemplate=simpleactivex.cab runmsi.exe simpleactivex.msi simpleactivex.inf 

我使用这个命令建立驾驶室

 "c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\signtool.exe" sign /sha1 9A15DC8F51773C557BA2F75CF155F8CBD367A8E1 /tr http://tsa/tsa /d SimpleActiveX /du "http://yourcompany.com" /v runmsi.exe simpleactivex.msi makecab /V3 /F make.ddl "c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\signtool.exe" sign /sha1 9A15DC8F51773C557BA2F75CF155F8CBD367A8E1 /tr http://tsa/tsa /d simpleactivex /du "http://yourcompany.com" /v simpleactivex.cab 

runmsi.exe是一个虚拟的exe文件,运行msiexec给定的参数。 或者,您可以使用exe安装程序或引导程序exe和msi安装程序。 重要的一点是,IE不允许在cab文件之外运行任何东西。 所以你必须做这个黑客。

调试时,我用这个虚拟的HTML页面

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <html> <head> <title>WebForm1</title> </head> <body style="margin-top: 0px; margin-left: 0px;"> <OBJECT id="SimpleActiveXCtrl" classid="clsid:C0082E22-8A19-4600-8332-D31C4055291A" codebase="SimpleActiveX.CAB"></OBJECT> <script language="javascript"> // da sa volat z JS metody ActiveXu alebo nastavit property function OpenActiveX() { try { alert(document.SimpleActiveXCtrl.HelloWorld("hello")); } catch(Err) { alert(Err.description); } } </script> </body> </html>