开发者

How can a Windows Service start a process when a Timer event is raised?

开发者 https://www.devze.com 2023-02-01 09:57 出处:网络
I have created a Windows Service with Timer and in firing event of timer.Elapsed I am creating a process 开发者_如何转开发(System.Diagnostics.Process.Start(exe path)) at interval of 5 seconds. But thi

I have created a Windows Service with Timer and in firing event of timer.Elapsed I am creating a process 开发者_如何转开发(System.Diagnostics.Process.Start(exe path)) at interval of 5 seconds. But this process does not get created on the firing of an event.

Is there any other way of doing this?

Thanks in advance.

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{       

    Process pr = new Process();
    pr.StartInfo.FileName = @"C:\Program Files\Messenger\msmsgs.exe";
    pr.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
    pr.StartInfo.CreateNoWindow = false;
    pr.Start();
}


You're adding descriptions of the problem in the comments as you go along that would have been helpful to know at the outset. The reason that you can see the process has started but no window ever gets opened is because of security model changes that were made to Windows Services under Windows Vista and later. You haven't mentioned it specifically yet, but I have a strong suspicion that you're trying to run this under one of those operating systems. The real issue is not starting a process, it's showing a UI.

What you're trying to accomplish is called an "Interactive Service", which is one that is allowed to interact directly with the user and the desktop (i.e., show a window or dialog).
If you're using Windows XP (and your service will only ever have to run under Windows XP), you can follow the instructions in that article to enable your service to run in interactive mode, which will allow you to display the Adobe Acrobat application window as you expect. However, as that documentation also indicates, this feature does not work under Windows Vista and later:

Important  Services cannot directly interact with a user as of Windows Vista. Therefore, the techniques mentioned in the section titled Using an Interactive Service should not be used in new code.

More specifically, in those versions, changes were made to how services and applications are run. Services are now isolated by the system in Session 0, while applications are run in other sessions. This is intended to isolate services from attacks that originate in application code. Hence, no UI shown by a service will ever be visible to any user on the system, including a simple message box. You can read the white paper that explains these changes in more detail here. If you're a more visual person, refer to following diagram illustrating the new model, paying specific attention to the dividing lines:

     

How can a Windows Service start a process when a Timer event is raised?

The upshot is that if you're targeting those versions, or might ever need to target those versions, you can't use this loophole. I say "loophole" because the bottom line, as I mentioned in a comment, is that Windows Services are not intended to be interactive. What you're trying to do here runs contrary to the purpose and design of a service. It wasn't recommended before, and now it flat doesn't work at all. If you need this particular functionality, you should create a different kind of application. Both Windows Forms and WPF are intended for user-mode applications, and both can start processes and open new windows as necessary. I strongly recommend that you convert to this style of application instead.


Since you won't get a process to show UI from the service, I recommend that you run the helper process when the user logs on and start your process from it.


I realize I'm a little late to this party. But since this question came up in my search for a solution, I'll provide an answer to the OP's question.

You can start a program from a service using CreateProcessAsUser, using the token of the logged-on user. MSDN provides a nice sample app demonstrating this; look for CSCreateProcessAsUserFromService: https://code.msdn.microsoft.com/windowsapps/CSCreateProcessAsUserFromSe-b682134e#content

I tried it, and it works. I'm able to create a new process for my existing .NET application from a service, and it works just fine. I set the service Log On properties to Local System account, but left the "Allow service to interact with desktop" unchecked. My application is created when the timer expires, and works just like it does when started normally, including GUI presentation and user interaction.

Whether this is an improper or undesirable thing to do is another discussion. But it is indeed possible, and really not all that difficult.


There is a kind of work around, but i would advice to only do this if YOU ARE SURE TO ACCEPT THE SECURITY ISSUE!

This could be the Answer to your Problem: CreateProcessAsUser.

The sample demonstrates how to create/launch a process interactively in the session of the logged-on user from a service application written in C#.Net.

0

精彩评论

暂无评论...
验证码 换一张
取 消