1

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jim
  • 155
  • 2
  • 7

1 Answers1

0

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?

byte
  • 1,665
  • 1
  • 19
  • 36
  • Unfortunately, that doesn't seem to make a difference with the case corrected. This thing is painful! – Jim Oct 12 '10 at 01:19
  • OK. Have you tried instantiating the ActiveX object in your web page using object or embed tag? See how this behaves. Also try and instantiate your COM control using local VBScript. Basically you need to identify whether the problem is because your ActiveX is not signed and registered correctly or due to security permissions – byte Oct 12 '10 at 09:06
  • If you are using IE, change the setting for testing purpose - Open IE -> Tools ->Internet Options -> Security -> Custom Level -> ActiveX controls and plug-ins ->Enable "Initialize and script ActiveX controls not marked as safe for scripting" – byte Oct 12 '10 at 09:14
  • My object tag is shown above. I changed the IE setting and voila, the DLL is actually working with that. So, I guess something is wrong with what I did to sign this. I signed the dll, then signed the .cab. Both said successful, but I probably did something wrong. I will post above what I am doing for that. Thank you. – Jim Oct 12 '10 at 12:58
  • No worries. It's nice to know the settings worked. Now you can focus on the actual issue. – byte Oct 12 '10 at 13:41
  • Ok, I posted some information for what I did to sign the cab file above. Thanks again! – Jim Oct 13 '10 at 05:38
  • We are going to purchase a real PKI certificate and see if that will resolve this. I am having no luck with the test certificate. – Jim Oct 17 '10 at 18:39
  • Jim, meanwhile, did you test the activex control from the article that you are referring? Are you able to install and instantiate that? If you can then sign your control with that certificate and try again. This will help confirm whether the problem is with the certificate at all. – byte Oct 18 '10 at 09:06
  • No, I didn't test that example control because it is not at all what our needs are. I now have a signed certificate from Comodo, created a cab file without the .OSD file, signed the dll and the cab with the comodo certificate. Now I get "Unknown publisher" even with the signed certificate from comodo which everything looks good for that, status is ok. This is unbelievable! Ahhhh – Jim Oct 24 '10 at 01:41
  • There is a "Comodo Certification Authority" certificate in the "Trusted Root Certification Autorities" tab. Then we have the newly purchased Comodo certificate in the "Personal Certificates" tab. Do these two certificates need some sort of relationship set up? – Jim Oct 24 '10 at 02:24
  • Ok, now I believe my signing is ok. My problem appears to be that IE does not cosider my ActiveX as safe for scripting. I may enter a new question for this. I have tried something I found in another article but maybe that isn't working. – Jim Oct 26 '10 at 02:36
  • I found a good article for making an activeX control including marking safe for scripting for anybody interested. – Jim Oct 26 '10 at 13:42