为什么 ActiveX 显示“未知发布者”使用签名证书时出错?

发布于 2024-09-27 10:57:54 字数 6128 浏览 4 评论 0原文

我已经努力了几天,试图让一个简单的 ActiveX DLL 工作,但没有成功,尽管研究了几个我在网上找到的有关该主题的文章。

我怀疑我有几处编码错误,因为我对此并不熟悉,而且大多数有关该主题的文章都已过时。我正在使用 Visual Studio 2008 并一直在使用 Windows SDK v7.1 用于数字签名。

我想做的是将客户端 machineName 从环境类返回到网页(并最终返回到 Web 服务器)。

这是我的 C# 类:

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.Win32;

namespace GetClientInfo101
{
    [Guid("121C3E0E-DC6E-45dc-952B-A6617F0FAA32")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [ComVisible(true)]
    public interface IGetClient
    {
        [DispId(1)]
        string GetClient();
    }
    [Guid("5085C918-0236-4828-BDFA-063FEE57C69B")]
    [ProgId("getClientInfoAx.CGetClient")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(IGetClient))]
    [System.ComponentModel.ToolboxItem(true)]
    [ComVisible(true)]
    public class CGetClient : IGetClient
    {
        public string GetClient()
        {
           return Environment.MachineName;
        }
    }
}

这是我的程序集:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("GetClientInfo101")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GetClientInfo101")]
[assembly: AssemblyCopyright("Copyright © N/A 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1bf2a0bc-f9cb-4f68-8990-5caaf3ab525d")]

// Version information for an assembly consists of the following four values:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")

这是我的网站母版页上的对象标记和脚本。 **注意:我收到错误

Microsoft JScript 运行时错误:自动化服务器无法创建对象

在“var”执行上创建对象**:

<object id="getClientInfo" name="GetClientInfo101" classid="clsid:5085C918-0236-4828-BDFA-063FEE57C69B"
        codebase="GetClientInfo/GetClientInfoAX.cab#version=1,0,0,0">
</object>

<script type="text/javascript">
    function OpenActiveX()
    {
        var objGetClientInfo = new ActiveXObject("GetClientInfoAx.CGetClient");
        if(objGetClientInfo != null)
         {
             //For testing only
             alert(objGetClientInfo.GetClient());
         }
     }
</script>

然后我手动创建了一个 .inf 文件,如下所示:

[version]
    signature="$CHICAGO$"
    AdvancedINF=2.0
[Add.Code]
    GetClientInfo101.dll=GetClientInfo101.dll
    GetClientInfo101.inf=GetClientInfo101.inf
[GetClientInfo101.dll]
    file-win32-x86=thiscab
    clsid={5085C918-0236-4828-BDFA-063FEE57C69B}
    FileVersion=1,0,0,0
    RegisterServer=yes
[GetClientInfo101.inf]
    file=thiscab

但是,当我构建 .cab 文件时,我我还得到 .OSD 文件输出到 .cab 如下(我担心同时存在 .inf>.OSD 文件位于同一个 .cab 文件中,这是否正确,是否会导致问题?我不确定如何告诉 Visual Studio 不要构建 .OSD< 帮助

<?XML version="1.0" ENCODING='UTF-8'?>
<!DOCTYPE SOFTPKG SYSTEM "http://www.microsoft.com/standards/osd/osd.dtd">
<?XML::namespace href="http://www.microsoft.com/standards/osd/msicd.dtd" as="MSICD"?>
<SOFTPKG NAME="GetClientInfoAX" VERSION="1,0,0,0">
    <TITLE> GetClientInfoAX </TITLE>
    <MSICD::NATIVECODE>
        <CODE NAME="GetClientInfo101">
            <IMPLEMENTATION>
                <CODEBASE FILENAME="GetClientInfo101.dll">
                </CODEBASE>
            </IMPLEMENTATION>
        </CODE>
    </MSICD::NATIVECODE>
</SOFTPKG>

不管怎样,试图拼凑出这个问题的所有细节都是一场噩梦,我非常感谢

代码项目文章 解决这个问题。 使用 ATL 的完整可编写脚本的 ActiveX Web 控件教程是我用来签署 .cab 文件的指南,请参阅标题为“签署 cab 文件”的部分,

这是我使用的命令。请注意,我使用 Visual Studio 创建 cab 文件而不是 CABARC。另请注意,我仅使用测试证书:

makecert -sv "getclientinfocert.pvk" -n "CN=My Company" getclientinfocert.cer

cert2spc getclientinfocert.cer getclientinfocert.spc

pvk2pfx -pvk getclientinfocert.pvk -pi AOTC20467cert -spc getclientinfocert.spc -pfx getclientinfocert.pfx -po AOTC81396pass –f

signtool sign /f getclientinfocert.pfx /p AOTC81396pass /t http://timestamp.verisign.com/scripts/timstamp.dll /v GetClientInfo101.dll

signtool sign /f getclientinfocert.pfx /p AOTC81396pass /t http://timestamp.verisign.com/scripts/timstamp.dll /v GetClientInfoAX.cab

使用 certmgr 将“根机构”证书导出​​和导入到受信任的根证书:

signtool verify /v /a GetClientInfoAX.cab

请注意,我将 DLL 复制到了 Windows SDK 文件夹,对其进行了签名,然后将其复制返回到我的 cab 文件,然后将其复制到我的 SDK 文件中,并对 cab 文件进行签名。最后,我将 cab 文件复制到我的网站项目中。

注意:请参阅第一个答案末尾的评论。我已从 Comodo 购买了签名证书,安装后,我现在收到“未知发布者”错误即使证书状态为“正常”。 DLL 和 CAB 文件均已签名。

我相信我现在的问题是控件需要标记为脚本安全。我发现了一篇最近的文章,使用 C# 在 .NET 中创建 ActiveX 控件,看起来非常有帮助。

I have been struggling for days trying to get a simple ActiveX DLL to work with no success despite studying several articles on the subject which I have found online.

I suspect I have several things coded incorrectly as I am just not familiar with this and most of the articles on the subject are out of date. I am using Visual Studio 2008 and have been using the Windows SDK v7.1 for digital signing.

What I am trying to do is return the client machineName from the environment class back to the web page (and eventually back to the web server).

This is my C# class:

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.Win32;

namespace GetClientInfo101
{
    [Guid("121C3E0E-DC6E-45dc-952B-A6617F0FAA32")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [ComVisible(true)]
    public interface IGetClient
    {
        [DispId(1)]
        string GetClient();
    }
    [Guid("5085C918-0236-4828-BDFA-063FEE57C69B")]
    [ProgId("getClientInfoAx.CGetClient")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(IGetClient))]
    [System.ComponentModel.ToolboxItem(true)]
    [ComVisible(true)]
    public class CGetClient : IGetClient
    {
        public string GetClient()
        {
           return Environment.MachineName;
        }
    }
}

Here is my assembly:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("GetClientInfo101")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GetClientInfo101")]
[assembly: AssemblyCopyright("Copyright © N/A 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1bf2a0bc-f9cb-4f68-8990-5caaf3ab525d")]

// Version information for an assembly consists of the following four values:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")

Here is my object tag and script on my website Master Page. **NOTE: I am getting the error

Microsoft JScript runtime error: Automation server can't create object

on the "var" execution**:

<object id="getClientInfo" name="GetClientInfo101" classid="clsid:5085C918-0236-4828-BDFA-063FEE57C69B"
        codebase="GetClientInfo/GetClientInfoAX.cab#version=1,0,0,0">
</object>

<script type="text/javascript">
    function OpenActiveX()
    {
        var objGetClientInfo = new ActiveXObject("GetClientInfoAx.CGetClient");
        if(objGetClientInfo != null)
         {
             //For testing only
             alert(objGetClientInfo.GetClient());
         }
     }
</script>

Then I have manually created a .inf file as follows:

[version]
    signature="$CHICAGO$"
    AdvancedINF=2.0
[Add.Code]
    GetClientInfo101.dll=GetClientInfo101.dll
    GetClientInfo101.inf=GetClientInfo101.inf
[GetClientInfo101.dll]
    file-win32-x86=thiscab
    clsid={5085C918-0236-4828-BDFA-063FEE57C69B}
    FileVersion=1,0,0,0
    RegisterServer=yes
[GetClientInfo101.inf]
    file=thiscab

However, when I build my .cab file I am also getting a .OSD file output to the .cab as follows (I am concerned about there being both a .inf and a .OSD file in the same .cab file. Is that right and will it cause problems? I am not sure how to tell Visual Studio to NOT build the .OSD file.

<?XML version="1.0" ENCODING='UTF-8'?>
<!DOCTYPE SOFTPKG SYSTEM "http://www.microsoft.com/standards/osd/osd.dtd">
<?XML::namespace href="http://www.microsoft.com/standards/osd/msicd.dtd" as="MSICD"?>
<SOFTPKG NAME="GetClientInfoAX" VERSION="1,0,0,0">
    <TITLE> GetClientInfoAX </TITLE>
    <MSICD::NATIVECODE>
        <CODE NAME="GetClientInfo101">
            <IMPLEMENTATION>
                <CODEBASE FILENAME="GetClientInfo101.dll">
                </CODEBASE>
            </IMPLEMENTATION>
        </CODE>
    </MSICD::NATIVECODE>
</SOFTPKG>

Anyway, this has been a nightmare trying to piece together all the details of this. I would be very grateful for any help resolving this.

OK, the The Code Project article A Complete Scriptable ActiveX Web Control Tutorial Using ATL is what I used as a guide for the signing the .cab file. See the section titled "Signing a cab file".

Here are the commands I used. Note that I used Visual Studio to create the cab file instead of CABARC. Also note I am only using a test cert:

makecert -sv "getclientinfocert.pvk" -n "CN=My Company" getclientinfocert.cer

cert2spc getclientinfocert.cer getclientinfocert.spc

pvk2pfx -pvk getclientinfocert.pvk -pi AOTC20467cert -spc getclientinfocert.spc -pfx getclientinfocert.pfx -po AOTC81396pass –f

signtool sign /f getclientinfocert.pfx /p AOTC81396pass /t http://timestamp.verisign.com/scripts/timstamp.dll /v GetClientInfo101.dll

signtool sign /f getclientinfocert.pfx /p AOTC81396pass /t http://timestamp.verisign.com/scripts/timstamp.dll /v GetClientInfoAX.cab

Use certmgr to export and import “Root Agency” certificate to Trusted Root Certs:

signtool verify /v /a GetClientInfoAX.cab

Note that I copied my DLL to my Windows SDK folder, signed that, copied it back to my cab file which I then copied over to my SDK file, signed the cab file. Then finally, I copied the cab file to my website project.

NOTE: See comments at end of first answer. I have purchased a signed certificate from Comodo and with that installed, I now get "Unknown Publisher" error even though the certificate status is "OK". Both the DLL and CAB file have been signed.

I believe my issue now is that the control needs to be marked as safe for scripting. I found a recent article, Creating an ActiveX control in .NET using C#, which looks very helpful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

离线来电— 2024-10-04 10:57:54

ComVisible co 类中与版本无关的 progid 设置为,

  [ProgId("getClientInfoAx.CGetClient")] 

而在 JScript 代码中,实例化代码为

  var objGetClientInfo = new ActiveXObject("GetClientInfoAx.CGetClient");

请首先验证区分大小写并确认行为?

Your version independent progid in the ComVisible co class is set as

  [ProgId("getClientInfoAx.CGetClient")] 

Whereas in the JScript Code the instantiation code is as

  var objGetClientInfo = new ActiveXObject("GetClientInfoAx.CGetClient");

Please verify case sensitivity first and confirm behavior?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文