Home All Groups Group Topic Archive Search About

Launching and Monitoring Executables

Author
31 Jul 2006 8:54 AM
Water Cooler v2
I have a Windows Service I am writing in C# and a set of, let us say
three, other executables written in C# (mostly console applications).

I want that the Windows Service must do so every few seconds:

Check to see if each of the other executables are running or not. If
they are not running, it should load them.

For this purpose, I am planning the following:

I'll take a timer object and set it to an appropriate interval. In the
timer's timer/elapsed event, I will check if the other executables are
running or not. For checking that, I can use either of the following
approaches:

1. Use OpenProcess/CreateProcess with LP_SECURITY_ATTRIBUTES set to
NULL and with PROCESS_INFO. This will give me everything I need to
know, like, the threadID, the processID, in order to determine if the
process is running or not. The processID will be constant throughout
the life of each process. This will help me check if a process is
running or not.

2. ShellExecute/ShellExecuteEx - I am not sure if this is the right
approach. If I am assuming correctly, ShellExecuteEx only sets
GetLastError and returns a bool/int indicating success or failure. This
may not be the approach I might want to take as this will not give me
any information as to the status of the executable I have launched.
Besides, even semantically, this method might not be suited for the
purpose I have at hand, which is not to "launch documents in their
associated application."

3. Create a new app domain for each process I want to launch, add all
the appDomains to the same process, call ExecuteAssembly the
Application Domain for each executable I want to launch.

However, with the third approach, my knowledge of application domains
is still limited. I have a couple of questions in this regard.

a. Given that all this checking will be performed by a Windows Service,
which is not really a Win32 process, like ordinary Windows PE files or
executables, whether managed or unmanaged, what are the implications of
creating appdomains from within a Windows service? Is it an alright
thing to do to launch other Win32 processes from within a Windows
service?

b. Would it be possible for me to monitor the lifetime of an executable
which I execute inside an application domain? Remember that my main
purpose is to monitor in a timer if an application is running or not,
and if not, to launch it again.

c. What is the difference between System.AppDomain.Load() and
System.AppDomain.ExecuteAssembly()? Sorry, I am being lazy here, but it
is easier to ask a forum. I'm on my way to the MSDN, anyway. But kindly
oblige.


Thanks very much for your thoughts.

Author
31 Jul 2006 12:22 PM
Vadym Stetsyak
Hello, Water!

WCv> I want that the Windows Service must do so every few seconds:

WCv> Check to see if each of the other executables are running or not. If
WCv> they are not running, it should load them.

WCv> For this purpose, I am planning the following:

WCv> I'll take a timer object and set it to an appropriate interval. In the
WCv> timer's timer/elapsed event, I will check if the other executables are
WCv> running or not. For checking that, I can use either of the following
WCv> approaches:

WCv> 1. Use OpenProcess/CreateProcess with LP_SECURITY_ATTRIBUTES set to
WCv> NULL and with PROCESS_INFO. This will give me everything I need to
WCv> know, like, the threadID, the processID, in order to determine if the
WCv> process is running or not. The processID will be constant throughout
WCv> the life of each process. This will help me check if a process is
WCv> running or not.

IMO it is bad approach, since specifying LP_SECURITY_ATTRIBUTES as NULL,
you will give an application privileges of the service. If service is working under
SYSTEM account, then application launched by it will also run under SYSTEM account.

[skipped]

WCv> 3. Create a new app domain for each process I want to launch, add all
WCv> the appDomains to the same process, call ExecuteAssembly the
WCv> Application Domain for each executable I want to launch.

AFAIK if you create AppDomains they're already in the same win32 process. 3-rd
approach will not help you. Note from the docs" 
[ExecuteAssembly] This method does not create a new process or application domain,
and it does not execute the entry point method on a new thread.".

WCv> However, with the third approach, my knowledge of application domains
WCv> is still limited. I have a couple of questions in this regard.

WCv> a. Given that all this checking will be performed by a Windows
WCv> Service, which is not really a Win32 process, like ordinary Windows PE
WCv> files or executables, whether managed or unmanaged, what are the
WCv> implications of creating appdomains from within a Windows service?

Implications:
- if starting processes from within service and not specifying new security account -
   the process will start under same account service is operating.
- service may be running when there is no desktop ( before windows login )

WCv> Is it an alright thing to do to launch other Win32 processes from
WCv> within a Windows service?

IMO it is not general practice to do so.

WCv> b. Would it be possible for me to monitor the lifetime of an
WCv> executable which I execute inside an application domain? Remember that
WCv> my main purpose is to monitor in a timer if an application is running
WCv> or not, and if not, to launch it again.

Will it be easier to accomplish your task if use Process class ( Process.GetProcesses ) and
detect if specified process is in the list or use WMI in the same way?
I think it will

WCv> c. What is the difference between System.AppDomain.Load() and
WCv> System.AppDomain.ExecuteAssembly()? Sorry, I am being lazy here, but
WCv> it is easier to ask a forum. I'm on my way to the MSDN, anyway. But
WCv> kindly oblige.

ExecuteAssembly begins executing at the entry point specified in the .NET Framework header.
And Load method loads an assembly into current app domain, no assembly code is executed
--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com
Author
31 Jul 2006 5:35 PM
Rob R. Ainscough
What I've discovered down this long ugly road of Windows Services under .NET
using Diagnostic.Process approach.

1.  Interact with Desktop is required for any shelled process with an
interface (even the most simple interfaces)
2.  You can only go one level deep on the shell under a service and retain
"Interact with Desktop" -- not inherited if you run a service that shells to
another program which in tern shells to another program -- you'll be left in
limbo non UI state.
3.  Many Windows programs/tools don't work reliably when shelled from a
service (i.e. MSIEXEC for example)
4.  Diagnostic.Process is the better way to go over WMI and/or Shell, you
can track, wait, timeout etc.
5.  just avoid using a service that has an interface or anything that shells
that might have an interface -- just too many problems with the bubble gum
nature of the OS that could send you into a spiral of R&D as to why
something isn't working as expected
6.  Not sure Diagnostic.Process can report back on processes that are
hidden.

Since you might be launching documents and/or their associate apps, you
really are better off NOT using a service to do this since the OS is
severely "lacking" in this area.  What you might want to consider is
standard windows app with a timer that installs in the Startup -- you'll
have to workout the details on Starting/Stoping and if the user trys to
termiante the app (this is why we like to code for a service, but
Microsoft's security problems and poor assumptions have left us with few
options).

IMHO, All services should be permitted to have an interface that works
reliably under all contexts because even if a user has not logged in, there
is STILL an interface.  I'm guessing Microsoft wanted to go this restricted
route simply because it is a easy solution for them to make a mass blanket
restriction even if not conceptually valid.  Frustrating isn't it -- more
half-ass implementations from M$

Rob.


Show quote
"Water Cooler v2" <wtr_***@yahoo.com> wrote in message
news:1154336059.205951.64200@m73g2000cwd.googlegroups.com...
>I have a Windows Service I am writing in C# and a set of, let us say
> three, other executables written in C# (mostly console applications).
>
> I want that the Windows Service must do so every few seconds:
>
> Check to see if each of the other executables are running or not. If
> they are not running, it should load them.
>
> For this purpose, I am planning the following:
>
> I'll take a timer object and set it to an appropriate interval. In the
> timer's timer/elapsed event, I will check if the other executables are
> running or not. For checking that, I can use either of the following
> approaches:
>
> 1. Use OpenProcess/CreateProcess with LP_SECURITY_ATTRIBUTES set to
> NULL and with PROCESS_INFO. This will give me everything I need to
> know, like, the threadID, the processID, in order to determine if the
> process is running or not. The processID will be constant throughout
> the life of each process. This will help me check if a process is
> running or not.
>
> 2. ShellExecute/ShellExecuteEx - I am not sure if this is the right
> approach. If I am assuming correctly, ShellExecuteEx only sets
> GetLastError and returns a bool/int indicating success or failure. This
> may not be the approach I might want to take as this will not give me
> any information as to the status of the executable I have launched.
> Besides, even semantically, this method might not be suited for the
> purpose I have at hand, which is not to "launch documents in their
> associated application."
>
> 3. Create a new app domain for each process I want to launch, add all
> the appDomains to the same process, call ExecuteAssembly the
> Application Domain for each executable I want to launch.
>
> However, with the third approach, my knowledge of application domains
> is still limited. I have a couple of questions in this regard.
>
> a. Given that all this checking will be performed by a Windows Service,
> which is not really a Win32 process, like ordinary Windows PE files or
> executables, whether managed or unmanaged, what are the implications of
> creating appdomains from within a Windows service? Is it an alright
> thing to do to launch other Win32 processes from within a Windows
> service?
>
> b. Would it be possible for me to monitor the lifetime of an executable
> which I execute inside an application domain? Remember that my main
> purpose is to monitor in a timer if an application is running or not,
> and if not, to launch it again.
>
> c. What is the difference between System.AppDomain.Load() and
> System.AppDomain.ExecuteAssembly()? Sorry, I am being lazy here, but it
> is easier to ask a forum. I'm on my way to the MSDN, anyway. But kindly
> oblige.
>
>
> Thanks very much for your thoughts.
>

AddThis Social Bookmark Button