为什么 ActiveX 显示“未知发布者”使用签名证书时出错?
我已经努力了几天,试图让一个简单的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
ComVisible co 类中与版本无关的 progid 设置为,
而在 JScript 代码中,实例化代码为
请首先验证区分大小写并确认行为?
Your version independent progid in the ComVisible co class is set as
Whereas in the JScript Code the instantiation code is as
Please verify case sensitivity first and confirm behavior?