none
Automation Error Raised by VB6 App on a .NET component ever since installing .NET 2.0 Framework

    Question

  • I noticed that a VB 6 app is no longer able to properly call a .NET component exposed with a COM interface that was compile via Visual Studio 2005, it raises an Automation error. Setting the application configuration file to point to the .NET framework v2.0.50727 does not help the situation.

    However, when the .NET component is compiled via Visual Studio 2003 it works provided I have the infamous application configuration for the VB6 app set to:

    <?xml version ="1.0"?>
     <configuration>
        <startup>
             <requiredRuntime version="v1.1.4322"/>
             <supportedRuntime version="v1.1.4322"/> 
         </startup>
    </configuration>

    Why is this happening???

    I did noticed that when I run the dependency walker program on the .NET component compile with VS2003 and then later VS2005 it gives the following:

    VS2003 compiled:
     
       MydllInQuestion.dll
          MSCOREE.dll
             KERNEL32.dll
             ADVAPI32.dll

    VS2005 compiled:

       MydllInQuestion.dll
          MSCOREE.dll
             KERNEL32.dll
       
    Why is VS2005 or better said .NET 2.0 compiler no longer considers ADVAPI32.dll necessary for my application dll? Could this be the issue? If so, why? How do I correct? Has the way a .NET component exposes a COM interface changed in .NET 2.0 Framework which works perfectly well under 1.1 Framework?

    Too many questions...

    Thanks for any help that any one can give

    Sincerely Yours 
       HumbleServant




    Thursday, December 01, 2005 7:42 PM

Answers

  • ADVAPI32.dll is loaded as a dependency of MSCOREE.dll, not of your application. Managed assemblies need only depend on MSCOREE.dll that at the very least defines their true entry points in native code. In .NET 2.0 ADVAPI32.dll is not imported by MSCOREE.dll, not directly in the IAT anyway.

    Is the interface attributed with the GuidAttribute at the very least to make sure it always has the same IID? Read http://blogs.msdn.com/heaths/archive/2005/03/09/391358.aspx for more guidelines.

    What is the full description and error number for the automation error? Also run fuslogvw.exe from the .NET Framework SDK (installed with VS 2005 by default) to see if any assemblies could not be loaded.

    Finally, if you build an application with VS.NET 2003 and you have .NET 1.1 installed, you do not need to define a redirection policy necessary. The .NET Framework against which an application was compiled will be loaded if it exists. Newer versions are only tried if the version you compiled against is not installed. This is known as the upgrade policy. Just FYI.
    Monday, December 05, 2005 7:47 AM
  • You should always decorate your class with at least GuidAttribute and either InterfaceTypeAttribute or ClassInterfaceAttribute as appropriate to maintain binary compatibility for times when using your typelib with a VB6 application. Make sure, too, that when you use regasm.exe to register your server and types you pass /tlb in the command-line options to register the typelib.

    The other reason for attributing your classes is that when you re-register your types you don't clutter your registry with older, unused GUIDs anymore. It's just a cleaner implementation and doesn't take much to do.

    Using the ProgIdAttribute is also useful to ensure that if you refactor your class by re-ordering your members that any cached PROGIDs are used incorrectly.

    The problem could be that if the GUIDs for the classes and interfaces are changing the VB6 app isn't binary compatible and is using those old types.

    Oh, and you should really be explicit in your class interfaces, too. I believe I explained that previously in this thread, but just in case...you declare your interface explicitly attributed with the correct attributes and implement that as the first interface of your implementation class. .NET 2.0 has an attribute  you can use in addition or in lieu of implementing the interface first named ComDefaultInterfaceAttribute. Two reasons for doing this is controlling what gets exposed, as well as controlling the interface GUID (IID) and interface type (IUnknown, IDispatch, or dual).

    Monday, January 16, 2006 5:19 PM

All replies

  • ADVAPI32.dll is loaded as a dependency of MSCOREE.dll, not of your application. Managed assemblies need only depend on MSCOREE.dll that at the very least defines their true entry points in native code. In .NET 2.0 ADVAPI32.dll is not imported by MSCOREE.dll, not directly in the IAT anyway.

    Is the interface attributed with the GuidAttribute at the very least to make sure it always has the same IID? Read http://blogs.msdn.com/heaths/archive/2005/03/09/391358.aspx for more guidelines.

    What is the full description and error number for the automation error? Also run fuslogvw.exe from the .NET Framework SDK (installed with VS 2005 by default) to see if any assemblies could not be loaded.

    Finally, if you build an application with VS.NET 2003 and you have .NET 1.1 installed, you do not need to define a redirection policy necessary. The .NET Framework against which an application was compiled will be loaded if it exists. Newer versions are only tried if the version you compiled against is not installed. This is known as the upgrade policy. Just FYI.
    Monday, December 05, 2005 7:47 AM
  • I'm glad to see someone else has the same problem as me.

    Same issue All I did was install the .Net 2.0 Framework.

    My VB app that uses a .net dll via regasm and gacutil gives me an automation error when ever I try to use the .net dll now. The exact error is:

    Run-time error '-2146233079 (8013509)':
    Automation error

    The application still works fine on machines that don't have .net 2.0 on them.Even if I rebuild it, it will work fine on other machines. I just can't run it on my machine any more.

    I tried the same thing in the app.config file ("specifying the runtime version") to no avail either.

    Here are the attributes on my .net class

    [

    ComVisible(true),

    ProgId("WsClient.UserSearch"),

    Guid("25EC5641-2B71-4a40-8179-0B5439FF3410"),

    ClassInterface(ClassInterfaceType.AutoDual)

    ]

     

    Any ideas?

     

    Thursday, December 22, 2005 1:07 AM
  • The error 0x80131509 is COR_E_INVALIDOPERATION, so unfortunately it's of little help in solving the problem.

    Do keep in mind that the mscoree.dll shim will always load the latest runtime when instantiating a managed class in a CCW. It's possible that functionality you're using is not available in .NET 2.0 or there is a load error with an assembly that will not load in .NET 2.0 for one of many reasons. You might running fuslogvw.exe from the .NET Framework SDK will help if there was binding errors, but this is only one possible problem.

    So, with the rather unfortunate error code you received we might have to try a few things to figure out what's going wrong.

    Thursday, December 22, 2005 5:40 PM
  •  

    OK.  I figured out the problem

    The class I am using for interop inherits from an abstract class.

    I did not have the abstract class decorated with the interop attributes.

    Before I installed the 2.0 framework this was all fine and it worked just fine. However, once I installed 2.0 I got the automation error.

    So to make the automation error go away all I had to do is decorate the abstract class.

    Hope this helps others.

    Since this is a breaking change, I'm hoping a fix is released.

    Thanks

    Friday, December 23, 2005 6:36 PM
  • I've just run into the same problem except that I'm instantiating the class from VBScript.

    I don't have any decorations on the class that I'm accessing (didn't really need any because the class was late-bound). My class eventualy derives from a dataset so I'm not sure how I would decorate it to prevent this problem.

    -- Mark

    Wednesday, January 11, 2006 11:52 PM
  • You should always decorate your class with at least GuidAttribute and either InterfaceTypeAttribute or ClassInterfaceAttribute as appropriate to maintain binary compatibility for times when using your typelib with a VB6 application. Make sure, too, that when you use regasm.exe to register your server and types you pass /tlb in the command-line options to register the typelib.

    The other reason for attributing your classes is that when you re-register your types you don't clutter your registry with older, unused GUIDs anymore. It's just a cleaner implementation and doesn't take much to do.

    Using the ProgIdAttribute is also useful to ensure that if you refactor your class by re-ordering your members that any cached PROGIDs are used incorrectly.

    The problem could be that if the GUIDs for the classes and interfaces are changing the VB6 app isn't binary compatible and is using those old types.

    Oh, and you should really be explicit in your class interfaces, too. I believe I explained that previously in this thread, but just in case...you declare your interface explicitly attributed with the correct attributes and implement that as the first interface of your implementation class. .NET 2.0 has an attribute  you can use in addition or in lieu of implementing the interface first named ComDefaultInterfaceAttribute. Two reasons for doing this is controlling what gets exposed, as well as controlling the interface GUID (IID) and interface type (IUnknown, IDispatch, or dual).

    Monday, January 16, 2006 5:19 PM
  • I made my interfaces explicit and it works now but I did run into one area that didn't work the way I expected. In the example code below my expectation was that a COM client talking to an object of class B should be able to invoke both B.x and B.y, instead I am only able to invoke method B.y. Removing the derivation from SomeComInvisibleClass allows me to invoke both methods.

    public interface IA

    {

      void x();

    }

     

    [ClassInterface(ClassInterfaceType.None)]

    public class A: SomeComInvisibleClass, IA

    {

      public void x()

      {

        // code

      }

    }

     

    public interface IB: IA

    {

      void y();

    }

     

    [ClassInterface(ClassInterfaceType.None)]

    public class B: A, IB

    {

      public void y()

      {

        // code

      }

    }

     

    Monday, January 16, 2006 8:19 PM
  • My question is not exactly this but it involves .NET 1.1 and .NET 2.0.  We have a legacy app that was built using .NET 1.1, and now as some systems (client PCs in a 3-tier client-server configuration) are coming online with .NET 2.0 installed as well as .NET 1.1, we are finding that these .NET 1.1 applications simply break.

    If I then uninstall .NET 2.0 on a PC, the legacy application functions again.

    I thought the whole point of .NET versions was for them to be able to peacefully co-exist on a system and not break apps dependent on the other .NET versions, but when 2.0 came out apparently something happened to change (or unintentionally break) this.

    Any ideas?  We really are not in a position to upgrade the legacy app for it to work with 2.0 installed at this time, but then again other apps need 2.0 so it is impractical for us to say "You can't install .net 2.0 on systems which have THIS app on them", in a large enterprise.

    Thanks for any insight.

    Thursday, August 17, 2006 6:18 PM
  • David, you are sure that .NET 1.1 is installed? If the Framework is present for assemblies than an application targets, it is what is supposed to be loaded. That said, that policy can be overridden using the application configuration file (a couple of different ways) or even through a registry hack (I don't think it's documented, but isn't hard to figure out - I did before I joined Microsoft). None of that should happen by default, however.

    You can prevent the application from running on a newer Framework, however. Put the following at the top (right after <configuration>) of your application's .config file:

    <configuration>
      <startup>
        <supportedRuntime version="v1.1.4322"/>
      </startup>
      <!-- ... -->
    </configuration>

    Thursday, August 17, 2006 11:45 PM
  • I guess I didn't give enough details.

    Our app(s) are VB 6 apps, and we had to remove the DCOM/RPC network communications piece in one, and the anonymous FTP piece in the other, substituting for it a .NET 1.1 Framework communication using https:, to meet internal security requirements.

    The client talks to the server via this .NET 1.1 https communication module that was, essentially, bolted onto the core VB program in place of the other protocol, and then the whole thing was compiled and packaged for distribution.

    The problem comes on the client workstation, when the .NET 2.0 Framework is installed along with the .NET 1.1 Framework.  At that point, all communication of the applications to the server (again, which use .NET 1.1) ceases to function UNTIL WE REMOVE the .NET 2.0 Framework!

    It is not just one application that exhibits this behavior.  It is two distinctly separate apps, both of which that were built by different teams originally, and it was two different teams who switched out the original communications layer for the .NET 1.1 layer.

     .NET 1.1 is installed on each client or the VB6 app won't function, and once .NET 2.0 is installed on the client along with .NET 1.1, the app's communication ceases.

    Tell me this (not my area of expertise, directly but I am having to dig into this issue and point the developers in a direction...ANY direction).  If a VB6 app is being built, inside the VB6 project is there a functional equivalent to the web.config where we can direct the code to use a specific .NET Framework with an explicit reference, and if no such specific reference is made, the code 'by default' is trying to use the latest version of .NET which is installed?  Might this solution be 'that' simple, and can you show me how that might be done in the context of a VB6 project, so I can show the developers how to set this?  Maybe we just don't know we don't know how to do this.

    Friday, August 18, 2006 2:27 PM
  • That does change things considerably. COM interop using the default shim (mscoree.dll) always uses the latest Framework version available on the machine. That said, there are ways of controlling that. Many times (dare I saw always?) putting a config file like I mentioned above in the same directory with the same name as your executable will cause mscoree.dll to load the latest supported version, even if that executable isn't managed. This, at least, used to work in tests and for a native production application at another company where I worked to control what gets loaded. The CLR will still query for an application configuration file when it needs it (and when it loads) regardless of whether the calling EXE is managed.

    When it comes to hosting and customization of the CLR, I highly recommend the book, Customing the Microsoft .NET Framework Common Language Runtime, by Steven Pratschner. You can also find my review of the book at http://blogs.msdn.com/heaths/archive/2006/02/27/539956.aspx. It's a very good book and goes into great detail about customing both the default and custom CLR hosts.

    Friday, August 18, 2006 2:52 PM
  • Ok, so 'blah.config' in the same folder as 'blah.exe' with the following directive would cause blah.exe to use the 1.1 framework regardless of whether another framework was installed, correct?  That is easy enough to test!

    <configuration>
      <startup>
        <supportedRuntime version="v1.1.4322"/>
      </startup>
      <!-- ... -->
    </configuration>

    Friday, August 18, 2006 3:15 PM
  • No, it needs to be blah.exe.config for blah.exe (and in the same directory), just like with managed application configuration files.
    Friday, August 18, 2006 8:35 PM
  • I installed .NET 2.0 and did the original 'blah.config' version of the directives, and oddly enough one of the two apps which was broken worked with that file name.

    The other didn't.

    Then I changed to blah.exe.config, and the app that worked with the blah.config still worked, but the app which had not worked before, even was worse when I used blah.exe.config.  The point of the 2nd app is that, with blah.config the first step after opening the app still worked (which was to contact a server and download some reference data into the client's cache), but once I put in blah.exe.config, and then there is a login step which fails after the reference data loads.  That first step failed immediately when I have blah.exe.config in place, along with the second step, so in the case of the 2nd app using this directive makes the problem worse, not better, and in the case of the other app I still have to do some more testing but the config file does seem to have fixed that issue with both .NET 1.1 and .NET 2.0 being on the machine at the same time.

    The app which was not helped by this also has some OCXs and DLLs that the .exe calls to do a couple things, so it is arguably more complex than the app which was helped by this.

    Friday, August 18, 2006 8:50 PM
  • <appname>.exe.config is the right format. I'm not sure why <appname>.config worked for you. I suspect that the 2nd app failed because your code for that first working part worked under .NET 2.0 while the rest later did not. Without knowing more about the application, I can't really help you. I do recommend using fuslogvw.exe from the .NET Framework SDK. Start it, click the "Settings" button, and select "Log all bindings". Watch what assemblies are loaded.

    Did the .config file have anything else in it for the second app?

    Also, you might pre-load the CLR by declaring an external function for CorBindToRuntime or CorBindToRuntimeEx and pass in the version of the Framework you want loaded (i.e., "v1.1.4322").

    Friday, August 18, 2006 8:57 PM
  • Config for both apps is identical (same lines just renamed to different files)

    I'll give fuslogvw.exe a try, or get the lead developer to do it.  Thanks very much for this insight!

    Friday, August 18, 2006 9:22 PM
  • I have a question related to this issue.  I am a little green when it comes to these types of issues.  Here is my scenario and any help you could provide would be great.  We are a dll that is built in .NET 1.1, it is registered for COM Interop and is called by a VB6 App.  I am not sure if this directly coninsides with the install of the 2.0 framework or not.  I believe that it does.  When a users runs the VB6 app and calls out to the .NET dll we receive the following error “-2146233078 – Automation Error”.  The .NET dll is called baseproject.dll and I have create the config in the manner I saw earlier in this post.  I called the file “baseproject.dll.config”.  I the file I put the following code:

     

    <configuration>

       <startup>

          <supportedRuntime version="v1.1.4322" />

       </startup>

    </configuration>

     

    This seemed to make a difference as I still receive the same error.

     

    Any insight would be great.

     

    Thanks.

    Wednesday, August 30, 2006 1:46 PM
  • The name of the file should be "VB6AppName.exe.config". A config file is not per assembly, is per appdomain. In your case the default appdomain of an exe.
    Wednesday, August 30, 2006 3:40 PM
  • Thanks.  That seems to work.
    Wednesday, August 30, 2006 6:02 PM
  • Hi Jim

    I am getting the error eveif I decorate the abstract class with the following attribute

    [ClassInterface(ClassInterfaceType.None)]

    Do I need to decorate my abstract class with other attributes?

    Thanks

    Minesh

    Friday, September 15, 2006 2:03 AM
  • Where did you deploy the config file?  I've got the same issue, and I can't get my config file to work.  Did you put it in the same directory as the EXE?

    I'd really appreciate your help.

    Thursday, December 28, 2006 4:09 PM
  • I've created one of these config files, but am I just supposed to put it in the app directory with the EXE, or is it supposed to go somewhere else?

     

    Thursday, December 28, 2006 4:18 PM
  • Hi,

     

    I have COM interop problem with my application - I have created a MyNetComponent.dll (Using VS 2005/.NET 2.0) and then installing it in GAC and registering it using Regasm for COM interop. After that I created excel based macro in which I added reference to the tlb file I created using Regasm however I get 'Automation Error' - Details as follows -

     

    MyNetComponent dll code -

     

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.Runtime.InteropServices;

    namespace MyNetComponent

    {

    [ClassInterface(ClassInterfaceType.None)] //No class interface to be exported

    [ProgId("MyApplication")] //type name to be exported

    [Guid("9F560E12-BE0F-4f92-8036-3684F0382304")] //!!Don't change the Guid ID

    public class MyApplication: IMyApplication

    {

    public double MyMethod(double x)

    {

    return  x*x;

    }

    }

     

    [ComVisible(true)]

    [InterfaceType(ComInterfaceType.InterfaceIsDual)]

    [Guid("AAF84F13-AB4D-4c63-B4BF-F5FFBEA8AAFD")] //!!Don't change the Guid ID

    public interface IMyApplication

    {

    double MyMethod(double x);

    }

    }

     

    Further I applied following attributes to the assembly -

    [assembly: ComVisible(true)]

    // The following GUID is for the ID of the typelib if this project is exposed to COM

    [assembly: Guid("89b5ba9a-5804-450a-8869-fcd47acb0f27")]

    // Version information for an assembly consists of the following four values:

    //

    // Major Version

    // Minor Version

    // Build Number

    // Revision

    //

    // You can specify all the values or you can default the Revision and Build Numbers

    // by using the '*' as shown below:

    [assembly: AssemblyVersion("1.0.0.0")]

    [assembly: AssemblyFileVersion("1.0.0.0")]

    [assembly: AssemblyKeyFile(@"C:\Documents and Settings\SachinM\Desktop\MyNetComponent\MyComponent.snk")]

     

     

    Now after compiling all this (In VS 2005/ .NET 2.0) class library code I get 'MyNetComponent.dll' assembly.

     

    After this I am deploying this assembly to newly created clean Windows XP SP1 Virtual PC for testing -

    This machine has following installation

    1. Microsoft Office 2003 - Excel

    2. .NET Framework 2.0

     

    On the virtual PC using Gacutil.exe I installed this MyNetComponent.dll in GAC

    >gacutil /i MyNetComponent.dll

     

    After this I used regasm.exe as follows

    >regasm MyNetComponent.dll /tlb:MyNetComponent.tlb

     

    This registers my dll for COM interop and created tlb as well

     

    Afte this I opened Excel and added reference of the generated tlb file and written following code

     

    Dim app As MyNetComponent.MyApplication

    Set app = New MyNetComponent.MyApplication  -----------> I get error here (Automation Error -2146232576 (80131700)

    Dim val As Double

    val = app.MyMethod(8.1)

     

    Can you please help me in fixing this bug. Please note that it works just fine on my development machine (where I have .NET 1.1, .NET 2.0 and VS 2005, 2003 installed) but it does not work on customer/depolyment machine where only .NET 2.0 is installed. Please Help Smile

    Sunday, April 29, 2007 7:06 AM
  • I had a very similar problem, with a VB6 project referencing a tlb from a dll created in C#/.Net 1.1.

    It worked fine, until I installed .Net 2.0 Framework, then I got 'Run-time error... Automation error The system cannot find the file specified'.

    I tried a number of fixes. The one that worked was to go back to the C# class and replace all the GUIDs with new ones (I got these from http://www.famkruithof.net/uuid/uuidgen). I rebuilt the solution and tried again.

    Worked a treat. I hope this helps someone else.


    Thursday, November 06, 2008 2:54 PM
  • I recently had the same problem. Applying all available Office patches solved it.
    Wednesday, May 13, 2009 1:46 PM