1. 程式人生 > >C#製作簡單的看門狗程式

C#製作簡單的看門狗程式

這個類實現了程式退出能重啟,但是程式停止執行彈出對話方塊,程序並沒有退出卻無法重啟。希望有好建議處理這個bug的朋友提出你們的寶貴意見。
原始碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;

    public  class ProcessWatcher
    {
        ///
<summary>
/// 程序列表 /// </summary> public List<MyProcess> myProcessList; private Thread watchThread; private int watchWaitingTime = 20; /// <summary> /// 初始化 /// -1 process.mj 檔案不存在 /// 0 看護程序不存在 /// 1 成功 /// 2 部分程序路徑不正確
/// </summary> /// <returns></returns> public int init() { if (!System.IO.File.Exists("process.mj")) return -1; string[] processPath = System.IO.File.ReadAllLines("process.mj",Encoding.Default); int count = 0; myProcessList = new
List<MyProcess>(); foreach (string path in processPath) { if (System.IO.File.Exists(path)) { count++; MyProcess mp = new MyProcess(path); myProcessList.Add(mp); } } if (count == 0) return 0; if (count == processPath.Length) return 1; return 2; } /// <summary> /// 啟動守護 /// /// </summary> /// <param name="sleepTime">等待時間</param> /// <returns></returns> public int watchStart(int sleepTime) { watchWaitingTime = sleepTime; watchStop(); watchThread = new Thread(watch); watchThread.Start(); return 0; } /// <summary> /// 關閉守護 /// </summary> /// <returns></returns> public int watchStop() { try { watchThread.Abort(); } catch { } return 0; } /// <summary> /// 守護執行緒,死迴圈 /// </summary> private void watch() { while (true) { if (myProcessList == null) return; if (myProcessList.Count < 1) return; foreach (MyProcess mp in myProcessList) { if (!mp.isAlive()) { //Thread.Sleep(1000); //if (!mp.isAlive()) mp.start(); mp.start(); } } Thread.Sleep(watchWaitingTime*1000); } } /// <summary> /// 全部重啟,如果已經啟動則先關閉 /// </summary> public void startAll() { if (myProcessList == null) return; if (myProcessList.Count < 1) return; foreach (MyProcess mp in myProcessList) { if (!mp.isAlive()) mp.start(); } } /// <summary> /// 關閉所有守護程序 /// </summary> public void stopAll() { if (myProcessList == null) return; if (myProcessList.Count < 1) return; foreach (MyProcess mp in myProcessList) { mp.stop(); } } /// <summary> /// 程序狀態 /// 1 顯示介面 /// 2 影藏介面 /// 3 重啟 /// 4 停止 /// </summary> /// <param name="state"></param> /// <param name="name"></param> public void setProcessState(int state,string name) { foreach (ProcessWatcher.MyProcess p in myProcessList) { if (p.Name == name) { switch (state) { case 1: p.show(); break; case 2: p.hide(); break; case 3: p.start(); break; case 4: p.stop(); break; } break; } } } /// <summary> /// 判斷某個執行緒是否存在 /// </summary> /// <param name="name">執行緒名字</param> /// <returns></returns> public Boolean processIsAlive(string name) { if (myProcessList == null) return false; if (myProcessList.Count < 1) return false; foreach (MyProcess mp in myProcessList) { if (mp.Name == name) { return mp.isAlive(); } } return false; } /// <summary> /// 顯示窗體 /// </summary> /// <param name="hWnd">窗體控制代碼</param> /// <param name="nCmdShow">0 隱藏,1顯示</param> /// <returns></returns> [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)] static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow); public class MyProcess { private string name; private string path; private IntPtr ptrHide; //private Process process; public MyProcess(string path) { string[] s = path.Split('\\'); this.name = s[s.Length-1]; this.name = name.Substring(0,name.Length-4); this.path = path; ptrHide = IntPtr.Zero; } /// <summary> /// 程序名字 /// </summary> public string Name { get { return name; } } /// <summary> /// 程序路徑 /// </summary> public string Path { get { return path; } } /// <summary> /// 程序狀態 /// </summary> /// <returns></returns> public Boolean isAlive() { Process p = process(); if (p == null) return false; if (p.Responding == true) return true; return !p.HasExited; //try //{ // return process().Responding; //} //catch //{ // return false; //} } /// <summary> /// 啟動,如果已經啟動,則關閉後再啟動 /// </summary> public void start() { stop(); Thread.Sleep(500); Process.Start(path); writeLog("啟動程式"+name); } /// <summary> /// 關閉 /// </summary> public void stop() { try { process().Kill(); writeLog("關閉程式" + name); } catch { } } /// <summary> /// 顯示 /// </summary> public void show() { if (process() != null) { if (ptrHide == IntPtr.Zero) { ShowWindow(process().MainWindowHandle, 1); } else { ShowWindow(ptrHide, 1); ptrHide = IntPtr.Zero; } } } /// <summary> /// 隱藏 /// </summary> public void hide() { if (process() != null) { if (ptrHide != IntPtr.Zero) return; //防止多次隱藏。 ptrHide = process().MainWindowHandle;//隱藏前儲存窗體控制代碼,隱藏後從新獲取的控制代碼與此不同。 ShowWindow(ptrHide, 0); } } /// <summary> /// 獲取程序 /// </summary> /// <returns></returns> private Process process() { Process[] proc = Process.GetProcessesByName(name); if (proc.Length > 0) { return proc[0]; } return null; } /// <summary> /// /// </summary> readonly static ReaderWriterLockSlim _rw = new ReaderWriterLockSlim(); /// <summary> /// 寫日誌檔案 /// </summary> /// <param name="str_msg"></param> public static void writeLog(string str_msg) { if (System.IO.Directory.Exists("logW") == false) System.IO.Directory.CreateDirectory("logW"); string msg = DateTime.Now.ToLongDateString() + DateTime.Now.ToLongTimeString() + ":" + str_msg + "\r\n"; _rw.EnterWriteLock(); System.IO.File.AppendAllText("logW\\" + DateTime.Now.ToString("yyyyMMdd") + ".txt", msg); _rw.ExitWriteLock(); string[] s = System.IO.Directory.GetFiles("logW"); if (s.Length > 7) { System.IO.File.Delete(s[0]); } } } }