欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C#看門(mén)狗程序源碼,確保指定程序崩潰后也能保持自動(dòng)開(kāi)啟

admin
2023年10月16日 15:41 本文熱度 608

前言

在有些特殊項(xiàng)目中,軟件可能是無(wú)人值守的,如果程序莫名其妙掛了或者進(jìn)程被干掉了等等,這時(shí)開(kāi)發(fā)一個(gè)看門(mén)狗程序是非常有必要的,它就像一只打不死的小強(qiáng),只要程序非正常退出,它就能立即再次將被看護(hù)的程序啟動(dòng)起來(lái)。

代碼實(shí)現(xiàn)

Tips:完整源代碼附件:WatchDogDemo-main.zip,就不一步一步寫(xiě)了

1、創(chuàng)建一個(gè)Dog類,主要用于間隔性掃描被看護(hù)程序是否還在運(yùn)行

開(kāi)了個(gè)定時(shí)器,每5秒去檢查1次,如果沒(méi)有找到進(jìn)程則使用Process啟動(dòng)程序

public class Dog
{
    private Timer timer = new Timer();
    private string processName ;
    private string filePath;//要監(jiān)控的程序的路徑
    public Dog()
    {
        timer.Interval = 5000;
        timer.Tick += timer_Tick;
    }

    public void Start(string filePath)
    {
        this.filePath = filePath;
        this.processName = Path.GetFileNameWithoutExtension(filePath);
        timer.Enabled = true;
    }

    /// <summary>
    /// 定時(shí)檢測(cè)系統(tǒng)是否在運(yùn)行
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void timer_Tick(object sender, EventArgs e)
    {
        try
        {
            Process[] myproc = Process.GetProcessesByName(processName);
            if (myproc.Length == 0)
            {
                Log.Info("檢測(cè)到看護(hù)程序已退出,開(kāi)始重新激活程序,程序路徑:{0}",filePath);
                ProcessStartInfo info = new ProcessStartInfo
                {
                    WorkingDirectory = Path.GetDirectoryName(filePath),
                    FileName = filePath,
                    UseShellexecute = true
                };
                Process.Start(info);
                Log.Info("看護(hù)程序已啟動(dòng)");
            }
        }
        catch (Exception)
        {
            
        }
        
    }
}

2、在程序入口接收被看護(hù)程序的路徑,啟動(dòng)Dog掃描

static class Program
{
    static NotifyIcon icon = new NotifyIcon();
    private static Dog dog = new Dog();
    /// <summary>
    /// 應(yīng)用程序的主入口點(diǎn)。
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        if (args == null || args.Length == 0)
        {
            MessageBox.Show("啟動(dòng)參數(shù)異常""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }

        string filePath = args[0];
        if(!File.Exists(filePath))
        {
            MessageBox.Show("啟動(dòng)參數(shù)異常""提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }
        Process current = Process.GetCurrentProcess();
        Process[] processes = Process.GetProcessesByName(current.ProcessName);
        //遍歷與當(dāng)前進(jìn)程名稱相同的進(jìn)程列表 
        foreach (Process process in processes)
        {
            //如果實(shí)例已經(jīng)存在則忽略當(dāng)前進(jìn)程 
            if (process.Id != current.Id)
            {
                //保證要打開(kāi)的進(jìn)程同已經(jīng)存在的進(jìn)程來(lái)自同一文件路徑
                if (process.MainModule.FileName.Equals(current.MainModule.FileName))
                {
                    //已經(jīng)存在的進(jìn)程
                    return;
                }
                else
                {
                    process.Kill();
                    process.WaitForExit(3000);
                }
            }
        }
        icon.Text = "看門(mén)狗";
        icon.Visible = true;
        Log.Info("啟動(dòng)看門(mén)狗,看護(hù)程序:{0}",filePath);
        dog.Start(filePath);
        Application.Run();
    }
}

3、簡(jiǎn)單實(shí)現(xiàn)個(gè)日志記錄器(使用第三方庫(kù)也行,建議看護(hù)程序最好不要有任何依賴),也可直接使用我下面這個(gè),很簡(jiǎn)單,無(wú)任何依賴

public class Log
{
    //讀寫(xiě)鎖,當(dāng)資源處于寫(xiě)入模式時(shí),其他線程寫(xiě)入需要等待本次寫(xiě)入結(jié)束之后才能繼續(xù)寫(xiě)入
    private static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
    //日志文件路徑
    public static string logPath = "logs\\dog.txt";

    //靜態(tài)方法todo:在處理話類型之前自動(dòng)調(diào)用,去檢查日志文件是否存在
    static Log()
    {
        //創(chuàng)建文件夾
        if (!Directory.Exists("logs"))
        {
            Directory.createDirectory("logs");
        }
    }

    /// <summary>
    /// 寫(xiě)入日志.
    /// </summary>
    public static void Info(string format, params object[] args)
    {
        try
        {
            LogWriteLock.EnterWriteLock();
            string msg = args.Length > 0 ? string.Format(format, args) : format;
            using (FileStream stream = new FileStream(logPath, FileMode.Append))
            {
                StreamWriter write = new StreamWriter(stream);
                string content = String.Format("{0} {1}",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),msg);
                write.WriteLine(content);
                //關(guān)閉并銷毀流寫(xiě)入文件
                write.Close();
                write.Dispose();
            }
        }
        catch (Exception e)
        {

        }
        finally
        {
            LogWriteLock.ExitWriteLock();
        }
    }
}

至此,看護(hù)程序已經(jīng)搞定。接著在主程序(被看護(hù)程序)封裝一個(gè)啟停類

4、主程序封裝看門(mén)狗啟停類

public static class WatchDog
{
    private static string processName = "WatchDog";  //看護(hù)程序進(jìn)程名(注意這里不是被看護(hù)程序名,你可以試一下?lián)Q成主程序名字會(huì)使什么效果)
    private static string appPath = AppDomain.CurrentDomain.BaseDirectory; //系統(tǒng)啟動(dòng)目錄
    /// <summary>
    /// 啟動(dòng)看門(mén)狗
    /// </summary>
    public static void Start()
    {
        try
        {
            string program = string.Format("{0}{1}.exe", appPath, processName);
            ProcessStartInfo info = new ProcessStartInfo
            {
                WorkingDirectory = appPath,
                FileName = program,
                createNoWindow = true,
                UseShellexecute = true,
                Arguments = Process.GetCurrentProcess().MainModule.FileName  //被看護(hù)程序的完整路徑
            };
            Process.Start(info);
        }
        catch (Exception)
        {
        }
    }

    /// <summary>
    /// 停用看門(mén)狗
    /// </summary>
    public static void Stop()
    {
        Process[] myproc = Process.GetProcessesByName(processName);
        foreach (Process pro in myproc)
        {
            pro.Kill();
            pro.WaitForExit(3000);
        }
    }
}

原理也很簡(jiǎn)單,其中有兩點(diǎn)需要注意:

  • processName字段表示看護(hù)程序,不是被看護(hù)程序,如果寫(xiě)反了,嗯...(你可以試下效果)‘

  • Arguments參數(shù)是被看護(hù)程序的完整路徑,因?yàn)橐话闱闆r下,是由被看護(hù)程序啟動(dòng)看護(hù)程序,所以我們可以直接使用Process.GetCurrentProcess().MainModule.FileName獲取到被看護(hù)程序的完整路徑

5、在主程序入口點(diǎn)啟動(dòng)看門(mén)狗

public partial class App : Application
{
    [STAThread]
    static void Main()
    {
        //程序啟動(dòng)前調(diào)用看護(hù)程序
        WatchDog.Start();
        Application app = new Application();
        MainWindow mainWindow = new MainWindow();
        app.Run(mainWindow);
    }
}

Winform、普通WPF、Prism等入口點(diǎn)都不太一樣,根據(jù)項(xiàng)目實(shí)際情況靈活處理即可

最后在需要正常退出程序的地方(也就是主程序關(guān)閉按鈕或其它想要正常退出程序的地方)停止看門(mén)狗程序

效果

以下視頻來(lái)源于Dotnet9



源代碼

https://github.com/luchong0813/WatchDogDemo

后續(xù)

如果是別人的 建議使用nssm把別人的程序 封裝成服務(wù)由wondows去管理,可以去看我以前發(fā)表的如何用零代碼將應(yīng)用封裝成服務(wù)-NSSM,如果是自己的 需要彈框跟用戶反饋或交互,那就說(shuō)明不是無(wú)人值守,可以不用看門(mén)狗。

在類似地鐵進(jìn)站通道、機(jī)場(chǎng)安檢通道、口岸出入境通道等等都有一個(gè)引導(dǎo)程序,這種比較依賴圖形界面的可以嘗試使用看門(mén)狗程序,看門(mén)狗程序不依賴第三方庫(kù)且代碼量較少,一般不會(huì)跑飛。



該文章在 2023/10/16 16:02:34 編輯過(guò)
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved