locked
COM interop call fails from Windows Service RRS feed

  • Question

  • Hi!

    I have a Windows Service that makes a COM interop call to a VB6 COM object. The call fails with the following error: Unable to cast COM object of type 'Project1.Class1Class' to interface type 'Project1._Class1'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{11B12816-2495-46DA-B537-70E50BB62F45}' failed due to the following error: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).

    It works on my XP box, but I get the error on the Server 2000.

    The user that runs the service is a domain account that has admin rights on the box. We have also tried making an exe that makes the exact same call to the COM object, deployed it to the server, logged in with the account the windows service uses and executed the exe, and it works fine. When examining Windows.Identity.GetCurrent().Name right before the COM call it was the same for both the service and the exe. But the Windows.Identity.GetCurrent().AuthenticationType differs. The Windows Service is "MICROSOFT_AUTHENTICATION_PACKAGE_V1_0" and when running the exe we get "NTLM"

    So any ideas??

    regards

    /Tommie

    Thursday, December 7, 2006 9:04 PM

All replies

  • Hi!

    Anyone that could please be kind enough and try to reproduce the problem?? So far I'm not sure if there is something wrong with my Win2k setup or not.

    These are the steps to reproduce the problem:

    Create a VB6 COM .DLL with one class called TestClass.cls with the following code:

    Public Function FromVB6() As String
        FromVB6 = "From VB6"
    End Function

    Change the name on the project to VB6COMComp. Build the COM dll.

    Start VS2005, create a new Windows Service.

    Add a reference to the COM component built previously.

    Add a class called DoSomething.cs with the following code:

    public class DoSomething
    {
        Timer myTimer;
        public void StartSomething()
        {
            myTimer = new Timer(4000);
            myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
            myTimer.Enabled = true;
        }
        public void StopSomething()
        {
            myTimer.Enabled = false;
            myTimer = null;
        }
        void myTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            myTimer.Enabled = false;
            EventLog.WriteEntry("TestService", "Name:" + WindowsIdentity.GetCurrent().Name + ", AuthType:" + WindowsIdentity.GetCurrent().AuthenticationType, EventLogEntryType.Information);
            try
            {
                VB6COMComp.TestClass VB6COMobject = new VB6COMComp.TestClass();
                EventLog.WriteEntry("TestService", "From VB6COMComp:" + VB6COMobject.FromVB6(), EventLogEntryType.Information);
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("TestService", ex.ToString(), EventLogEntryType.Error);
            }
     
        myTimer.Enabled = true;
    }

    }
     

    Add the following using statement:

    using System.Security.Principal;

    Change the OnStart and OnStop events in Service1.cs

     protected override void OnStart(string[] args)
    {
        
    // TODO: Add code here to start your service.
        doSomething.StartSomething();
    }
    protected override void OnStop()
    {
        
    // TODO: Add code here to perform any tear-down necessary to stop your service.
        doSomething.StopSomething();
    }

    Add an installer(double click on Service1.cs  in Solution Explorer, then rightclick in the design view and choose "Add Installer".

    Compile, register the service with installutil.

    many thanks in advance

     

    /Tommie

    Tuesday, December 12, 2006 8:34 AM