【问题标题】:CoInitializeSecurity for managed application, creating a shim?托管应用程序的 CoInitializeSecurity,创建垫片?
【发布时间】: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 以及stackoverflow.com/questions/30560589/…

标签: c# .net atl com+


【解决方案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()); 的优点,将其删除。

告诉我更多

【讨论】:

  • 难道不能启动本机 dll,设置 CoInitializeSecurity 并运行另一个进程,将“主机的”DCOM 安全设置传递给它吗?
  • @John 可能不会。尽管可以将某些设置传递给子窗口进程(如窗口句柄),但我认为这不适用于 COM。此外,您不应调用 COM 初始化函数,包括库中的 CoInitializeSecurity
猜你喜欢
  • 2012-03-19
  • 2013-04-30
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 2012-04-16
  • 2010-10-31
  • 2018-11-02
  • 2019-10-19
相关资源
最近更新 更多