Windows服务和桌面程序互相控制

网上有这方面的文章,不过大多介绍不够全面、详尽,而且大部分言必称API。本文试图描述更多使用framework类库,更加详尽的操作方法。

2007年11月5日
http://www.cnblogs.com/birdshover/


一、需求
假定有这样一个需求:
1、需要一个服务来启动应用程序
2、当应用程序启动后会完成一些任务
3、如果应用程序执行任务过程中发生错误,由服务来重启该应用程序
4、服务关闭,应用程序同时关闭
5、应用程序启动后发现服务未注册或者未启动则完成这些动作
6、应用程序可停止服务

二、思路
服务OnStart应该定时检查程序是否处于启动状态,如果启动,读取消息,完成动作。如果未启动,则启动。
服务OnStop需要关闭程序
程序启动后检查服务状态
程序有按钮可以关闭服务

三、方法

1、启动应用程序
要启动应用程序,首先要找到系统中是否有应用程序存在,假定应用程序名称MyTestApp.exe,服务名称MyTestService
找到MyTestApp很简单,就一句话

Process[] p = Process.GetProcessesByName("MyTestApp"".");

注意要引用System.Diagnostics,为什么GetProcessesByName的参数是"MyTestApp"和".","."是大多.Net程序的类名称,MyTestApp是程序名称,是程序编译选项里的程序集名称。

这里要且只要启动一个,所以
                if (p.Length == 0)
                {
                    Process ip 
= Process.Start(System.IO.Path.Combine(localPath, "MyTestApp.exe"));
                    ip.StartInfo.CreateNoWindow 
= false;
                    ip.StartInfo.UseShellExecute 
= false;
                    ip.StartInfo.RedirectStandardInput 
= true;
                    ip.StartInfo.RedirectStandardOutput 
= true;
                    ip.StartInfo.RedirectStandardError 
= true;
                    ip.StartInfo.WindowStyle 
= ProcessWindowStyle.Normal;
                }

localPath是程序运行目录
 
string localPath = System.Windows.Forms.Application.StartupPath;

需要注意,Service项目中不包含System.Windows.Forms.dll的引用,需要自己添加。

好了,这样就能完成使命了,但是还需要实时监视。所以,用Timer.
一共有两个Timer,一个在System.Threading空间下,一个在System.Windows.Forms空间下。使用System.Windows.Forms空间下的Timer,两个不一样。
            System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
            t.Interval 
= 1000;
            t.Tick 
+= new EventHandler(t_Tick);
            t.Start();

        
void t_Tick(object sender, EventArgs e)
        {
            Process[] p 
= Process.GetProcessesByName("MyTestApp"".");
            
if (p.Length == 0)
            {
                Process ip 
= Process.Start(System.IO.Path.Combine(localPath, "MyTestApp.exe"));
                ip.StartInfo.CreateNoWindow 
= false;
                ip.StartInfo.UseShellExecute 
= false;
                ip.StartInfo.RedirectStandardInput 
= true;
                ip.StartInfo.RedirectStandardOutput 
= true;
                ip.StartInfo.RedirectStandardError 
= true;
                ip.StartInfo.WindowStyle 
= ProcessWindowStyle.Normal;
            }
        }

加进去了,发现没有用....还没搞清楚什么原因。试试线程,发现可以。
Thread td;

            td = new Thread(doAction);
            td.Start();

 
        void doAction()
        {
            
while (true)
            {
                Process[] p 
= Process.GetProcessesByName("MyTestApp"".");
                
if (p.Length == 0)
                {
                    Process ip 
= Process.Start(System.IO.Path.Combine(localPath, "MyTestApp.exe"));
                    ip.StartInfo.CreateNoWindow 
= false;
                    ip.StartInfo.UseShellExecute 
= false;
                    ip.StartInfo.RedirectStandardInput 
= true;
                    ip.StartInfo.RedirectStandardOutput 
= true;
                    ip.StartInfo.RedirectStandardError 
= true;
                    ip.StartInfo.WindowStyle 
= ProcessWindowStyle.Normal;
                }

                Thread.Sleep(
1 * 1000);
            }
        }

到现在就满足服务启动程序的要求了。


中午了,要吃饭了,下午上班没什么时间写,下次续....
posted @ 2007-11-05 11:50  Birdshover  阅读(2607)  评论(1编辑  收藏  举报