当使用CreateProcessLogonW或类似的方法启动时,进程启动,但不能运行



我开始使用c#以编程方式运行我的应用程序,它在管理员帐户下工作得很好,但是一旦我开始使用不同用户的凭据运行它们"普通用户可以在登录时正常运行这些控制台应用程序",它们要么会像没有输入或输出的无限循环一样运行,.net的会崩溃,java会立即退出。

我需要在一个被监禁的用户下运行这些应用程序,除了它正在执行的应用程序之外,对系统没有最小的访问权限,重定向标准输入和输出,由在系统或管理员帐户下运行的主机应用程序处理,理想情况下隐藏这些已创建进程的控制台窗口。到目前为止,我已经在c#和c++的各种例子中尝试过了…

My Code in 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();

我的c++代码:

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中中断。但在上述两种解决方案中,我仍然遇到同样的问题,即应用程序不能正常运行。

另外,我注意到,当我不重定向输出时,我正在运行的这些进程将运行良好。所以这个问题似乎是与传递句柄为入,出和错误跨用户…

尝试查找ProcessInfo然后创建对象并分配您需要的属性。然后创建实际的Process对象,将processInfo对象分配给该Process,并创建一个while循环来检查退出代码

好了,经过更多的测试,我发现"据我所知"不可能直接将在一个用户下运行的应用程序的输出和输入路由到在admin类型用户下运行的主机应用程序。

所以我用命名管道解决了这个问题,我用c++创建了一个基本的应用程序,打算在用户下运行,这个应用程序用命令行参数指定的名称打开命名管道。这个"包装器"应用程序使用CreateProcess运行所需的应用程序,因为包装器已经在正确的用户下运行。In、Out和Error流由包装器重定向到包装器启动时打开的命名管道。

我的主机应用程序可以通过包装器打开的管道与在不同用户下运行的应用程序通信。

运行良好,问题解决了:)

最新更新