ActiveX,安装不起作用 [英] ActiveX, installation doesn't work

查看:24
本文介绍了ActiveX,安装不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建和部署一个很小的 ​​ActiveX 插件.我只想显示一个消息框.

I want to create and deploy an ActiveX plugin, somethign really small. I just want to display a message box.

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

I've created a library project for it and compile it to a DLL. The plugin works when I register the dll via command line (regasm) on one machine.

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

So I now need to create an installer, put it inside a CAB file and sign it.

我已经安装了 Visual Studio 2008 以使用 Setup Project 项目(但如果有人可以解释如何操作,我可以使用 2010+ 的 InstallShield).我将我的 dll 添加到应用程序文件夹并将其标记为 Register = vsdrpCOM 并构建它并获得 .msi 和 .exe.

I've installed Visual Studio 2008 to use Setup Project project (but I can use the InstallShield from 2010+ if anyone can explain how to do it). I add my dll to the Application Folder and mark it as Register = vsdrpCOM and I build it and I get a .msi and .exe.

我想我只需要 msi 文件而不需要 exe.我创建了一个包含空闲内容的 setup.inf 文件:

I think I only need the msi file and not the exe. I created a setup.inf file with the fallowing content :

[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 文件:

To build the .cab file I use the command makecab /f build.ddf. Here is my .ddf file :

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

这生成了 cab 文件.现在我需要签字.目前我使用了我生成并安装在我的电脑上的自签名证书(当我检查签名 cab 文件时,windows 说它是安全的).我使用另一个命令行 signtool signwizard(我也尝试从 此处).然后对文件进行签名并将其上传到我的网站,然后启动网站,系统提示我安装插件并安装它.

This generated the cab file. Now I need to sign it. At the moment I used a self signed certificate that I generated and installed on my pc (when I check the sign cab file, windows says it's safe). I use another command line which is signtool signwizard (I also try to sign it manually from here). Then the file is signed and I upload it to my website, I launch the website, I'm prompted to install the plugin and I install it.

但是,它不起作用,我不知道为什么.我尝试了很多东西,使用不同的安装程序、不同的选项、不同的 inf 文件、不同的签名方法等.

But then, it does not work, I have no idea why. I've tried so much stuff, with different installer, different options, different inf file, different signing method, etc.

我发现的唯一教程至少已经三年了,我不知道自它们编写以来是否有任何变化.这是我使用的主要链接: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

The only tutorial that I found are at least three years old, I don't know if anything as changed since they were wrote. Here are the main link that I used : http://blogs.msdn.com/b/asiatech/archive/2011/12/05/how-to-develop-and-deploy-activex-control-in-c.aspx and another one http://www.codeproject.com/Articles/24089/Create-ActiveX-in-NET-Step-by-Step

解决方案:

所以,Pepo 所说的一切都是真实的,所以我将他的回答标记为已接受.我还找到了一个完整的源代码(包括如何创建运行 msi 的 .exe)此处.

So, everything Pepo said is true so I marked his answer as accepted. I also found someone who the whole source code (including how to create the .exe which runs the msi) here.

推荐答案

问题可能是您尝试运行 msiexec.exe 而此 exe 不在 cab 文件中.请参阅 这个问题(一定要向下滚动到 Roey 2009 年 8 月 5 日发布的非常有用的示例代码).尝试创建一个 setup.exe 来运行进程 msiexec.exe 并安装您的 msi,或者使用引导 setup.exe 文件制作一个安装程序并将两者都包含在 cab 中.

The problem might be that you try to run msiexec.exe and this exe is not in the cab file. See this question (be sure to scroll down to the incredibly helpful sample code posted by Roey 5 Aug 2009). Try to either create a setup.exe that will run process msiexec.exe and install your msi or make an installer with a bootstrap setup.exe file and include both in the cab.

此外,您可能想阅读非-管理员 activex 安装.

你的activex dll必须被签名并且你的activeX应该实现这个接口

Your activex dll has to be signed and your activeX should implement this interface

/// <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 注册.高级安装程序然后生成所有必要的注册表项.

I used advanced installer to create msi installer and I set dll registration. Advanced installer then generated all necessary registry keys.

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

In my test the final inf file was

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

请注意三重引号.它们很重要.

Please note the triple quotes. They are important.

我用过这个ddl

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

我使用这个命令构建 cab

And I build cab using this commands

"c:Program Files (x86)Microsoft SDKsWindowsv7.0ABinsigntool.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 SDKsWindowsv7.0ABinsigntool.exe" sign /sha1 9A15DC8F51773C557BA2F75CF155F8CBD367A8E1 /tr http://tsa/tsa /d simpleactivex /du "http://yourcompany.com" /v simpleactivex.cab

runmsi.exe 是一个虚拟的 exe 文件,它使用给定的参数运行 msiexec.或者,您可以使用 exe 安装程序或 bootstrap exe 和 msi 安装程序.需要注意的重要部分是 IE 不允许运行 cab 文件之外的任何内容.因此,您必须执行此操作.

runmsi.exe is a dummy exe file that runs msiexec with given parameters. Alternatively you could use exe installer or bootstrap exe and msi installer. The important part to note is that IE will not allow to run anything outside the cab file. Therefore you have to do this hack.

调试时我使用了这个虚拟的 html 页面

When debugging I used this dummy html page

<!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>

这篇关于ActiveX,安装不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆