Browse Source

其他-限制应用程度躲开

ZhouJieSheng 1 year ago
parent
commit
45040f40b8
3 changed files with 217 additions and 0 deletions
  1. 74 0
      PDF Office/App.xaml.cs
  2. 53 0
      PDF Office/Helper/Win32Helper.cs
  3. 90 0
      PDF Office/Views/MainWindow.xaml.cs

+ 74 - 0
PDF Office/App.xaml.cs

@@ -65,6 +65,9 @@ using Microsoft.AppCenter;
 using System.Globalization;
 using Microsoft.AppCenter.Analytics;
 using Microsoft.AppCenter.Crashes;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+using System.Text;
 
 namespace PDF_Master
 {
@@ -126,6 +129,15 @@ namespace PDF_Master
         //app第一次启动时需要弹出注册弹窗
         public static bool IsShowRegist = false;
 
+        /// <summary>
+        /// 双击打开文件通知ID
+        /// </summary>
+        public static uint MsgId;
+        /// <summary>
+        /// 将应用前置通知ID
+        /// </summary>
+        public static uint WakeId;
+
         /// <summary>
         /// 文案资源管理器  首页
         /// </summary>
@@ -202,6 +214,68 @@ namespace PDF_Master
 
         protected override void OnStartup(StartupEventArgs e)
         {
+            MsgId = Win32Helper.RegisterWindowMessage("msgNotify_PDFMaster");
+            WakeId = Win32Helper.RegisterWindowMessage("msgWake_PDFMaster");
+            Process[] pros = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
+
+            //禁止多开程序
+            if (pros.Length > 1)
+            {
+                if (e != null && e.Args != null && e.Args.Length > 0)
+                {
+                    foreach (var filePath in e.Args)
+                    {
+                        if (filePath.ToLower().Contains(".pdf")&&Path.GetExtension(filePath).ToLower()==".pdf")
+                        {
+                            try
+                            {
+                                uint mapSize = 1024;
+                                IntPtr mapHandle = Win32Helper.CreateFileMapping(IntPtr.Zero, IntPtr.Zero, Win32Helper.FileMapProtection.PageReadWrite, 0, mapSize, "Global\\sharePathNotify");
+
+                                if (mapHandle != IntPtr.Zero)
+                                {
+                                    IntPtr writePtr = Win32Helper.MapViewOfFileEx(mapHandle, Win32Helper.FileMapAccessType.Read | Win32Helper.FileMapAccessType.Write, 0, 0, UIntPtr.Zero, IntPtr.Zero);
+                                    Marshal.Copy(filePath.ToCharArray(), 0, writePtr, filePath.Length);
+                                    MD5 currMd5 = MD5.Create();
+                                    byte[] hashArray = currMd5.ComputeHash(Encoding.Default.GetBytes(filePath));
+                                    StringBuilder hexBuilder = new StringBuilder();
+                                    foreach (byte code in hashArray)
+                                    {
+                                        hexBuilder.AppendFormat("{0:X2}", code);
+                                    }
+
+                                    IntPtr waitPtr = Win32Helper.CreateEvent(IntPtr.Zero, true, false, "Global\\shareWaitNotify" + hexBuilder.ToString());
+                                    if (waitPtr != IntPtr.Zero)
+                                    {
+                                        Win32Helper.PostMessage((IntPtr)0xffff, MsgId, IntPtr.Zero, (IntPtr)filePath.Length);
+                                        Win32Helper.WaitForSingleObject(waitPtr, 5000);
+                                        Win32Helper.CloseHandle(waitPtr);
+                                    }
+                                    Win32Helper.UnmapViewOfFile(writePtr);
+                                    Win32Helper.CloseHandle(mapHandle);
+                                }
+                            }
+                            catch (Exception ex)
+                            {
+
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    //进程置于前台
+                    Win32Helper.PostMessage((IntPtr)0xffff, WakeId, IntPtr.Zero, IntPtr.Zero);
+                    IntPtr waitPtr = Win32Helper.CreateEvent(IntPtr.Zero, true, false, "Global\\shareWaitNotify" + Guid.NewGuid());
+                    Win32Helper.WaitForSingleObject(waitPtr, 5000);
+                    Win32Helper.CloseHandle(waitPtr);
+                }
+                Environment.Exit(1);
+                return;
+            }
+
+
+
             LicenseVerify();
 
             InitSettings();

+ 53 - 0
PDF Office/Helper/Win32Helper.cs

@@ -94,6 +94,29 @@ namespace PDF_Master.Helper
             SHCNF_FLUSHNOWAIT = 0x2000
         }
 
+        [Flags]
+        public enum FileMapProtection : uint
+        {
+            PageReadonly = 0x02,
+            PageReadWrite = 0x04,
+            PageWriteCopy = 0x08,
+            PageExecuteRead = 0x20,
+            PageExecuteReadWrite = 0x40,
+            SectionCommit = 0x8000000,
+            SectionImage = 0x1000000,
+            SectionNoCache = 0x10000000,
+            SectionReserve = 0x4000000,
+        }
+        [Flags]
+        public enum FileMapAccessType : uint
+        {
+            Copy = 0x01,
+            Write = 0x02,
+            Read = 0x04,
+            AllAccess = 0x08,
+            Execute = 0x20,
+        }
+
         [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
         public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes,
     bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
@@ -107,6 +130,36 @@ namespace PDF_Master.Helper
         [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
         public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
 
+        [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern uint RegisterWindowMessage(string lpString);
+
+        [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern int PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
+
+        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern bool SetEvent(IntPtr hEvent);
+
+        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpFileMappingAttributes, FileMapProtection flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, [MarshalAs(UnmanagedType.LPStr)] string lpName);
+
+        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern IntPtr MapViewOfFileEx(IntPtr hFileMappingObject, FileMapAccessType dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, UIntPtr dwNumberOfBytesToMap, IntPtr lpBaseAddress);
+
+        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern int UnmapViewOfFile(IntPtr lpBaseAddress);
+
+        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern bool CloseHandle(IntPtr hObject);
+
+        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern IntPtr OpenFileMapping(int dwDesiredAccess, int bInheritHandle, [MarshalAs(UnmanagedType.LPStr)] string lpName);
+
+        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);
+
+        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+        public static extern IntPtr OpenEvent(uint dwDesiredAccess, bool bInheritHandle, string lpName);
+
         /// <summary>
         /// 注册为默认PDF浏览器
         /// </summary>

+ 90 - 0
PDF Office/Views/MainWindow.xaml.cs

@@ -23,6 +23,9 @@ using System.IO;
 using ComPDFKit.PDFDocument;
 using PDFSettings.Settings;
 using PDF_Master.Properties;
+using System.Windows.Interop;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
 
 namespace PDF_Master.Views
 {
@@ -38,6 +41,93 @@ namespace PDF_Master.Views
         public MainWindow()
         {
             InitializeComponent();
+
+            this.SourceInitialized += MainWindow_SourceInitialized;
+        }
+
+        private void MainWindow_SourceInitialized(object sender, EventArgs e)
+        {
+            try
+            {
+                //限制应用多开,显示已有窗体或者直接打开文件
+                IntPtr hwnd = new WindowInteropHelper(this).Handle;
+                HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));
+            }
+            catch { }
+        }
+
+        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
+        {
+            if (msg == App.MsgId)
+            {
+                try
+                {
+                    int msgLength = (int)(lParam);
+                    IntPtr mapHandle = Win32Helper.OpenFileMapping((int)Win32Helper.FileMapAccessType.Read, 0, "Global\\sharePathNotify");
+                    IntPtr readPtr = Win32Helper.MapViewOfFileEx(mapHandle, Win32Helper.FileMapAccessType.Read, 0, 0, UIntPtr.Zero, IntPtr.Zero);
+                    string filePath = Marshal.PtrToStringAuto(readPtr, msgLength);
+                    Win32Helper.UnmapViewOfFile(readPtr);
+                    Win32Helper.CloseHandle(mapHandle);
+                    MD5 currMd5 = MD5.Create();
+                    byte[] hashArray = currMd5.ComputeHash(Encoding.Default.GetBytes(filePath));
+                    StringBuilder hexBuilder = new StringBuilder();
+                    foreach (byte code in hashArray)
+                    {
+                        hexBuilder.AppendFormat("{0:X2}", code);
+                    }
+
+                    IntPtr waitPtr = Win32Helper.OpenEvent(0x0002, false, "Global\\shareWaitNotify" + hexBuilder.ToString());
+                    if (waitPtr != IntPtr.Zero)
+                    {
+                        Win32Helper.SetEvent(waitPtr);
+                        Win32Helper.CloseHandle(waitPtr);
+                    }
+                    if (File.Exists(filePath))
+                    {
+                        //打开传过来的文件路径
+                        if (App.OpenedFileList.Contains(App.GuidPDFPath))
+                        {
+                            //如果已经打开时,则选中文档所在页签
+                            App.mainWindowViewModel.SelectItem(App.GuidPDFPath);
+                        }
+                        else
+                        {
+                            (this.DataContext as MainWindowViewModel).AddTabItem(filePath);
+                        }
+                        if (WindowState == WindowState.Minimized)
+                        {
+                            WindowState = WindowState.Normal;
+                        }
+                        Activate();
+                    }
+                }
+                catch (Exception ex)
+                {
+
+                }
+                handled = true;
+                return (IntPtr)(1);
+            }
+            if (msg == App.WakeId)
+            {
+                //将现有窗口激活 并前置
+                try
+                {
+                    if (WindowState == WindowState.Minimized)
+                    {
+                        WindowState = WindowState.Normal;
+                    }
+                    Activate();
+                    handled = true;
+                }
+                catch (Exception ex)
+                {
+
+                }
+
+                return (IntPtr)(1);
+            }
+            return IntPtr.Zero;
         }
 
         /// <summary>