Best Method for Tracking Processes - c#

At my consulting company, we use some very expensive simulation software. I need a means to monitor the usage of these applications/processes (in the background, using C#). The idea is that when someone runs a particular application, they are prompted to enter the job name. Then, when they close the program, the amount of time they used it is sent to a database residing on the network. This way we can recoup the costs of the software by charging our clients on a $/min basis. Aside from the prompt, the program must be nearly invisible to users.
I have thought of a few ways of doing this, but I'm not sure what's best:
Have a program that runs on startup, with only a tray icon. I suppose then I would have to have a backgroundworker monitoring the processes continuously, perhaps sleeping the thread, and checking the processes every 5 minutes or so.
Use something like Quartz.net, on startup and with a tray icon. If this is even applicable on a minute-by-minute basis. I am not very familiar with Quartz.net, but from my research it looks maybe do-able.
Use some kind of Windows Service. This one I am least familiar with.
Which method would be most fruitful? Thanks

You could write a simple C# program that upon execution collects the required information and start time.
Then by using the Process class you execute the simulation software.
Wait for the process to end using WaitForExit() and do whatever is needed with the execution time etc.
So essentially you end up with an application that simply collects the required information, launches the main application, waits for the application to end and does whatever is needed with the total execution time. As far as being invisible to the user, you could just minimize the main window ( which also acts as the form for collecting the needed info ) while waiting for the application to end.
Here is a small example of starting an executable within C#.
private void LaunchApp()
{
Process proc = new Process();
/* we are going to assume wordpad is installed on workstation */
/* collect needed info and time */
proc.StartInfo.FileName = "Wordpad.exe";
proc.StartInfo.Arguments = "SomeFile.txt";
proc.Start();
proc.WaitForExit();
/* App has ended. Now process execution time etc. */
}

Related

Until a process has started, do something

So I have a background program that starts with Windows, minimized to system tray icon. Once it loads I need it to constantly start checking if a process has started (for example VLC). Once the process has started, It must wait for it to close in order to start doing stuff and then get back to check if it has started. I've been trying to do this for a while now, but I just can't figure out how.
How would I constantly check if a program has started?
One way would be to have the Background Deamon look for aprogramm of a specific name. Unfortunately this not overly reliable (due to name overlaps), would require a lot of polling and runs the risk of race conditions (the process starting when your deamon is still working).
What would be reliable, is if it is the Deamon that actually starts the foreground process. That way it could do work before Process.Start() and after Process.WaitForExit(), with full information when both states happen: https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process?view=netcore-3.1
Steam is a good example. It is a single-instance process, so any further requests can be relayed to the running instance. The desktop links to programms/games are actually weblinks - not programm links. Those links use the :steam protocoll, wich is associated with the steam processes. So it goes like this:
user klicks on a WebLink with :steam procotoll
Windows resolves to hand this into a commandline call to the steam programm
A instance is started with the proper order in via commandline. Single instancing will not allow a 2nd instanc to start, but hand the request over a already running one
the already or now suddenly running instance calls the programm, having full data on when it starts and ends - being the actuall logical caller

How can restart a process only by its pid?

I want to create a watchdog in c# in which the user selects a process by his pid a then the application watch he consumes of ram and CPU, after, if that application pass over the min consume then restart the process so his CPU and ram go again to 0.
my problem is when I want to restart the process, because I can get the process by his pid, but can't restart again because his want the path of application but I don't want restart entire application I only want restart that specific process
How I can achieve this?
Is possible to do this?
UPGRADE:
well, I think this understand better with an example, so here is:
First, imagine I want to watch the process with pid 12780 of the application Microsoft Edge.
Second, when this process exceeds the min consume of RAM or CPU what I set in my watchdog, that process should restart, begin with RAM and CPU in 0.
But here is the problem if I want to restart that process I can kill it, yes, but I can't start it after, Even if I set the full path of my application (in this case Microsoft Edge) it can't start again.
So, how I can restart only that process don't the full application?
Once you use How to get the full path of running process? to get the executable that was used to start the process you might be able to restart it.
However, if the executable was started in a specific way (think of a working folder, start parameters, environment variables, ...) it might not run the same way it was previously started. These special setting can be retrieved by using this answer: https://stackoverflow.com/a/5497319/563088 (commandline result)
The environment variables can be retrieved by using How to get the Process Environment Block (PEB) from extern process?
No, there is no way to do what you want.
If you wanted to restart a full application, that would be possible, but as you would potentially lose some data.
However, you say that you want to restart only a part of your application, say one of the processes, and that is not possible, unless it is specifically supported by the application itself - which is not generally the case.
Let the explain why.
When an application decides to create a new process, that process gets a copy (simplifying, but still) of the memory of the parent process at that moment, and after that both processes start diverging from that state, so it doesn't exist anymore.
Is it possible to create applications that allow you to restart it's processes? Yes. But most applications don't allow you to do that, and it's not even always clear what would mean to restart a process.

Process.Start() only after current application killed

Is it possible for a running c# application to start/invoke some new arbitrary process, but only do so after the current running application is terminated?
I guess it's possible to call the new process from Process.Start() via cmd.exe and do something like sleep 3 & c:\mynewapplication.exe - this would giver the 'caller' some three seconds to terminate itself.
However this is a bit hacky, and was wondering if there was a neater way?
Depending on the type of application, you could simply listen to the end of the program. One option you have is the Application.ApplicationExit event.
Another possibility is to start another process, that waits until the first process dies. You could poll Process.GetProcesses for example. This will raise the event, even if the first process crashes. You could also register the Process.Exited event.
It has little to do with C#. It is a question about the Windows OS, and, in particular, in WinAPI.
Generally, the only 'thing' that runs code is threads. When your process in terminated, all its threads die.
Your best approach is probably by starting a process that will wait before starting your new process, as you suggested, however you may, for example, hook on some of the functions called when something happens and start your new process there.

How to measure the time an application takes to start up in C#?

I have an GUI application that takes a while to load all its plugins, before it is ready to be used by the user.
I want to write a C# program that would measure the time taken for this application to start up. I thought the Process.WaitForInputIdle() method would do the trick, but it doesn't. It exits as soon as the process is started.
What I have now is this:
DateTime startTime = DateTime.Now;
Process myAppUnderTest = Process.Start("C:\\Program Files\\My App\app_under_test.ext");
myAppUnderTest.WaitForInputIdle(); //Wait until the application is idle.
DateTime endTime = DateTime.Now;
int elapsedTimeInSecs = endTime.Subtract(startTime).Seconds;
Console.WriteLine("Start up time (sec): {0}", elapsedTimeInSecs);
How can I get the start up time that I intend?
I say it's very difficult.
How do you classify an application loaded and ready? If there is a way (which I don't think so) then it would be easy.
But if the app you are loading signals you in certain way (IPC/files/network), then you can capture that signal and say the app is loaded. In that case, you can use a timer/stopwatch/performance counter.
If you can modify the to be timed app, then you can achieve in various ways. If its external to you, I doubt there is any easy way.
Process.WaitForInputIdle() respones to the main window. Once that process starts up it will move on. Is there a message on the main the main window you can look at that indicates the app is in a ready state? If so you can try putting or app in a loop unitl that is present or so much time has passed. As has been noted you will probably also want to look at the Stopwatch class for your timing.
Just a couple of other thoughts as you are doing this. Make sure that this process is the only one running. You can sometimes get some conflicts otherwise. You may need to play arround with figuring out what the trigger is to tell you when the app is fully loaded.

Handling a forced exit

Is there any good way to handle a forced exit in C#?
I have a formless C# application that talks to an LCD over serial. Once the application is running, the only way to kill it is with task manager. The trouble with this is that the program needs to turn the LCD off when it is done, and it doesn't look as if my Application.ApplicationExit event is ever fired in this condition.
Any ideas?
Once the application is running, the only way to kill it is with task manager.
My big idea would be to change this.
Stick an icon in the notification area that the user can use to shut your app down properly, or set it up so that running the app again will instead shut down an already-running instance if one exists, or any other way that sounds like a good idea.
Requiring a user to use Task Manager to shut down your application screams poor design.
Write a code in your program loop (with a timer perhaps) to read a file or a registry key. For example if a file at C:\YOURPROGRAM\CLOSEME contains text "closeme", close your program gracefully. Write another program that write that C:\YOURPROGRAM\CLOSEME file. So, whenever you want to shutdown your program, don't use taskmanager, instead, open second program.
Some options:
Write a separate process with a GUI that can start and stop the main process. For example, when you install the Apache web server on Windows the server itself is installed as a service. It can be started and stopped from the system services management panel, but it also comes with a "monitor" process that sits in the notification area, tells you whether Apache is running and lets you start or stop it manually.
If it's acceptable for your use-case, make the application a console application. You can register a handler for when the user presses CTRL+C (see Console.CancelKeyPress) that performs your cleanup before your process exits. This still won't let you handle someone killing the process from Task Manager, but it's very easy to do and might be good enough depending on your situation.

Categories

Resources