Question

I'm currently playing with CreateProcessAsUser using P/Invoke from c#, in order to launch process as limited users from a windows Service running in SYSTEM Account.

My objective is to have a Service that launches an app that needs to get info from users on our office (process running in foreground, time idle, etc.). Problem is that if this app is running with user's privilige... well, he can close it. If running like a regular process from another app I can control this respawn with:

ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = ExePath;
psi.UseShellExecute = false;

Process p = new Process();
p.StartInfo = psi;
p.EnableRaisingEvents = true;
p.Exited += new EventHandler(LaunchAgain);
p.Start();

But this way, my problem is that instead having a no-respawn-closable-by-user-app, I have two-apps-closable-by-user (well, but one of them respawns the other :P).

Do you know it there is some way of know if a process created by CreateProcessAsUser can be "monitored" to launch some action when it's killed or terminated?

PD: Of course, be free of suggest any kind of improve or different approaches.

Was it helpful?

Solution 2

I finally managed to solve it:

ProcessRunner runner = new ProcessRunner(Path, hSessionToken);
runner.Run();
this.Launch(context);

And in my ProcessRunner class i used something like:

CreateProcessAsUser(this.mSessionTokenHandle, this.mApplicationPath, this.CommandLine, IntPtr.Zero, IntPtr.Zero, 0, creationFlags, envBlock, this.WorkingDirectory, si, pi);
ProcessWaitHandle waitable = new ProcessWaitHandle(pi.hProcess);
if (waitable.WaitOne())
{
    return;
}  

because WaitOne returns true when it gets signaled.

This is my class to fiddle with the wait handle.

internal class ProcessWaitHandle : WaitHandle
{
    public ProcessWaitHandle(IntPtr processHandle)
    {
        this.SafeWaitHandle = new SafeWaitHandle(processHandle, false);
    }
}

Thanks to JeffRSon for the idea to work with the handles.

OTHER TIPS

Two things - CreateProcessAsUser has a parameter lpProcessInformation that receives data about the new process. You could then wait on the process handle. Or you could create a C# process class by Process.GetProcessById(...) and use it like in your snippet above.

OTOH, it might be simpler to do the functiom (collect information - if I understand it right) right from your service.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top