Windows service interaction with WinForms app?

D

deko

When to use a privileged user thread rather than a windows service?

That's the question raised in a previous post [Make a Windows Service start
a windows program]. It was suggested that if the service needs to interact
with a WinForms app (which is the UI used to adjust the actions taken by,
and the schedule of the service), then a privileged user thread should be
used in the UI - no service required.

But...

"A windows service enables the creation of long-running executable
applications that run in their own Windows session that has the ability to
automatically start when the computer boots and can be manually paused,
stopped or even restarted. Services can run in the security context of an
account that is different from the logged-on user."

This is EXACTLY the behavior required by my application. A single app with
a privileged user thread may avoid the problem of interaction between the
service and the UI, but that's no reason to abandon the design option of a
Service-WinForms app paired together, if that accomplishes the required
functionality.

The problem is the parameters that drive the service are complex. These
parameters are expressed with relational data. The various controls in the
UI are bound to a typed DataSet (persisted to xml) and business logic is
contained in the object that represents the "project" that the service runs.
This is why a separate app is needed to create and configure the projects
that the service runs at various intervals.

The interaction required between the UI and the service is very limited: the
service needs only to instantiate the Project object (with all the methods
and business logic) in the UI app at project runtime. The only other
communication between the UI and the service occurs when the user requests
the "time remaining until next project runtime" from the UI. This
"WaitTime" value is calculated using the value of Timer object maintained by
the service (for each project defined in the UI). The project runtime
intervals are based on system up time, so all the service does is maintain
counters for each project (started and stopped at boot), and launch the
projects when their respective counters reach zero.

The question is:

1) Can the service instantiate an object from the UI app (which is in the
same assembly), and

2) What is the best way to enable the limited communication necessary
between the service and the app?

As far as I know, the service CAN instantiate an object from the UI app, and
it would run in the service's process thread, which is good. But the
interaction between the UI and the service would require interprocess
communication, which is bad. Is this a job for Remoting? Or is there a
better way to pass a simple TimeSpan object from the service to the UI?
 
W

Willy Denoyette [MVP]

| When to use a privileged user thread rather than a windows service?
|
| That's the question raised in a previous post [Make a Windows Service
start
| a windows program]. It was suggested that if the service needs to
interact
| with a WinForms app (which is the UI used to adjust the actions taken by,
| and the schedule of the service), then a privileged user thread should be
| used in the UI - no service required.
|
| But...
|
| "A windows service enables the creation of long-running executable
| applications that run in their own Windows session that has the ability to
| automatically start when the computer boots and can be manually paused,
| stopped or even restarted. Services can run in the security context of an
| account that is different from the logged-on user."
|
| This is EXACTLY the behavior required by my application. A single app
with
| a privileged user thread may avoid the problem of interaction between the
| service and the UI, but that's no reason to abandon the design option of a
| Service-WinForms app paired together, if that accomplishes the required
| functionality.
|
| The problem is the parameters that drive the service are complex. These
| parameters are expressed with relational data. The various controls in
the
| UI are bound to a typed DataSet (persisted to xml) and business logic is
| contained in the object that represents the "project" that the service
runs.
| This is why a separate app is needed to create and configure the projects
| that the service runs at various intervals.
|
| The interaction required between the UI and the service is very limited:
the
| service needs only to instantiate the Project object (with all the methods
| and business logic) in the UI app at project runtime. The only other
| communication between the UI and the service occurs when the user requests
| the "time remaining until next project runtime" from the UI. This
| "WaitTime" value is calculated using the value of Timer object maintained
by
| the service (for each project defined in the UI). The project runtime
| intervals are based on system up time, so all the service does is maintain
| counters for each project (started and stopped at boot), and launch the
| projects when their respective counters reach zero.
|
| The question is:
|
| 1) Can the service instantiate an object from the UI app (which is in the
| same assembly), and
|
| 2) What is the best way to enable the limited communication necessary
| between the service and the app?
|
| As far as I know, the service CAN instantiate an object from the UI app,
and
| it would run in the service's process thread, which is good. But the
| interaction between the UI and the service would require interprocess
| communication, which is bad. Is this a job for Remoting? Or is there a
| better way to pass a simple TimeSpan object from the service to the UI?
|
|

THE question remains un-answered, do you need to have this application
running when no user is logged on?
If the answer is NO, then you don't need a service you only need a single UI
application, if the answer is yes then you need something that runs across
logon/logoff events, but keep in mind that you can't run a UI application
when no user is logged on.
So, assuming the answer is YES, you'll need a way to communicate and because
both applications running in a different process you need some form of IPC.
There are many forms of IPC available to .NET, one of them is remoting
others are through COM interop, you can even use sockects to communicate or
simply transfer serialized object state through the file system.
The easiest and most native to .NET is remoting and COM+ (enterprise
Services).
So you could have the following set-up:

Windows Service <---- remoting -----> UI application
COM+ service <----- DCOM interop -----> UI Applcation.
Both COM+ and Windows sevices are not tied to the logon session and can both
run as a privileged user.

Notice that in both cases the service cannot control (say start) the UI app,
it's the UI that 'drives' the service (the UI is the client). So it's up to
the UI to pass data (create an instance of a Project object) to the service
where it gets processed. The UI can also request the time remaining until
the next process run.
So, you see it's the UI who drives the process and the Service who executes
the process.

But again, if you don't need the process to run when no user is logged on
forget about all this and use a single WinForms program for all this.

Willy.
 
D

deko

But again, if you don't need the process to run when no user is logged on
forget about all this and use a single WinForms program for all this.

I guess that it THE question...

A separate thread is easy enough in .NET, and running that thread with Admin
privileges, apparently, is easy enough as well. So the only other thing is
when the app starts, which can't be that difficult to control.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top