#c# #c #com #com-interop #credential-providers
#c# #c #com #com-взаимодействие #поставщики учетных данных
Вопрос:
Я создал пользовательский поставщик учетных данных для Windows. Базовая библиотека DLL находится на C и загружает C # DLL через COM-интерфейс.
if (CoInitialize(NULL) != S_OK) {
hr = _authenticationManager.CreateInstance("{BAF984BD-0D41-42D1-AA49-4BC98EE6C4A1}");
std::stringstream stream;
stream << std::hex << (int)hr;
MessageBoxA(NULL, stream.str().c_str(), "", 0);
Класс зарегистрирован так :
REGEDIT4
[HKEY_CLASSES_ROOTRecord{71C93A0D-861E-3195-A2D8-51DA34307BCA}1.0.0.0]
"Class"="AuthenticationManager.BUTTON_TYPE"
"Assembly"="AuthenticationManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.30319"
[HKEY_CLASSES_ROOTAuthenticationManager.AuthenticationManager]
@="AuthenticationManager.AuthenticationManager"
[HKEY_CLASSES_ROOTAuthenticationManager.AuthenticationManagerCLSID]
@="{BAF984BD-0D41-42D1-AA49-4BC98EE6C4A1}"
[HKEY_CLASSES_ROOTCLSID{BAF984BD-0D41-42D1-AA49-4BC98EE6C4A1}]
@="AuthenticationManager.AuthenticationManager"
[HKEY_CLASSES_ROOTCLSID{BAF984BD-0D41-42D1-AA49-4BC98EE6C4A1}InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="AuthenticationManager.AuthenticationManager"
"Assembly"="AuthenticationManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.30319"
[HKEY_CLASSES_ROOTCLSID{BAF984BD-0D41-42D1-AA49-4BC98EE6C4A1}InprocServer321.0.0.0]
"Class"="AuthenticationManager.AuthenticationManager"
"Assembly"="AuthenticationManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.30319"
[HKEY_CLASSES_ROOTCLSID{BAF984BD-0D41-42D1-AA49-4BC98EE6C4A1}ProgId]
@="AuthenticationManager.AuthenticationManager"
[HKEY_CLASSES_ROOTCLSID{BAF984BD-0D41-42D1-AA49-4BC98EE6C4A1}Implemented Categories{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]
Разделение C # DLL выглядит следующим образом :
[Guid("BAF984BD-0D41-42D1-AA49-4BC98EE6C4A1")]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IAuthenticationManager))]
public class AuthenticationManager : IAuthenticationManager
Он отлично работает при использовании winlogon для входа на компьютер, когда я выхожу из системы, провайдер загружается, и C # тоже, все хорошо
Но, когда я использую его для других целей, не удается загрузить COM-компонент : CreateInstance возвращает 0x80040154 (REGDB_E_CLASSNOTREG).
Пример использования, который не работает: SHIFT ЩЕЛКНИТЕ ПРАВОЙ КНОПКОЙ мыши на exe -> Выполнить от имени другого пользователя, поставщик загружен, а класс не найден…
Я слышал на форумах, что источником проблемы может быть смешивание 32 и 64 бит, но оба процесса (winlogon и explorer) являются x64, и все мои библиотеки dll (credential AuthenticationManager) тоже x64.
Не могли бы вы мне помочь, я застрял на 3 дня….
Большое вам спасибо.
Комментарии:
1. Вы, вероятно, захотите взглянуть на github.com/SteveSyfuhs/CredProvider.NET
Ответ №1:
Больше COM — плохая идея! Альтернативно, вы можете использовать Visual C CLI. Поддержка CLI является связующим звеном между собственным C и управляемым C#.NET библиотеки.
Комментарии:
1. Могу ли я скомпилировать свой поставщик учетных данных в C CLI и загрузить его в Windows?
2. Я тестировал и даже не могу его скомпилировать, потому что ему нужен secur32, который недоступен с CLI.
3. Это не то, что я хотел сделать. Я хотел заставить работать мой COM, избегая этого C CLI. Но, наконец …… я сделал резервную копию этого решения.