Процессы запускаются, но не работают при запуске с CreateProcessLogonW или аналогичными методами - PullRequest
0 голосов
/ 03 декабря 2011

Я начал использовать C # для программного запуска своих приложений, и он работал нормально под учетной записью администратора, но как только я начал запускать их с учетными данными другого пользователя - обычного пользователя, который может нормально запускать эти консольные приложения при входе в систему msgstr "они либо работали бы так, как если бы они были бесконечным циклом без ввода или вывода, .net - сбои, и java немедленно выходил бы.

Мне нужно запустить эти приложения в тюрьме, не имея минимального доступа к системе за пределами приложения, которое оно выполняет, перенаправить стандартный ввод и вывод для обработки хост-приложением, работающим под учетной записью системы или администратора, и в идеале спрятать консольные окна этих созданных процессов. До сих пор я пробовал это в C # и с различными примерами C ++ ...

Мой код в C #:

// Start the process
currentProcess = new Process();
currentProcess.StartInfo.FileName = AppFile;
currentProcess.StartInfo.Arguments = Args;
// No window and make sure all output is redirected to us
// TODO: Start process as a jailed user
currentProcess.StartInfo.CreateNoWindow = true;
currentProcess.StartInfo.UseShellExecute = false;
currentProcess.StartInfo.WorkingDirectory = AppPath;
currentProcess.StartInfo.UserName = User.Username;
currentProcess.StartInfo.Password = User.Password;
currentProcess.StartInfo.RedirectStandardInput = true;
currentProcess.StartInfo.RedirectStandardError = true;
currentProcess.StartInfo.RedirectStandardOutput = true;
currentProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
currentProcess.EnableRaisingEvents = true;
currentProcess.Exited += new EventHandler(ExitedHandler);
currentProcess.Start();

Мой код на С ++:

PROCESS_INFORMATION pi;
STARTUPINFO si;

// Set up the start up info struct.
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;// | STARTF_USESHOWWINDOW;
si.hStdOutput = hChildStdOut;
si.hStdInput  = hChildStdIn;
si.hStdError  = hChildStdErr;
// Use this if you want to hide the child:
//si.wShowWindow = SW_HIDE;
// Note that dwFlags must include STARTF_USESHOWWINDOW if you want to
// use the wShowWindow flags.


// Launch the process that you want to redirect (in this case,
// Child.exe). Make sure Child.exe is in the same directory as
// redirect.c launch redirect from a command line to prevent location
// confusion.
//CreateProcessAsUser(hptoken, 0, cmd, 0, 0, FALSE, 0, 0, 0, &si, &pi )

HANDLE hTempUser;
//LogonUserA("tesy","TIM-WORK","test", LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &hTempUser);
//if (hTempUser == INVALID_HANDLE_VALUE || hTempUser == NULL)
//    DisplayError("LoginUser");
//else if (!DuplicateTokenEx(hTempUser, 0, NULL, SECURITY_IMPERSONATION_LEVEL::SecurityImpersonation, TOKEN_TYPE::TokenPrimary, &hUserToken))
//    DisplayError("DuplicateUserToken");
//
//// Close the temporary handle to the user
//CloseHandle(hTempUser);

//if (GrantDesktopAccess(hUserToken) != S_OK)
//    DisplayError("GrantDesktop");

//if (!CreateProcessAsUserA(hUserToken,NULL,"C:\\test\\test.exe",NULL,NULL,FALSE,NULL,NULL,NULL,&si,&pi))
//   DisplayError("CreateProcessAsUser");

//CreateProcessWithTokenW(hUserToken, NULL, L"C:\\test\\test.exe", NULL, NULL, NULL, L"C:\\test\\", &si, &pi);
CreateProcessWithLogonW(L"tesy", L"TIM-WORK", L"test", LOGON_WITH_PROFILE, L"C:\\test\\test.exe", NULL, CREATE_NEW_CONSOLE, NULL, L"C:\\test\\", &si, &pi);
//if (GetLastError() > 0);
//    DisplayError("CreateProcessWithLogon");

// Set global child process handle to cause threads to exit.
hChildProcess = pi.hProcess;

// Close any unnecessary handles.
if (!CloseHandle(pi.hThread)) DisplayError("CloseHandle");

C ++ - лучшее решение для меня, так как я могу скрыть окно процесса, эта функциональность прерывается в .net, как только указаны имя пользователя и пароль. Но в обоих вышеупомянутых решениях я по-прежнему сталкиваюсь с одной и той же проблемой, когда приложения работают неправильно.

Кроме того, я заметил, что эти процессы, которые я запускаю, будут работать нормально, если я не перенаправлю вывод. Таким образом, проблема заключается в передаче дескрипторов входа, выхода и ошибки между пользователями ...

Ответы [ 2 ]

0 голосов
/ 05 декабря 2011

Хорошо, после дополнительного тестирования я обнаружил, что «насколько мне известно» невозможно напрямую направить вывод и ввод приложения, работающего под одним пользователем, на хост-приложение, работающее под пользователем типа администратора.

Итак, я решил это с именованными каналами, я создал базовое приложение на c ++, предназначенное для запуска под пользователем, которое открывает именованные каналы с именем, указанным в аргументе командной строки. Это приложение-оболочка запускает нужное приложение с помощью CreateProcess, поскольку оболочка уже запущена под нужным пользователем. Потоки In, Out и Error перенаправляются оболочкой на именованные каналы, открытые при запуске оболочки.

Мое хост-приложение может затем связаться с приложением, работающим под другим пользователем, через каналы, открытые оболочкой.

Работает хорошо, проблема решена:)

0 голосов
/ 03 декабря 2011

попробуйте поискать ProcessInfo, затем создайте объект и назначьте там нужные вам свойства ... после этого создайте фактический объект Process, назначьте объект processInfo этому процессу и создайте цикл while для проверки кода выхода

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...