C# Windows服务应用程序控制器

C# Windows服务应用程序控制器,c#,.net,windows-services,C#,.net,Windows Services,前提是: 我有一个桌面,我需要能够启动和停止应用程序,但无法远程访问。我想到的是在机器上设置一个服务,它将启动/停止所告诉的应用程序列表。此windows服务将定期向web服务发送新命令,并相应地执行这些命令 这些是我的问题 1) 这是最简单的解决方案吗?你还推荐什么 2) 从windows服务运行exe有多难?停一辆怎么样 这不是为了一个项目或任何东西,只是我对实现感兴趣的东西(主要是为了好玩)。任何答案或想法都将不胜感激。一般性讨论也是受欢迎的(请随意发表评论)。所以我想这是不可能的 除此之

前提是:

我有一个桌面,我需要能够启动和停止应用程序,但无法远程访问。我想到的是在机器上设置一个服务,它将启动/停止所告诉的应用程序列表。此windows服务将定期向web服务发送新命令,并相应地执行这些命令

这些是我的问题

1) 这是最简单的解决方案吗?你还推荐什么

2) 从windows服务运行exe有多难?停一辆怎么样

这不是为了一个项目或任何东西,只是我对实现感兴趣的东西(主要是为了好玩)。任何答案或想法都将不胜感激。一般性讨论也是受欢迎的(请随意发表评论)。

所以我想这是不可能的

除此之外,在Win服务中实现程序运行并不困难。只需使用.NET Process类即可,我的代码示例如下:

        ProcessStartInfo processStartInfo = new ProcessStartInfo (programExePath, commandLineArgs);

        consoleLogger.WriteLine (log, Level.Debug, "Running program {0} ('{1}')", programExePath, commandLineArgs);

        processStartInfo.CreateNoWindow = true;
        processStartInfo.ErrorDialog = false;
        processStartInfo.RedirectStandardError = true;
        processStartInfo.RedirectStandardOutput = true;
        processStartInfo.UseShellExecute = false;

        using (Process process = new Process ())
        {
            process.StartInfo = processStartInfo;
            process.ErrorDataReceived += new DataReceivedEventHandler (process_ErrorDataReceived);
            process.OutputDataReceived += new DataReceivedEventHandler (process_OutputDataReceived);
            process.Start ();

            process.BeginOutputReadLine ();
            process.BeginErrorReadLine ();

            if (false == process.WaitForExit ((int)TimeSpan.FromHours(1).TotalMilliseconds))
                throw new ArgumentException("The program '{0}' did not finish in time, aborting.", programExePath);

            if (process.ExitCode != 0)
                throw new ArgumentException ("failed.");
        }

我已经完成了一项启动其他exe文件的服务。有一些事情需要考虑:作为一项服务,您没有可视桌面->不可能进行直接交互。此外,程序必须设计为长时间运行


停止exe就是终止进程。考虑通常的副作用。

< P>它不会太难-你可以只让它在一些Web服务上轮询一个“禁止”的应用程序列表,然后在另一个定时器上,检查一个被禁止的应用程序,如果它是运行的,那么就杀死它。下面是一些用于获取进程列表的代码,您可以使用process类上的方法来启动或终止某些内容:


计时器也可以独立运行—它可以每天检查一次Web服务,以获得新的添加/禁止列表,但随后每隔2分钟检查一次计算机上运行的进程。

关于在C#中创建Windows服务本身,请参阅我的帖子


轮询机制可以工作,但一般来说,我更喜欢事件驱动的进程而不是轮询进程。您没有提到您使用的.NET版本,但如果是.NET 3.0/3.5,我建议您使用WCF。当该命令发布到web服务时,web服务可以将该命令发送到要执行的Windows服务。很简单。《编程WCF服务》一书的作者Juval Lowy提供了一系列WCF示例/库,可以在他的网站上免费使用。

我先回答问题2:

要启动或停止程序,只需使用System.Diagnostics.Process对象,示例代码就在MSDN库中

关于问题1: 如果您想这样做,可以让它定期轮询web服务

作为替代方案,您可以将服务设置为远程处理,让它只在tcp端口上侦听函数调用,然后编写一个可以使用远程处理调用服务的Windows应用程序。我不得不为一个合法的商业应用程序这么做,它运行得非常好

然而,如果我没有包括以下警告,我将是非常不负责任的:

无论哪种方式,设置一台计算机以便它可以执行任意代码都是一个坏主意,应该非常小心地进行。仅仅因为它能做,并不意味着它应该做。如果您选择web服务路线,您将如何确保有人不会篡改web服务并执行恶意代码?你怎么知道有人不会弄乱你的app.config并将应用指向他们自己的web服务?在远程处理场景中,如何确保其他.Net开发人员不只是创建自己的代理

老实说,我很惊讶微软竟然允许System.Diagnostocs.Process在.Net应用程序中使用。你可以用它做任何你想做的事情,包括启动cmdshell和执行系统命令。因此,我强烈要求你们认真考虑这是否真的有必要做。安装vnc或使用远程桌面或其他远程访问应用程序可能会更好


您需要回答的另一个问题是“应用程序是否对该远程计算机上的用户可见?”如果是,那么您需要确保服务已设置为在该用户的上下文下运行。否则,例如,您可以使用本地系统帐户启动Word,登录到该计算机的用户将永远看不到它。

然后您可以使用TaskKill停止远程进程。虽然PSExec不需要管理员权限,但TaskKill需要管理员权限,他可能没有。这当然是一个选项,但应用程序的数量将非常有限,我更愿意自己构建大部分应用程序。我遇到了一个非常类似的问题,最终采用了一种类似于此处暗示的方法