2

What i'm trying to do is writing a little wrapper, that allows me to start an application on the Windows GUI of the currently locked in User from withing a service. The wrapper is called as following: "wrapper.exe mspaint arg1 arg2 < some-piped-input". Everything works fine, except the pipe stuff. At the moment i'm creating 3 pipes (for stdin, stdout, stderr), that should redirect the input, that is piped to the wrapper (in the example some-piped-input) to the process of the GUI-Application and the output/error to stdout/stderr of the wrapper.

I do not get any errors, it just doesn't work.

With the following code none of these pipes works:

pi = new PROCESS_INFORMATION();
sa = new SECURITY_ATTRIBUTES();
saProcess = new SECURITY_ATTRIBUTES();
saThread = new SECURITY_ATTRIBUTES();
si = new STARTUPINFO();

sa.nLength = (uint)Marshal.SizeOf(sa);
sa.lpSecurityDescriptor = IntPtr.Zero;
sa.bInheritHandle = true;

saProcess.nLength = (uint)Marshal.SizeOf(saProcess);
saThread.nLength = (uint)Marshal.SizeOf(saThread);

si.cb = (uint)Marshal.SizeOf(si);

// Create in/out/err pipes
subprocessStdIn = new IntPtr();
subprocessStdOut = new IntPtr();
subprocessStdErr = new IntPtr();

// Get main processes in/out/err pipes
mainProcessStdIn = GetStdHandle(StdHandle.Stdin);
mainProcessStdOut = GetStdHandle(StdHandle.Stdout);
mainProcessStdErr = GetStdHandle(StdHandle.Stderr);

//                 this ---------------> subprocess
if (CreatePipe(ref subprocessStdIn, ref mainProcessStdIn, ref sa, 0x0001))
{
    Console.WriteLine("Pipe stdIn   --> pIn created.");
    si.hStdInput = subprocessStdIn;
}


//                 this <--------------- subprocess
if (CreatePipe(ref mainProcessStdOut, ref subprocessStdOut, ref sa, 0x0001))
{
    Console.WriteLine("Pipe stdOut <--  pOut created.");
    si.hStdOutput = subprocessStdOut;
}

//                 this <--------------- subprocess
if (CreatePipe(ref mainProcessStdErr, ref subprocessStdErr, ref sa, 0x0001))
{
    Console.WriteLine("Pipe stdErr <--  pErr created.");
    si.hStdError = subprocessStdErr;
}

si.lpDesktop = @"WinSta0\Default"; //Modify as needed 
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK | STARTF_USESTDHANDLES;
si.wShowWindow = SW_SHOW;

CreateProcessAsUser(token, null, cmdLine, ref saProcess, ref saThread, false, CREATE_UNICODE_ENVIRONMENT, envBlock, null, ref si, out pi);
andred
  • 1,204
  • 1
  • 17
  • 29
  • Almost all GUI processes completely ignore stdin, stdout and stderr. What are you expecting to happen? – arx Apr 29 '13 at 13:54
  • I'd just like to execute the exactly same command, as if i run the application without the wrapper. And looking forward, the issue will get me, if i want to run non-gui applications in the future. – andred Apr 29 '13 at 15:07
  • So what isn't happening that you expect to happen? – arx Apr 29 '13 at 16:00
  • I want the piped input to be directly lead through to the spawned process. And i want the output of the spawned process to be directed, as if it comes from the wrapper. – andred Apr 29 '13 at 16:24
  • For a start you are trying to read and write from the service's stdio. Which isn't going to work, services do not run in a console. So instead of `GetStdHandle` you must create new named pipes which you can read and write to. then join the other end of those pipes to your command's stdout, stdin and stderr. Then you can read from these pipes. You must also communicate back with your command line app over named pipes. The service must read from the stdout pipe and then write to the client pipe. And the reverse, best to use 2 independent threads here. – silicontrip Mar 27 '21 at 07:16

0 Answers0