|
|
using Common.HslAuthor.Framework;
|
|
|
using CompressorXN.Untils;
|
|
|
using CompressorXN_Common;
|
|
|
using CompressorXN_Communication.TuMos;
|
|
|
using CompressorXN_Log;
|
|
|
using CompressorXN_Service;
|
|
|
using Custom.Utils.Framework;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Diagnostics;
|
|
|
using System.Reflection;
|
|
|
using System.Runtime.InteropServices;
|
|
|
using System.Threading;
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
namespace CompressorXN
|
|
|
{
|
|
|
internal static class Program
|
|
|
{
|
|
|
#region 使用的Win32函数的声明
|
|
|
/// <summary>
|
|
|
/// 设置窗口的显示状态
|
|
|
/// </summary>
|
|
|
/// <param name="hWnd">窗口句柄</param>
|
|
|
/// <param name="cmdShow">指示窗口如何被显示</param>
|
|
|
/// <returns>如果窗体之前是可见,返回值为非零;如果窗体之前被隐藏,返回值为零</returns>
|
|
|
[DllImport("User32.dll")]
|
|
|
private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改变各种可视的记号。
|
|
|
/// 系统给创建前台窗口的线程分配的权限稍高于其他线程。
|
|
|
/// </summary>
|
|
|
/// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
|
|
|
/// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零</returns>
|
|
|
[DllImport("User32.dll")]
|
|
|
private static extern bool SetForegroundWindow(IntPtr hWnd);
|
|
|
|
|
|
// 指示窗口为普通显示
|
|
|
private const int WS_SHOWNORMAL = 1;
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 应用程序的主入口点。
|
|
|
/// </summary>
|
|
|
[STAThread]
|
|
|
static void Main()
|
|
|
{
|
|
|
|
|
|
//设置应用程序处理异常方式:ThreadException处理
|
|
|
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
|
|
//主线程异常捕获
|
|
|
Application.ThreadException += Application_ThreadException;
|
|
|
//子线程异常捕获
|
|
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
|
|
Application.EnableVisualStyles();
|
|
|
Application.SetCompatibleTextRenderingDefault(false);
|
|
|
|
|
|
#region 调用Win32 API,禁止程序重复运行并激活运行程序的窗口显示在最前端
|
|
|
/*
|
|
|
* 这种方式在VS调用的情况不成立的,因为在VS中按F5运行的进程为OnlyInstanceRunning.vshost,从这个进程的命名就可以看出
|
|
|
该进程为OnlyInstanceRunning进程的宿主进程
|
|
|
而直接点OnlyInstanceRunning.exe运行的程序进程为OnlyInstanceRunning,
|
|
|
但是我们可以一些小的修改,即currentProcess.ProcessName.Replace(".vshose","")此时无论如何都为 OnlyInstanceRunning
|
|
|
*/
|
|
|
|
|
|
//获得正在运行的程序,如果没有相同的程序,则运行该程序
|
|
|
Process process = RunningInstance();
|
|
|
if (process == null)
|
|
|
{
|
|
|
#region 授权
|
|
|
var communicationAuthor = HslAuthorize.HslCommunicationAuthor();
|
|
|
if (!communicationAuthor)
|
|
|
{
|
|
|
new FrmDialog("通讯授权失败!").ShowDialog();
|
|
|
}
|
|
|
|
|
|
var hslControlAuthor = HslAuthorize.HslControlsAuthor();
|
|
|
if (!hslControlAuthor)
|
|
|
{
|
|
|
new FrmDialog("控件授权失败!").ShowDialog();
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
InitSystemConfigIni();//读取配置文件
|
|
|
|
|
|
//FrmLogin frmLogin = new FrmLogin();
|
|
|
//frmLogin.ShowDialog();
|
|
|
//if (frmLogin.DialogResult == DialogResult.OK)
|
|
|
//{
|
|
|
// Application.Run(new FrmMain());
|
|
|
//}
|
|
|
Application.Run(new FrmMain());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 已经运行该程序,显示信息并使程序显示在前端
|
|
|
new FrmDialog("应用程序已经在运行中......").ShowDialog();
|
|
|
Thread.Sleep(1000);
|
|
|
Environment.Exit(Environment.ExitCode);
|
|
|
HandleRunningInstance(process);
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
|
|
|
#region 异常捕获
|
|
|
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
|
|
{
|
|
|
Exception ex = e.ExceptionObject as Exception;
|
|
|
LogHelper.Error(ex, "子线程异常捕获", string.Format("捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}\r\nCLR即将退出:{3}", ex.GetType(), ex.Message, ex.StackTrace, e.IsTerminating));
|
|
|
}
|
|
|
|
|
|
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
|
|
|
{
|
|
|
Exception ex = e.Exception;
|
|
|
LogHelper.Error(ex, "主线程异常捕获", string.Format("捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}", ex.GetType(), ex.Message, ex.StackTrace));
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region 禁止程序重复运行相关
|
|
|
/// <summary>
|
|
|
/// 获取正在运行的程序,没有运行的程序则返回null
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private static Process RunningInstance()
|
|
|
{
|
|
|
// 获取当前活动的进程
|
|
|
Process currentProcess = Process.GetCurrentProcess();
|
|
|
|
|
|
// 根据当前进程的进程名获得进程集合
|
|
|
// 如果该程序运行,进程的数量大于1
|
|
|
Process[] processcollection = Process.GetProcessesByName(currentProcess.ProcessName.Replace(".vshost", ""));
|
|
|
foreach (Process process in processcollection)
|
|
|
{
|
|
|
// 如果进程ID不等于当前运行进程的ID以及运行进程的文件路径等于当前进程的文件路径
|
|
|
// 则说明同一个该程序已经运行了,此时将返回已经运行的进程
|
|
|
if (process.Id != currentProcess.Id)
|
|
|
{
|
|
|
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == process.MainModule.FileName)
|
|
|
{
|
|
|
return process;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 显示已运行的程序
|
|
|
/// </summary>
|
|
|
/// <param name="instance"></param>
|
|
|
private static void HandleRunningInstance(Process instance)
|
|
|
{
|
|
|
// 显示窗口
|
|
|
ShowWindow(instance.MainWindowHandle, WS_SHOWNORMAL);
|
|
|
|
|
|
// 把窗体放在前端
|
|
|
SetForegroundWindow(instance.MainWindowHandle);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
|
/// 读取系统INI配置文件
|
|
|
/// </summary>
|
|
|
static void InitSystemConfigIni()
|
|
|
{
|
|
|
var iniFilePath = GlobalVar.IniFilePath;
|
|
|
|
|
|
GlobalVar.PlcIpAddress=IniHelper.Read("PlcConfig", "Ip", string.Empty,iniFilePath);
|
|
|
string strPlcPort = IniHelper.Read("PlcConfig", "port", string.Empty, iniFilePath);
|
|
|
int.TryParse(strPlcPort, out int plcPort);
|
|
|
GlobalVar.PlcPort = plcPort;
|
|
|
var dbServerIp = IniHelper.Read("DdataBaseConfig", "DbServerIp", "127.0.0.1", iniFilePath);
|
|
|
var port = IniHelper.Read("DdataBaseConfig", "Port", "5432", iniFilePath);
|
|
|
var database = IniHelper.Read("DdataBaseConfig", "Database", "", iniFilePath);
|
|
|
var userId = IniHelper.Read("DdataBaseConfig", "UserId", "postgres", iniFilePath);
|
|
|
var password = IniHelper.Read("DdataBaseConfig", "Password", "", iniFilePath);
|
|
|
var schema = IniHelper.Read("DdataBaseConfig", "Schema", "public", iniFilePath);
|
|
|
var strIsEncrypt = IniHelper.Read("DdataBaseConfig", "DbPwdIsEncrypt", "false", iniFilePath);
|
|
|
_ = bool.TryParse(strIsEncrypt, out bool isEncrypt);
|
|
|
//数据库连接
|
|
|
DbContext.GetConStr(dbServerIp, port, database, userId, password, isEncrypt, schema);
|
|
|
}
|
|
|
}
|
|
|
}
|