我将一个Microsoft示例用于COM-Server: Out-of-process C# COM server (CSExeCOMServer)
一个简单的控制台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;
}
这实际上可以直接使用。由于配置的平台目标x86,服务器出现在32位。但我有一个64位操作系统,现在我想让它以64位运行。 注册在服务器的post build事件中完成。所以我更改了注册(使用Framework64 regasm.exe),以便服务器也将在64位注册。然后我将平台目标更改为AnyCPU。 如果我现在启动客户端它会挂起
行 ISimpleObject comObject = (ISimpleObject)Activator.CreateInstance(type);
但我可以在任务管理器中看到服务器已正确启动64位。经过1分钟左右的时间后,我得到以下例外:
使用CLSID检索组件的COM类工厂 {DB9935C1-19C5-4ED2-ADD2-9A57E19F53A3}由于以下原因而失败 错误:80080005服务器执行失败(来自HRESULT的异常: 0x80080005(CO_E_SERVER_EXEC_FAILURE))。
在 System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔值 publicOnly,Boolean noCheck,Boolean& canBeCached, RuntimeMethodHandleInternal&安培; ctor,布尔& 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)
在System.Activator.CreateInstance(Type type,Boolean nonPublic)at System.Activator.CreateInstance(Type type)at ConsoleClient.Program.Main(String [] args)in C:\源\用户\雄性\测试\ CSExeCOMServer \ C#\ ConsoleClient \ Program.cs中:线 17在System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集, System.AppDomain.ExecuteAssembly上的String [] args)(String assemblyFile,Evidence assemblySecurity,String [] args)at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
在System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback回调,对象状态,布尔值 preserveSyncCtx)at System.Threading.ExecutionContext.Run(执行上下文 executionContext,ContextCallback回调,对象状态,布尔值 preserveSyncCtx)at System.Threading.ExecutionContext.Run(执行上下文 executionContext,ContextCallback回调,对象状态)at System.Threading.ThreadHelper.ThreadStart()
如果我手动启动服务器exe并尝试再次通过COM连接它,我可以在任务管理器中看到客户端启动第二台服务器而不是连接到第一台服务器。这个确实在64位,但发生异常,关闭客户端后,第二台服务器也关闭。 如果我在AnyCPU中强制服务器为32位,并且优先使用32位标志,那么一切正常,但是在32位。如果我将平台目标设置为x64,一切正常,并且在64位。因此,如果以64位启动,它仅在AnyCPU配置中不起作用。
有谁知道我做错了什么? 我真的需要一个COM-Server在AnyCPU配置中运行,即使使用64位也是如此。我实际上不希望有单独的32位和64位exe。当我顺便测试时,它也有用。
感谢您的帮助。
答案 0 :(得分:1)
有谁知道我做错了什么?我真的需要一个COM-Server在AnyCPU配置中运行,即使使用64位也是如此。我实际上不希望有单独的32位和64位exe。
COM要求对32位和64位以及两个不同的进程外COM服务器进行单独的COM注册;因此,您需要32位COM exe以及64位exe。你不能同时拥有一个。
你可以在任何地方看到这样的例子:
Windows资源管理器的特定于比特的shell扩展版本。例如 TortoiseSVN的; TortoiseGit 。在64位Windows上运行的Windows资源管理器仅接受64位扩展;类似于在32位Windows上运行
分离32位和64位版本的 Microsoft Office (现在已经是COM / Ole一段时间了)与COM加载项的位数相同
可以能够绕过的唯一方法是希望32位客户端连接到64位服务器,如果您添加适当的DCOM注册并在另一个盒子上运行您的服务器(运行Windows 64位),客户端通过网络连接到它。虽然,这可能不是特别有用。