托管应用程序的 CoInitializeSecurity,创建垫片?
Posted
技术标签:
【中文标题】托管应用程序的 CoInitializeSecurity,创建垫片?【英文标题】:CoInitializeSecurity for managed application, creating a shim? 【发布时间】:2018-07-10 16:38:25 【问题描述】:我目前正在研究将 com+ 安全上下文设置为:托管 winforms 进程的无。
在 .NET 中,不可能将 CoInitializeSecurity 设置为 Main 之后的第一行代码,为时已晚。据我了解,CLR 已经调用了该方法。
在下面的链接中: http://www.pinvoke.net/default.aspx/ole32.coinitializesecurity
上面写着:
“解决方法是编写一个将调用 CoInitializeSecurity 的非托管“shim”,然后激活并调用托管代码。您可以通过从混合模式 C++ DLL 导出,注册一个托管组件供以下人员使用来完成此操作COM,或使用 CLR 托管 API。”
有人能解释一下吗?应该如何用非托管代码编写(语言无关紧要)
托管应用程序时不时调用 com+ 服务器,我看不到 我应该立即激活界面以通过的任何理由 指向托管代码的指针?
【问题讨论】:
您发布的 PInvoke 链接中的代码示例按原样为我工作。您使用的是什么版本的 Visual Studio 和 .NET Framework?另外,请注意您引用的文本下方的更新:引用:“通常......在 CoInitializeSecurity 已经调用时发生(隐式或显式,这无关紧要)。当您使用 Visual Studio 时,它使用所谓的“Visual Studio Hosting已经调用 CoInitializeSecurity 的进程”。关闭 Visual Studio 托管进程并享受乐趣,现在您可以调试调用 CoInitializeSecurity 的应用程序,而不会出现 RPC_E_TOO_LATE 错误。” ".. CoInitialize 将implicitly call
CoInitializeSecurity 如果尚未调用..." - 在提供的链接中不正确 .请参考 MSDN doco 以及***.com/questions/30560589/…
【参考方案1】:
解决方法是编写一个将调用 CoInitializeSecurity 的非托管“shim”,然后激活并调用托管代码。您可以通过从混合模式 C++ DLL 导出、注册供 COM 使用的托管组件或使用 CLR 托管 API 来执行此操作。
这意味着您在 c/c++ 中创建了一个非常小的原生 .exe(“Shim”),它调用 CoInitializeEx()
,然后调用 CoInitializeSecurity
,作为建立 COM 安全环境的方法整个 Windows 进程。
----------------------------------
| 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());
的优点,将其删除。
告诉我更多
How to call a managed DLL from native Visual C++ code
CoInitializeEx
CoInitializeSecurity
【讨论】:
难道不能启动本机 dll,设置 CoInitializeSecurity 并运行另一个进程,将“主机的”DCOM 安全设置传递给它吗? @John 可能不会。尽管可以将某些设置传递给子窗口进程(如窗口句柄),但我认为这不适用于 COM。此外,您不应调用 COM 初始化函数,包括库中的CoInitializeSecurity
以上是关于托管应用程序的 CoInitializeSecurity,创建垫片?的主要内容,如果未能解决你的问题,请参考以下文章
一个解决方案中的非托管 DLL 项目和托管 WinForms 应用程序