Program.cs 12.6 KB
using log4net;
using log4net.Config;
using OnlineStore.Common;
using OnlineStore.AssemblyLine;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using OnlineStore.DeviceLibrary;
using System.IO;

namespace OnlineStore.AssemblyLine
{
    static class Program
    {
        #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);

        /// <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;
        public static IntPtr formhwnd;
        //public static readonly ILog LOGGER = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        #endregion

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] Args)
        {

            //string code = " (X: 380,Y: 148) L00000000000WG9D19055;E20191230 0180;B7H.10618.5B1008082019123004000;R0080820191230E9600";
            //string r = CodeManager.ReplaceCode(code);
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
            AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
            // 因为方法三只能是最小化的窗体显示出来,如果隐藏到托盘中则不能把运行的程序显示出来 
            Process currentproc = Process.GetCurrentProcess();
            Process[] processcollection = Process.GetProcessesByName(currentproc.ProcessName.Replace(".vshost", string.Empty));
            //  该程序已经运行,

            bool isShow = false;
            if (processcollection.Length >= 1)
            {
                foreach (Process process in processcollection)
                {
                    if (process.Id != currentproc.Id)
                    {
                        // 如果进程的句柄为0,即代表没有找到该窗体,即该窗体隐藏的情况时
                        if (process.MainWindowHandle.ToInt32().Equals(0))
                        {
                            string formTitle = ConfigAppSettings.GetValue(Setting_Init.App_Title);
                            // 获得窗体句柄
                            formhwnd = FindWindow(null, formTitle);
                            // 重新显示该窗体并切换到带入到前台
                            ShowWindow(formhwnd, SW_RESTORE);
                            SwitchToThisWindow(formhwnd, true);
                            isShow = true;
                            break;
                        }
                        else
                        {
                            // 如果窗体没有隐藏,就直接切换到该窗体并带入到前台
                            // 因为窗体除了隐藏到托盘,还可以最小化
                            SwitchToThisWindow(process.MainWindowHandle, true);
                            isShow = true;
                            break;
                        }
                    }
                }
            }
            if (!isShow)
            {
                System.Net.ServicePointManager.DefaultConnectionLimit = 512;
                XmlConfigurator.Configure();
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                ManagerUtil.Init();
                Application.Run(new FrmLineStore());
            }
        }

        private static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
        {
            //  LogUnhandledException("CurrentDomain_FirstChanceException", e);
        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            LogUnhandledException("CurrentDomain_UnhandledException", e.ToString() + "" + e.ExceptionObject.ToString() + " ");
        }

        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            LogUnhandledException("Application_ThreadException", e.ToString() + "" + e.Exception.ToString() + " ");
        }

        static void LogUnhandledException(string type, string exceptionobj)
        {
            //这里可以进一步地写日志
            string dir = Application.StartupPath + "\\ErrorDump\\";
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);
            string formTitle = ConfigAppSettings.GetValue(Setting_Init.App_Title);
            MiniDump.Write(dir + DateTime.Now.ToString("yyyyMMddHHmmss") + $"-{formTitle}.dmp");
            LogUtil.error("【" + type + "】" + exceptionobj);
            MessageBox.Show(exceptionobj, type);
        }
        #region dump
        public sealed class MiniDump
        {
            [Flags]
            public enum DumpType : uint
            {
                // From dbghelp.h:
                MiniDumpNormal = 0x00000000,
                MiniDumpWithDataSegs = 0x00000001,
                MiniDumpWithFullMemory = 0x00000002,
                MiniDumpWithHandleData = 0x00000004,
                MiniDumpFilterMemory = 0x00000008,
                MiniDumpScanMemory = 0x00000010,
                MiniDumpWithUnloadedModules = 0x00000020,
                MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
                MiniDumpFilterModulePaths = 0x00000080,
                MiniDumpWithProcessThreadData = 0x00000100,
                MiniDumpWithPrivateReadWriteMemory = 0x00000200,
                MiniDumpWithoutOptionalData = 0x00000400,
                MiniDumpWithFullMemoryInfo = 0x00000800,
                MiniDumpWithThreadInfo = 0x00001000,
                MiniDumpWithCodeSegs = 0x00002000,
                MiniDumpWithoutAuxiliaryState = 0x00004000,
                MiniDumpWithFullAuxiliaryState = 0x00008000,
                MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
                MiniDumpIgnoreInaccessibleMemory = 0x00020000,
                MiniDumpValidTypeFlags = 0x0003ffff,
            };

            //typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
            //    DWORD ThreadId;
            //    PEXCEPTION_POINTERS ExceptionPointers;
            //    BOOL ClientPointers;
            //} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
            [StructLayout(LayoutKind.Sequential, Pack = 4)]  // Pack=4 is important! So it works also for x64!
            struct MiniDumpExceptionInformation
            {
                public uint ThreadId;
                public IntPtr ExceptioonPointers;
                [MarshalAs(UnmanagedType.Bool)]
                public bool ClientPointers;
            }

            //BOOL
            //WINAPI
            //MiniDumpWriteDump(
            //    __in HANDLE hProcess,
            //    __in DWORD ProcessId,
            //    __in HANDLE hFile,
            //    __in MINIDUMP_TYPE DumpType,
            //    __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
            //    __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
            //    __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam
            //    );
            [DllImport("dbghelp.dll",
              EntryPoint = "MiniDumpWriteDump",
              CallingConvention = CallingConvention.StdCall,
              CharSet = CharSet.Unicode,
              ExactSpelling = true, SetLastError = true)]
            static extern bool MiniDumpWriteDump(
              IntPtr hProcess,
              uint processId,
              IntPtr hFile,
              uint dumpType,
              ref MiniDumpExceptionInformation expParam,
              IntPtr userStreamParam,
              IntPtr callbackParam);

            [DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
            static extern uint GetCurrentThreadId();

            [DllImport("kernel32.dll", EntryPoint = "GetCurrentProcess", ExactSpelling = true)]
            static extern IntPtr GetCurrentProcess();

            [DllImport("kernel32.dll", EntryPoint = "GetCurrentProcessId", ExactSpelling = true)]
            static extern uint GetCurrentProcessId();

            public static bool Write(string fileName)
            {
                return Write(fileName, DumpType.MiniDumpWithFullMemory);
            }
            public static bool Write(string fileName, DumpType dumpType)
            {
                using (var fs = new System.IO.FileStream(fileName, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.None))
                {
                    MiniDumpExceptionInformation exp;
                    exp.ThreadId = GetCurrentThreadId();
                    exp.ClientPointers = false;
                    exp.ExceptioonPointers = System.Runtime.InteropServices.Marshal.GetExceptionPointers();
                    bool bRet = MiniDumpWriteDump(
                      GetCurrentProcess(),
                      GetCurrentProcessId(),
                      fs.SafeFileHandle.DangerousGetHandle(),
                      (uint)dumpType,
                      ref exp,
                      IntPtr.Zero,
                      IntPtr.Zero);
                    return bRet;
                }
            }
        }
        #endregion
        static void Test()
        {

            string s = "http://192.168.101.11/myproject/rest/api/qisda/device/getSize?robotIndex=2&barcode=L165K001877%3bE20200329+0730%3bBQT001200218504192020032915000%3bR04192020042451762%23%230201X104K100CT%2f15000%2f165K001877%2f20200329%23%23";
            string param = "robotIndex=2&barcode=L165K001877";
            System.Collections.Specialized.NameValueCollection data = new System.Collections.Specialized.NameValueCollection();
            Dictionary<string, object> value = new Dictionary<string, object>();
            data.Add("robotIndex", 2.ToString());
            data.Add("barcode", "L165K001877%3bE20200329+0730%3bBQT001200218504192020032915000%3bR04192020042451762%23%230201X104K100CT%2f15000%2f165K001877%2f20200329%23%23");
            value.Add("robotIndex", 2);
            value.Add("barcode", "L165K001877%3bE20200329+0730%3bBQT001200218504192020032915000%3bR04192020042451762%23%230201X104K100CT%2f15000%2f165K001877%2f20200329%23%23");
            // string param = JsonHelper.SerializeObject(value);
            s = "http://192.168.101.11/myproject/service/store/emptyPosForPutin?cids=line-ac-01%2cline-ac-02%2cline-ac-03%2cline-ac-04%2cline-ac-05%2cline-ac-06%2cline-ac-07%2cline-ac-08%2cline-ac-09%2cline-ac-10%2cline-ac-11%2cline-ac-12%2cline-ac-13%2cline-ac-14%2cline-ac-15%2cline-ac-16%2cline-ac-17%2cline-ac-18&code=%3d7x8%3dL0000000IA0106D25D015%3bE20200106+0730%3bB7H.10524.5C1035042020010604000+%3bR035042020010600208%23%23&rfid=B16";
            string result = HttpHelper.Post(s, "");
            s = "http://192.168.101.11/myproject/rest/api/qisda/device/getSize?robotIndex=2&barcode=L165K001877%3bE20200329+0730%3bBQT001200218504192020032915000%3bR04192020042451762%23%230201X104K100CT%2f15000%2f165K001877%2f20200329%23%23";
            result = HttpHelper.Post(s, "");
            return;
        }
    }
}