1

I use a Microsoft example for a COM-Server: Out-of-process C# COM server (CSExeCOMServer)

A simple Console COM Client should just start up the Server and use its Methods, Properties and Events.

    static void Main(string[] args)
    {            
        Type type = Type.GetTypeFromCLSID(new Guid(SimpleObject.ClassId));

        if (type == null)
        {
            throw new Exception("ClientObject component is not registered");
        }

        ISimpleObject comObject = (ISimpleObject)Activator.CreateInstance(type);

        string what = comObject.HelloWorld();

        float fvalue = (float) 2.22;
        comObject.FloatProperty = fvalue;
        fvalue = (float)3.33;
        fvalue = comObject.FloatProperty;
    }

This actually works directly. The server came up in 32bit due to its configured Platform target x86. But I have a 64bit OS and now I wanted to get it run in 64bit. The registration is done in post build event of the server. So I changed the registration (using the Framework64 regasm.exe) so that the server will be also registered in 64bit. Then I changed the Platform target to AnyCPU. If I start the client now it hangs in the line

    ISimpleObject comObject = (ISimpleObject)Activator.CreateInstance(type);

But I can see in the task manager that the server was properly started up in 64bits. After a time of 1min or so I get the following Exception:

Retrieving the COM class factory for component with CLSID {DB9935C1-19C5-4ED2-ADD2-9A57E19F53A3} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).

at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic) at System.Activator.CreateInstance(Type type) at ConsoleClient.Program.Main(String[] args) in C:\Source\User\MaLe\Tests\CSExeCOMServer\C#\ConsoleClient\Program.cs:line 17 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()

If I start the server exe by hand and try to connect to it by COM again I can see in the task manager that the Client starts up a second server rather than connecting to the first one. This one is indeed in 64bit but the exception occurs and after closing the client the second server closes as well. If I force the Server to be 32bit in AnyCPU with Prefere 32-bit flag everything works fine but in 32bit. If I set the platform target to x64 everything works fine also and in 64bit. So it doesnt work only in AnyCPU configuration if it starts up in 64bit.

Does anyone have an idea what I do wrong? I really need a COM-Server to run in AnyCPU configuration even with 64bit. I actually do not want to have seperate 32bit and 64bit exe's. Which worked also when I tested it by the way.

Thank you for your help.

MaLe
  • 33
  • 6
  • _"...Client starts up a second server rather than connecting to the first one..."_ - Unless you are using "COM singletons" via IROT then that is normal behavior –  Feb 03 '17 at 15:09
  • @MickyD Yes you are right I use a Singleton COM Server. This is why I did find it a strange behaviour.If I do the same thing with a working platform configuration there is only one server at a time. – MaLe Feb 03 '17 at 20:07

1 Answers1

1

Does anyone have an idea what I do wrong? I really need a COM-Server to run in AnyCPU configuration even with 64bit. I actually do not want to have seperate 32bit and 64bit exe's.

COM requires separate COM registrations for 32 bit and 64 bit and two different out-of-process COM servers; therefore you require a 32 bit COM exe as well as a 64-bit exe. You can't have one for both.

You'll see examples of this everywhere like:

  • bit-specific version of shell extensions for Windows Explorer. e.g. TortoiseSVN; TortoiseGit. Windows Explorer running on 64-bit Windows only accepts 64-bit extensions; similarly for running on 32-bit Windows

  • separate 32 and 64 bit versions of Microsoft Office (which has been COM/Ole for some time now) with the same bitness for COM add-ins

The only way you may be able to get around say wanting a 32-bit client connecting to a 64-bit server, is if you add the appropriate DCOM registrations and run your server on another box (running Windows 64 bit) with your client connecting to it over the network. Though, that's probably not particularly useful.

  • 1
    Actually all you need are 32 and 64 bit proxy dlls, which you probably want anyway. – Eric Brown Feb 03 '17 at 17:01
  • Ok I understand. Thank you for your answer Guys. I thought this is why there is such a thing like AnyCPU. To have one exe that runs on a 32bit OS with 32bit and in 64bit on a 64bit OS. But you can't do this if you use COM-Interfacing right? – MaLe Feb 03 '17 at 20:24
  • @MaLe that's right. This is one example of where using Any CPU is kinda bad –  Feb 03 '17 at 23:52
  • @EricBrown perhaps, but OP wants one-size-fits-everything and creating a proxy DLL just moves the problem –  Feb 04 '17 at 00:29