简体   繁体   English

在C#中监控应用

[英]Monitoring app in c#

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. 我正在用c#制作一个控制台应用程序以监视公司个人计算机中的使用情况,该应用程序很好用,但是我的问题是我想让工作人员关闭它,但我要么不想关闭它(尽管我已经读过) (无法避免他从任务监视器关闭它)或再次重新启动它。

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). 我的方法是编写一个Windows服务,以检查应用程序是否正在运行,但是从服务启动时,应用程序无法正确记录用户的活动(即使通过在服务控制选项卡上进行检查,也可以允许服务与桌面进行交互)。

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 ;) PD:如果他关闭了该应用程序,则可能无法正常工作,这将不再是必需的;)

Anyway once user closes the program your windows forms applciation will receive the WM_CLOSE message. 无论如何,一旦用户关闭程序,您的Windows窗体应用程序将收到WM_CLOSE消息。 In the handler of this message you can write a .bat file to the hard drive which merely runs your applciation again. 在此消息的处理程序中,您可以将.bat文件写入硬盘驱动器,该文件仅再次运行您的应用程序。 Then you just need to schedulle you .bat file in a few moments. 然后,您只需要片刻即可安排.bat文件。 So once your appliction is closed it is started again by windows. 因此,一旦关闭您的应用程序,它将再次由Windows启动。 You can also use additional windows service as you mentioned before. 您还可以使用前面提到的其他Windows服务。 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);

Just make sure you have control over the Process instance. 只要确保您对Process实例具有控制权即可。 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(); 您的process_Exited事件可以循环回到StartProcess();

My approach was to write a windows service that checks if app is running 我的方法是编写Windows服务,以检查应用程序是否正在运行

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. Terje的答案解决了这个问题。

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++ 请参阅在C ++中启动交互式客户端进程

To retrieve the user's token is very simple for a windows service: 对于Windows服务,检索用户令牌非常简单:

In the Service handle the OnSessionChange event to retrieve the session ID's of users as they log-on/off. 在服务中,处理OnSessionChange事件以在用户登录/注销时检索其会话ID。 Once you have the session ID you can retrieve the User Token and launch the monitor application on the user's desktop. 获得会话ID后,您可以检索用户令牌并在用户的桌面上启动监视器应用程序。

Now all you have to do is call CreateProcessAsUser using the following for STARTUPINFO. 现在,您要做的就是使用下面的STARTUPINFO调用CreateProcessAsUser

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 有关完整的示例源,请参阅Henry Chong的博客文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM