Я пытаюсь запустить приложение .NET под другим пользователем из службы .NET. Идея состоит в том, чтобы создать изолированное хостинговое приложение в Windows. В службе я программно создал пользователя в Windows, создал папку для этого пользователя и загрузил хост .exe с сервера в эту папку. Затем я запускаю хост .exe с помощью System.Diagnostics.Process. Вот StartInfo для процесса:
_process = new Process
{
StartInfo =
{
Arguments = " -debug",
FileName = instanceDirectory + "host.exe",
WorkingDirectory = instanceDirectory,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
UserName = Helpers.GetUserNameForInstance(_hostid),
Password = _hostpass,
Domain = ""
},
EnableRaisingEvents = true
};
Когда я запускаю службу как СЛУЖБУ, процесс мгновенно завершается с ошибкой с кодом -1073741502. но когда я запускаю службу от имени того же пользователя, который указан в службе Windows, но в интерактивном режиме в консоли, все работает нормально. Это происходит только при запуске службы в качестве СЛУЖБЫ, а не непосредственно в консоли.
Любая помощь приветствуется. Это уже давно стало головной болью, и это последнее средство :(
Ответ 1 · рейтинг 14 · Gyuri
Похоже, что при использовании new Process() с именем пользователя и паролем, а сервисный режим "не вычисляет" :)
Цитата из MSDN:
Вы можете изменить параметры, указанные в свойстве StartInfo, до момента вызова метода Start для процесса. После запуска процесса изменение значений StartInfo не влияет на связанный процесс и не перезапускает его. Если вы вызываете метод Start (ProcessStartInfo) с установленными свойствами ProcessStartInfo .. ::. UserName и ProcessStartInfo .. ::. Password, вызывается неуправляемая функция CreateProcessWithLogonW, которая запускает процесс в новом окне, даже если значение свойства CreateNoWindow имеет значение true или значение свойства WindowStyle - Hidden.
Кроме того, посмотрев документацию CreateProcessWithLogonW:
lpStartupInfo [дюйм]
Указатель на структуру STARTUPINFO. Приложение должно добавить разрешение для указанной учетной записи пользователя на указанную оконную станцию и рабочий стол, даже для WinSta0 \ Default.
Если член lpDesktop имеет значение NULL или пустую строку, новый процесс наследует рабочий стол и оконную станцию своего родительского процесса. Приложение должно добавить разрешение для указанной учетной записи пользователя унаследованной оконной станции и рабочему столу.
В .NET StartupInfo нет lpDesktop, с другой стороны, у пользователя SERVICE нет рабочего стола, что может вызвать вашу проблему.
Короче говоря, попробуйте установить LoadUserProfile на true, чтобы загрузить информацию о пользователе из реестра, или, может быть, вам нужно установить рабочий каталог и т. Д.
Для дальнейшего исследования вам следует проверить свою среду и, возможно, записать, к каким файлам осуществляется доступ с помощью FileMon.
Ответ 2 · рейтинг 5 · Sean Kornish
Я бы попытался создать процесс в олицетворенном контексте вновь созданного пользователя, как показано ниже.
[DllImport("advapi32.DLL", SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
static void Main()
{
IntPtr admin_token = new IntPtr();
WindowsIdentity wid_admin = null;
WindowsImpersonationContext wic = null;
LogonUser("username", "domain", "password", 9, 3, out admin_token);
wid_admin = new WindowsIdentity(admin_token);
wic = wid_admin.Impersonate();
_process = new Process
{
StartInfo =
{
Arguments = " -debug",
FileName = instanceDirectory + "host.exe",
WorkingDirectory = instanceDirectory,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
UserName = Helpers.GetUserNameForInstance(_hostid),
Password = _hostpass,
Domain = ""
},
EnableRaisingEvents = true
};
if (wic != null) wic.Undo();
CloseHandle(admin_token);
}
Ответ 4 · рейтинг 2 · wj32
0xc0000142 (-1073741502) имеет статус STATUS_DLL_INIT_FAILED:
Инициализация библиотеки динамической компоновки [имя] не удалась. Процесс аварийно завершается.
Как указано на веб-сайте TenaciousImpy, вам необходимо предоставить разрешения учетной записи для оконной станции и рабочего стола. Но если программа интерактивна, вам также необходимо установить идентификатор сеанса для токена процесса.