如何启动一个AnyCPU编译COM服务器

问题描述:

我使用微软例如,对于一个COM服务器: Out-of-process C# COM server (CSExeCOMServer)如何启动一个AnyCPU编译COM服务器

一个简单的控制台COM客户端应该只启动服务器和使用它的方法,属性和事件。

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; 
    } 

这实际上直接起作用。服务器由于其配置的Platform target x86而成为32位。但我有一个64位的操作系统,现在我想让它运行在64位。 注册是在服务器的构建后事件中完成的。所以我改变了注册(使用Framework64 regasm.exe),这样服务器也将在64位注册。然后我将Platform目标更改为AnyCPU。 如果我现在开始在客户端它挂在该行

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

但我可以在任务管理器中看到该服务器被正确的64位启动。之后的时间1分钟左右,我得到以下异常:

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()

如果我开始用手服务器exe文件,并尝试通过COM连接到一遍我可以在任务管理器中看到的是,客户端启动一第二台服务器,而不是连接到第一台服务器。这个确实是64位的,但是发生异常,关闭客户机后第二台服务器也关闭。 如果我强制服务器是32位的优先32位国旗的AnyCPU 32位的一切工作正常,但在32位。如果我将平台目标设置为x64,那么在64bit中一切正常。所以如果它启动在64位,它只能在AnyCPU配置中工作。

有没有人有一个想法我做错了什么? 我真的需要一个COM-Server甚至可以在64位的AnyCPU配置下运行。我其实不想有单独的32位和64位exe。顺便说一下,当我测试它时,它也起作用。

谢谢你的帮助。

+0

_” ......客户端启动的第二个服务器,而不是连接到第一个...“_ - - 除非你通过IROT使用”COM单例“,那么这是正常行为 – MickyD

+0

[AnyCPU Exes通常比它们值得的更麻烦](https://blogs.msdn.microsoft.com/rmbyers/2009/06/09/anycpu-exes-are-usually-trouble-than-theyre-worth /) –

+0

@MickyD是的你是对的我使用一个Singleton COM服务器,这就是为什么我发现它是一个奇怪的行为。同一个工作平台配置一次只有一个服务器 – MaLe

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需要单独的COM注册为32位和64位和两个不同的进程外COM服务器;因此您需要一个32位COM exe以及一个64位exe。两者都不能有一个。

你会看到这样的例子比比皆是,如:外壳扩展为Windows资源管理器

  • 特定位版本。例如TortoiseSVN; TortoiseGit。在64位Windows上运行的Windows资源管理器仅接受64位扩展;同样,对于32位运行Windows

  • 独立32和的Microsoft Office(这一直是COM/OLE一段时间了)的与COM相同的位数64个版本的插件

只有这样,你可能能够避开说想要一个32位客户端连接到64位服务器,就是如果你添加相应的DCOM注册并运行在服务器上的另一盒(运行Windows 64位)您的客户端通过网络连接到它。虽然,这可能不是特别有用。

+0

其实所有你需要的是32位和64位的代理dll,你可能想要的是 –

+0

好吧,我明白了,谢谢你的回答伙计们。这就是为什么有像AnyCPU这样的东西,要在一个32位操作系统上运行一个32位操作系统,在64位操作系统上运行64位操作系统,但是如果你使用COM接口,你不能这么做吗? – MaLe

+0

@MaLe这是使用Any CPU的一个例子d – MickyD