C#製作簡單的看門狗程式
阿新 • • 發佈:2018-12-31
這個類實現了程式退出能重啟,但是程式停止執行彈出對話方塊,程序並沒有退出卻無法重啟。希望有好建議處理這個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]);
}
}
}
}