Using Process.Start() to start a process as a diff

2019-01-03 23:25发布

I'd like to periodically run an arbitrary .NET exe under a specified user account from a Windows Service.

So far I've got my windows service running with logic to decide what the target process is, and when to run it. The target process is started in the following manner:

  1. The Windows Service is started using "administrator" credentials.
  2. When the time comes, an intermediate .NET process is executed with arguments detailing which process should be started (filename, username, domain, password).
  3. This process creates a new System.Diagnostics.Process, associates a ProcessStartInfo object filled with the arguments passed to it, and then calls Start() on the process object.

The first time this happens, the target process executes fine and then closes normally. Every subsequent time however, as soon as the target process is started it throws the error "Application failed to initalize properly (0xc0000142)". Restarting the Windows Service will allow the process to run successfully once again (for the first execution).

Naturally, the goal is to have target process execute successfully every time.

Regarding step 2 above: To run a process as a different user .NET calls the win32 function CreateProcessWithLogonW. This function requires a window handle to log the specified user in. Since the Windows Service isn't running in Interactive Mode it has no window handle. This intermediate process solves the issue, as it has a window handle which can be passed to the target process.

Please, no suggestions of using psexec or the windows task planner. I've accepted my lot in life, and that includes solving the problem in the manner stated above.

8条回答
老娘就宠你
2楼-- · 2019-01-03 23:55

I've just read this comment over at msdn (http://msdn.microsoft.com/en-us/library/ms682431(VS.85).aspx):

Don't call user applications with this function! ChristianWimmer |
Edit | Show History Please Wait If you going to call user mode applications that offer document editing and similar stuff (like Word), all unsaved data will be lost. This is because the usual shutdown sequence does not apply to processes launched with CreateProcessWithLogonW. In this way the launched applications do not get WM_QUERYENDSESSION, WM_ENDSESSION and the most important WM_QUIT message. So they don't ask for saving the data or clean up their stuff. They will just quit without warning. This function is not user friendly and should be used with caution.

It is just "bad user experience". Nobody expects it.

This could explain what I've observed: Works the first time. Fails every subsequent time. That reinforces my belief that something isn't being cleaned up properly internally

查看更多
不美不萌又怎样
3楼-- · 2019-01-03 23:56

I won't suggest neither psexec nor the task planner. But, have you looked at Sudowin?

It does almost exactly what you wish, with the exception it asks for a password before executing the process.

Also, being open source and all, you can see how it executes processes from the associated service time and again.

查看更多
登录 后发表回答