Program.cs 10.6 KB
using System;
using Model;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
using BLL;
using log4net;
using System.Text;
using System.Collections.Generic;
using log4net.Util;

namespace SmartScan
{
    static class Program
    {
        static void show(string msg)
        {
            // MessageBox.Show(msg);
        }
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        /// <param name="args"></param>
        [STAThread]
        static void Main(string[] args)
        {
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
            Application.ThreadException += Application_ThreadException;
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            bool isShow = false;
            Environment.CurrentDirectory = Application.StartupPath;
            _ = new Mutex(true, Application.ProductName, out bool ret);
            if (!ret)
            {
                IntPtr formhwnd = GetWindowHandle("BarCode Rule Setting");
                if (formhwnd == IntPtr.Zero)
                    formhwnd = GetWindowHandle("条码规则设置");

                show($"查找条码规则窗口句柄:{formhwnd}");
                if (formhwnd != IntPtr.Zero)
                {
                    ShowWindow(formhwnd, SW_RESTORE);
                    SwitchToThisWindow(formhwnd, true);
                }
                else
                {
                    Process currentproc = Process.GetCurrentProcess();
                    Process[] processcollection = Process.GetProcessesByName(Application.ProductName);
                    //  该程序已经运行,
                    if (processcollection.Length >= 1)
                    {
                        foreach (Process process in processcollection)
                        {
                            if (process.Id != currentproc.Id)
                            {
                                // 如果进程的句柄为0,即代表没有找到该窗体,即该窗体隐藏的情况时
                                if (process.MainWindowHandle.ToInt32().Equals(0))
                                {
                                    string formTitle = "物料注册系统";
                                    // 获得窗体句柄
                                    formhwnd = FindWindow(null, formTitle);
                                    if (formhwnd != IntPtr.Zero)
                                    {
                                        // 重新显示该窗体并切换到带入到前台
                                        ShowWindow(formhwnd, SW_RESTORE);
                                        SwitchToThisWindow(formhwnd, true);
                                    }
                                    else
                                    {
                                        formTitle = "Material Registration System";
                                        formhwnd = FindWindow(null, formTitle);
                                        // 重新显示该窗体并切换到带入到前台
                                        ShowWindow(formhwnd, SW_RESTORE);
                                        SwitchToThisWindow(formhwnd, true);
                                    }
                                    show($"窗体隐藏,查找软件窗口句柄:{formhwnd}");
                                    isShow = true;
                                    break;
                                }
                                else
                                {
                                    // 如果窗体没有隐藏,就直接切换到该窗体并带入到前台
                                    // 因为窗体除了隐藏到托盘,还可以最小化
                                    SwitchToThisWindow(process.MainWindowHandle, true);
                                    show($"窗体没有隐藏,查找软件窗口句柄:{formhwnd}");
                                    isShow = true;
                                    break;
                                }
                            }
                        }
                    }
                }
                return;
            }

            if (!isShow)
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                //BLL.Config.Backgrounder = true;
                bool back = BLL.Config.Backgrounder;
                bool hide = false;
                if (args.Length > 0)
                    hide = args[0].ToLower() == "hide";
                if (Config.Func_EnabledOCR)
                {
                    var paddle = "paddleOCR.exe";
                    Process process = new Process();
                    process.StartInfo = new ProcessStartInfo();
                    process.StartInfo.FileName = paddle;
                    process.StartInfo.WorkingDirectory = ".\\paddle";
                    if (File.Exists(".\\paddle\\paddleOCR.exe"))
                        process.Start();
                }
                //else
                //{
                //    var onnxexe = "onnx\\OcrLiteOnnxForm.exe";
                //    Process process1 = Process.Start(onnxexe);
                //}




                Application.Run(new FrmLoading(back));  //预加载,完成后自动退出


                Common.frmMain = new FrmMain();
                Common.frmWaitting = new FrmWaitting();

                if (back)
                {
                    var fsp = new FrmSetPlus();
                    if (hide)
                        fsp.WindowState = FormWindowState.Minimized;

                    Application.Run(fsp);
                }
                else
                    Application.Run(Common.frmMain);
            }

            Exit();
        }
        
        private static bool IsRun()
        {
            Process current = Process.GetCurrentProcess();
            Process[] processes = Process.GetProcessesByName(current.ProcessName);
            foreach (Process process in processes)
            {
                if (process.Id == current.Id) continue;  //自己
                if (process.MainModule.FileName == current.MainModule.FileName)
                    return true;
            }
            return false;
        }

        private static void Exit()
        {
            LogNet.log.Info("=====准备退出...=====");
            BLLCommon.lightSource.Close();
            BLLCommon.ioModule?.Close();
            Camera.Dispose();
            WebService.Close();
            LogNet.log.Info("=====程序结束=====\r\n");
        }

        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            LogNet.log.Error("CurrentDomain_UnhandledException", (Exception)e.ExceptionObject);
        }

        private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            LogNet.log.Error("Application_ThreadException", e.Exception);
        }

        #region Win32函数的声明

        /// <summary>
        /// 找到某个窗口与给出的类别名和窗口名相同窗口 
        /// </summary>
        /// <param name="lpClassName">类别名</param>
        /// <param name="lpWindowName">窗口名</param>
        /// <returns>成功找到返回窗口句柄,否则返回null</returns>
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        /// <summary>
        /// 切换到窗口并把窗口设入前台,类似 SetForegroundWindow方法的功能
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <param name="fAltTab">True代表窗口正在通过Alt/Ctrl +Tab被切换</param>
        [DllImport("user32.dll ", SetLastError = true)]
        static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
        [DllImport("user32.dll")]
        private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
        private delegate bool WNDENUMPROC(IntPtr hWnd, int lParam);
        [DllImport("user32.dll")]
        private static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, int lParam);
        /// <summary>
        ///  设置窗口的显示状态 
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <param name="cmdShow">指示窗口如何被显示</param>
        /// <returns>如果窗体之前是可见,返回值为非零;如果窗体之前被隐藏,返回值为零</returns>
        [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
        public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
        public const int SW_RESTORE = 9;
        [DllImport("user32.dll")]
        private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
        #endregion

        //寻找系统的全部窗口
        static WindowInfo[] GetAllDesktopWindows()
        {
            List<WindowInfo> wndList = new List<WindowInfo>();
            EnumWindows(delegate (IntPtr hWnd, int lParam)
            {
                WindowInfo wnd = new WindowInfo();
                StringBuilder sb = new StringBuilder(256);
                //get hwnd
                wnd.hWnd = hWnd;
                //get window name
                GetWindowTextW(hWnd, sb, sb.Capacity);
                wnd.szWindowName = sb.ToString();
                //get window class
                GetClassNameW(hWnd, sb, sb.Capacity);
                wnd.szClassName = sb.ToString();
                Console.WriteLine("Window handle=" + wnd.hWnd.ToString().PadRight(20) + " szClassName=" + wnd.szClassName.PadRight(20) + " szWindowName=" + wnd.szWindowName);
                //add it into list
                wndList.Add(wnd);
                return true;
            }, 0);
            return wndList.ToArray();
        }
        static IntPtr GetWindowHandle(string titleName)
        {
            WindowInfo[] a = GetAllDesktopWindows();
            int i = 0;
            for (i = 0; i < a.Length; i++)
            {
                // MessageBox.Show(a[i].szWindowName.ToString());
                if (a[i].szWindowName.ToString().Contains(titleName))
                {
                    return a[i].hWnd;
                }
            }
            return IntPtr.Zero;
        }
    }

    public struct WindowInfo
    {
        public IntPtr hWnd;
        public string szWindowName;
        public string szClassName;
    }
}