我开始使用C#以编程方式运行我的应用程序,它在管理员帐户下工作正常,但是一旦我开始使用其他用户的凭据运行它们“可以在登录时正常运行这些控制台应用程序的常规用户“,它们要么就好像它们是无限循环而没有输入或输出,.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();
我在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中中断。 但是在上面的两个解决方案中,我仍然遇到应用程序无法正常运行的相同问题。
此外,我注意到,当我不重定向输出时,我正在运行的这些进程将正常运行。所以问题似乎是在用户之间传递输入,输出和错误的句柄......
答案 0 :(得分:0)
尝试查找ProcessInfo然后创建对象并分配您需要的属性..之后创建实际的Process对象将processInfo对象分配给该Process并创建while循环以检查退出代码
答案 1 :(得分:0)
好的,经过更多的测试后,我发现“根据我的知识”直接将在一个用户下运行的应用程序的输出和输入路由到在管理类型用户下运行的主机应用程序是不可能的。
所以我用命名管道解决了它,我在c ++中创建了一个基本应用程序,用于在用户下运行,该应用程序打开命名管道,其名称由命令行参数指定。这个“包装器”应用程序使用CreateProcess运行所需的应用程序,因为包装器已经在正确的用户下运行。 In,Out和Error流由包装器重定向到启动包装器时打开的命名管道。
然后,我的主机应用程序可以通过包装程序打开的管道与在不同用户下运行的应用程序进行通信。
工作正常,问题解决了:)