我试图让COM启动我的进程外的.NET COM服务器。 如果服务器进程是用x64编译的,但是如果我使用AnyCPU(这是我想要的),那么它会挂起一段时间,并最终以0x80080005(CO_E_SERVER_EXEC_FAILURE)失败。 我怎样才能使这个工作?
另一个人也有类似的问题 ,但MSFT的答案是混乱的。 他似乎暗示它只能通过DCOM(请参阅链接)或COM +工作。 我怀疑要么会是一个非常多的工作,而且比分配我的.exe作为x64和x86构build更差。
您可能想知道为什么我正在实施IPersistFile。 这是因为我真正的问题是从一个32位的C ++程序工作到我的AnyCPU .Net程序的BindMoniker()。 我已经减less了我的问题到这里提出的更简单的例子。
这里是客户端代码:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } [DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)] [return: MarshalAs(UnmanagedType.Interface)] static extern object CoCreateInstance( [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, [MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, CLSCTX dwClsContext, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid); [Flags] enum CLSCTX : uint { CLSCTX_LOCAL_SERVER = 0x4, CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000, } private void Form1_Load(object sender, EventArgs e) { IPersistFile pf = (IPersistFile)CoCreateInstance( new Guid("1984D314-FC8D-44bc-9146-8A13500666A6"), null, CLSCTX.CLSCTX_LOCAL_SERVER, new Guid("0000010b-0000-0000-C000-000000000046")); // IPersistFile pf.Load("c:\\bozo", 0); } }
这里是服务器:
static class Program { [STAThread] static void Main() { if (Environment.CommandLine.Contains("/reg")) { RegistryKey cls = Registry.LocalMachine.CreateSubKey(String.Format( "SOFTWARE\\Classes\\CLSID\\{0}", PersistFile.ClassID.ToString("B"))); cls.SetValue("InprocHandler32", "Ole32.dll"); RegistryKey ls32 = cls.CreateSubKey("LocalServer32"); ls32.SetValue(null, '"' + Application.ExecutablePath + '"'); ls32.SetValue("ServerExecutable", Application.ExecutablePath); } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); RegistrationServices reg = new RegistrationServices(); reg.RegisterTypeForComClients( typeof(PersistFile), RegistrationClassContext.LocalServer, RegistrationConnectionType.MultipleUse); Application.Run(new Form1()); } } [ComVisible(true), Guid("1984D314-FC8D-44bc-9146-8A13500666A6"), ClassInterface(ClassInterfaceType.None)] public class PersistFile : IPersistFile { public static Guid ClassID { get { GuidAttribute a = (GuidAttribute)typeof(PersistFile).GetCustomAttributes(typeof(GuidAttribute), false)[0]; return new Guid(a.Value); } } #region IPersistFile public void GetClassID(out Guid pClassID) { MessageBox.Show("GetClassID"); pClassID = ClassID; } public int IsDirty() { MessageBox.Show("IsDirty"); return 1; } public void Load(string pszFileName, int dwMode) { MessageBox.Show(String.Format("Load {0}", pszFileName)); } public void Save(string pszFileName, bool fRemember) { MessageBox.Show("Save"); throw new NotImplementedException(); } public void SaveCompleted(string pszFileName) { MessageBox.Show("SaveCompleted"); throw new NotImplementedException(); } public void GetCurFile(out string ppszFileName) { MessageBox.Show("GetCurFile"); throw new NotImplementedException(); } #endregion }
尝试使用RegistrationServices类来注册您的com程序集。 它也将选择正确的注册表修改,并做一些其他的事情。
例:
Assembly currentAssembly = Assembly.GetExecutingAssembly(); System.Runtime.InteropServices.RegistrationServices regAsm = new System.Runtime.InteropServices.RegistrationServices(); bool isRegistered = regAsm.RegisterAssembly(currentAssembly, System.Runtime.InteropServices.AssemblyRegistrationFlags.SetCodeBase);
此外,我认为,.NET客户端程序集根据.NET COM服务器有一些麻烦,但我找不到任何资源…
希望,这将有助于…
我想这个问题是在运行时。 我已经创建了一个COM服务器,使用C ++库进行注册(注册完美无瑕)。 从.NET(CS)切换到AnyCPU时遇到问题。
架构:
注册构建为“AnyCPU”的.NET应用程序时会发生丑陋的事情。 一旦COM客户端通过DCOM调用COM服务器,服务器应用程序启动,但客户端收到COM服务器无法启动的错误。
我又进了一步,用procmon和其他工具分析了注册数据,得出了同样的结论:
现在,我做了更多的实验:x86 / x64 / AnyCPU COM客户端可以连接到任何x86 / x64 COM服务器没有问题,但它不能连接任何AnyCPU COM服务器…
然后我执行了以下测试用例:
地狱是沟通的问题? 这是非常奇怪的…没有提出的解决方案(CLSCTX_ACTIVATE_64_BIT_SERVER,PreferredserverBitness或corflags)帮助。
还有人在这个问题上取得了一些进展? 我们应该联系微软吗?