views:

176

answers:

2

Hi, 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 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"&gt;
<?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 peice together all the details of this. I would be very grateful for any help resolving this.

Thank you, Jim

Ok, the following article is what I used as a guide for the signing the .cab file. See the section titled "Signing a cab file".

http://www.codeproject.com/KB/atl/ScriptableActiveX.aspx?artkw=activex

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, 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 the control needs to be marked as safe for scripting, I found a recent article here which looks very helpful:

http://www.olavaukan.com/2010/08/creating-an-activex-control-in-net-using-c/
A: 

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
I will try that and advise results, thank you.
Jim
Unfortunately, that doesn't seem to make a difference with the case corrected. This thing is painful!
Jim
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
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
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
No worries. It's nice to know the settings worked. Now you can focus on the actual issue.
byte
Ok, I posted some information for what I did to sign the cab file above. Thanks again!
Jim
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
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
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
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
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
that's good. at least you know what's going wrong now
byte
I found a good article for making an activeX control including marking safe for scripting for anybody interested.
Jim
"http://www.olavaukan.com/2010/08/creating-an-activex-control-in-net-using-c/"
Jim
Jim, thanks for sharing the URL.
byte
A: 

Hey guys, just wondering how you managed to get by the OSD problem. Pretty much followed the steps above, successfully signed the dlls and cab but when i install it in IE and I look at the setupapi.log, error says:

[2010/10/20 16:05:19 844.32]
#-198 Command line processed: "C:\Program Files\Internet Explorer\iexplore.exe" SCODEF:3756 CREDAT:14337
#-024 Copying file "C:\DOCUME~1\RAYMAR~1.ROM\LOCALS~1\Temp\ICD1.tmp\OSD1694.OSD" to "C:\WINDOWS\Downloaded Program Files\OSD1694.OSD".
#E361 An unsigned or incorrectly signed file "C:\DOCUME~1\RAYMAR~1.ROM\LOCALS~1\Temp\ICD1.tmp\OSD1694.OSD" will be installed (Policy=Ignore). Error 0x800b0100: No signature was present in the subject.

I've been stuck on this problem for days, any help would be deeply appreciated!

roman
I used MS.Cab.Maker.exe available as freeware from Brothersoft to create a cab with only my two files. That resolves that problem, but I still have more.
Jim
Thanks Jim, that did fix my problem. Unfortunately i'm facing a different problem now. I have a vb.net activex and it is working perfectly on the development machine (which has the IIS), but when i try to install it on other machines i get the error in the setupapi.log which says ".INF file will be installed (policy=ignore). error 0x0800b0100: No Signature was present in the subject". my Inf file seems to work cause i checked the registry and System32 folder (in both dev machine and other machines) my dll was registered. Any tips please.
roman