CoInitializeSecurity для управляемого приложения, создание прокладки?

В настоящее время я исследую проблему установки контекста безопасности com+ на: None для управляемого процесса winforms.

В .NET нельзя установить CoInitializeSecurity первой строкой кода после Main, слишком поздно это делать. Насколько я понял, этот метод уже вызывается CLR.

По ссылке ниже: http://www.pinvoke.net/default.aspx/ole32.coinitializesecurity

Это написано:

Обходной путь состоит в том, чтобы написать неуправляемую «прокладку», которая будет вызывать CoInitializeSecurity, а затем активировать и вызывать управляемый код. Вы можете сделать это с помощью экспорта из DLL C++ смешанного режима, зарегистрировав управляемый компонент для использования COM или с помощью API размещения CLR».

Может ли кто-нибудь пролить свет на это? Как это должно быть написано в неуправляемом коде (язык не имеет значения)

Управляемое приложение время от времени вызывает сервер com+, и я не вижу причин, почему я должен сразу же активировать интерфейс, чтобы передать указатель на управляемый код?


person John    schedule 31.01.2018    source источник
comment
Пример кода в ссылке PInvoke, которую вы разместили, работал у меня как есть. Какую версию Visual Studio и .NET Framework вы используете? Так же обратите внимание на обновление под процитированным вами текстом: QUOTE: Обычно... бывает, когда CoInitializeSecurity уже вызывается (неявно или явно, не важно). Когда вы используете Visual Studio, он использует так называемый процесс размещения Visual Studio, где CoInitializeSecurity уже вызывается. Отключите процесс размещения Visual Studio и получайте удовольствие, теперь вы можете отлаживать приложение, которое вызывает CoInitializeSecurity, без ошибки RPC_E_TOO_LATE.   -  person felix-b    schedule 31.01.2018
comment
.. CoInitialize вызовет implicitly call CoInitializeSecurity, если он еще не был вызван... - это неверно в предоставленной ссылке. Пожалуйста, обратитесь к документу MSDN, а также к заголовку stackoverflow.com/questions/30560589/   -  person MickyD    schedule 31.01.2018


Ответы (1)


Обходной путь — написать неуправляемую «прокладку», которая будет вызывать CoInitializeSecurity, а затем активировать и вызывать управляемый код. Это можно сделать с помощью экспорта из библиотеки DLL C++ смешанного режима, путем регистрации управляемого компонента для использования COM или с помощью API размещения CLR.

Это означает, что вы создаете очень маленький собственный .exe ("Shim"), скажем, на c/c++, который вызывает 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();
}

После этого следующий трюк заключается в вызове кода .NET из c/c++. Здесь проще всего создать класс 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
   }
}

Вам нужно будет переместить свой код из проекта С# .exe в новую сборку/библиотеку С#. Именно эта библиотека будет предоставлять COM-видимый класс, который будет вызываться из вашего приложения c/c++. (хотя приложению c/c++ все равно, находится ли оно в COM-exe или dll, для этого упражнения вы не хотите запутать проблему, пытаясь загрузить другой .exe в уже запущенный процесс Windows)

Насосы сообщений и диалоги

Я немного упростил здесь, сделав главное окно модальным диалогом. Модальные диалоги имеют свою собственную обработку Windows Message Pump, которую мы убрали, поместив код вашей формы в dll и отказавшись от метода Main() вашей исходной программы и того добра, которое есть Application.Run(new MainForm());.

Расскажи мне больше

person MickyD    schedule 31.01.2018
comment
Нельзя ли запустить родную dll, установить CoInitializeSecurity и запустить другой процесс, передав ему настройки безопасности DCOM хоста? - person John; 01.02.2018
comment
@ Джон Вероятно, нет. Хотя некоторые настройки могут быть переданы дочерним процессам Windows (например, дескрипторы Windows), я не думаю, что это применимо к COM. Также вы не должны вызывать функции инициализации COM, включая CoInitializeSecurity из библиотеки. - person MickyD; 01.02.2018