0

I'm making a console app in c# for monitoring use in company pcs, the app works great, but my problem is that I want to make that if worker close it, i want to either disallow to close it (although i've read that it's not possible to avoid that he closes it from task monitor) or restart it again.

My approach was to write a windows service that checks if app is running, but when started from service, app doesnt record users activity correctly (even allowing service to interact with desktop, by checking it on service control tab).

I've think also in making a scheduled task, that monitor if app is running and restarts it if needed.

My question is, what is the best approach to make that an app keeps going on while user (regular user, not admin rights) is logged in and can not be closed by him?

PD: If he closes the app, he could be not working and it will be no constance of it ;)

Largo
  • 53
  • 1
  • 5
  • 1
    Begs the question, why don't you just do the monitoring from within the service itself? – KingCronus Apr 16 '13 at 11:33
  • Because things I'm recording are like which window is in the foreground and so. If I use a service, it is running like other user. Im not sure if possible. – Largo Apr 16 '13 at 11:35
  • Ah Ok, the question didn't make it clear that you want to spy the open windows etc. I thought you mean't monitor things like CPU/memory etc. – KingCronus Apr 16 '13 at 11:38
  • Yes, it's an app to know if user is working or is losing time on other things. – Largo Apr 16 '13 at 11:39
  • What is the nature of the application? Winforms? Can't you just hide the window? – ken2k Apr 16 '13 at 11:40
  • It's a console app. If users close it from task monitor, i want to be reopen. – Largo Apr 16 '13 at 11:41
  • @Largo Please see http://stackoverflow.com/questions/2763669/how-to-hide-a-console-application-in-c-sharp – ken2k Apr 16 '13 at 11:44
  • @ken2k users will be notified that app will be used, and even hiding app, it will be listed on task monitor when they could close it. – Largo Apr 16 '13 at 11:47
  • Check this question, maybe help you. http://stackoverflow.com/questions/4646827/on-exit-for-a-console-application – Daniel Valcarce Apr 16 '13 at 12:05

3 Answers3

0

Anyway once user closes the program your windows forms applciation will receive the WM_CLOSE message. In the handler of this message you can write a .bat file to the hard drive which merely runs your applciation again. Then you just need to schedulle you .bat file in a few moments. So once your appliction is closed it is started again by windows. You can also use additional windows service as you mentioned before. This is more reliable way. You just need to run your program as the special desktop user. There a couple of ways to achive this goal, for example:

System.Diagnostics.Process.Start(filenameToStart, username, password, domain);
Oleg Ignatov
  • 877
  • 2
  • 8
  • 22
0

Just make sure you have control over the Process instance. If you have a service like you mentioned, you could start the real monitor app from it.

Then you can do something like this:

public void StartProcess()
{
      var process = new Process();
      process.EnableRaisingEvents = true;
      process.Exited += new EventHandler(process_Exited);
      process.Start();
}

And your process_Exited event can just loop back to StartProcess();

Terje
  • 1,753
  • 10
  • 13
0

My approach was to write a windows service that checks if app is running

This is the easiest (and probably the cleanest ) method to monitor a daemon application running in the user's context. Terje's answer solves this issue.

but when started from service, app doesnt record users activity correctly (even allowing service to interact with desktop, by checking it on service control tab).

This is because your application is running on the service desktop. Checking the box on the service control tab only displays windows created by the service itself on the user's desktop.

You need to launch the application on the default desktop of the logged on user. See Starting an Interactive Client Process in C++

To retrieve the user's token is very simple for a windows service:

In the Service handle the OnSessionChange event to retrieve the session ID's of users as they log-on/off. Once you have the session ID you can retrieve the User Token and launch the monitor application on the user's desktop.

Now all you have to do is call CreateProcessAsUser using the following for STARTUPINFO.

var si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = "Winsta0\\default";//this is the user's desktop.

For the full sample source see this blog post by Henry Chong