我目前正在研究将com +安全上下文设置为:无管理winforms进程的问题。
在.NET中,不可能将CoInitializeSecurity设置为Main之后的第一行代码,为时已晚。正如我所理解的那样,CLR已经调用了该方法。
在以下链接中: http://www.pinvoke.net/default.aspx/ole32.coinitializesecurity
写道:
"解决方法是写一个不受管理的" shim"将调用CoInitializeSecurity,然后激活并调用托管代码。您可以通过从混合模式C ++ DLL导出,注册托管组件以供COM使用,或使用CLR托管API来完成此操作。"
有人可以对此有所了解吗?应该如何用非托管代码编写(语言并不重要)
托管应用程序不时调用com + server,我看不到 任何我应该直接激活界面通过的原因 托管代码的指针?
答案 0 :(得分:2)
解决方法是编写一个非托管的" shim"将调用CoInitializeSecurity,然后激活并调用托管代码。您可以通过从混合模式C ++ DLL导出,注册托管组件以供COM使用,或使用CLR托管API来完成此操作。
这意味着您创建了一个非常小的原生.exe(" Shim")用c / c ++表示调用CoInitializeEx()
然后调用CoInitializeSecurity
作为为整个 Windows进程建立COM安全环境的方法。
----------------------------------
| Windows Process |
| ----------- ---------- |
| | exe | COM | dll | |
| | "Shim" | ====> | | |
| | (c/c++) | | c# | |
| ----------- ---------- |
-----------------------------------
代码:
// pseudo c++ code
.
.
.
int main (int argc, char* argv)
{
CoInitializeEx(...);
CoInitializeSecurity(...);
IMyContractPtr pFoo (__uuidof (MyClass));
pFoo->RunMe();
CoUnitialize();
}
有了这个,下一个技巧是从c / c ++调用你的.NET代码。这里最简单的方法是创建一个ComVisible(True)
c#类,向COM公开一个方法,比如RunMe()
,当被调用时显示你的WinForms表单。
public interface IMyContractPtr
{
void RunMe();
}
[ComVisible(true)] // there are cleaner ways to expose COM-visible
public class MyClass : IMyContractPtr
{
public void RunMe()
{
var form = new MainForm();
form.ShowDialog(); // example
}
}
您需要将代码从c#.exe项目移动到新的c#程序集/库中。正是这个库将公开将从您的c / c ++应用程序调用的COM可见类。 (虽然c / c ++应用程序不关心它是否在COM exe或dll中,但是对于这个例外,你不想通过尝试将另一个.exe加载到已经运行的Windows进程来混淆该问题)
通过使主窗口成为模态对话框,我在这里简化了一些事情。模态对话框有自己的Windows消息泵处理,我们通过将表单代码放入dll并丢弃原始程序的Main()
方法和Application.Run(new MainForm());
的优点来解决这个问题。< / p>