From 1b5e320313592da092187b5d79a950611b09cfe9 Mon Sep 17 00:00:00 2001 From: Jim Norman Date: Mon, 3 Jul 2006 19:04:31 +0000 Subject: [PATCH] Bug 164181. Prevent multiple instances of CASAManager on windows. --- CASA/CASA.changes | 4 + CASA/gui/CASAManager.csproj | 43 +++++----- CASA/gui/CASAManager.csproj.user | 2 +- CASA/gui/Common.cs | 4 + CASA/gui/SingleApplication.cs | 137 +++++++++++++++++++++++++++++++ 5 files changed, 170 insertions(+), 20 deletions(-) create mode 100644 CASA/gui/SingleApplication.cs diff --git a/CASA/CASA.changes b/CASA/CASA.changes index 031322bd..9dd8fa38 100644 --- a/CASA/CASA.changes +++ b/CASA/CASA.changes @@ -1,3 +1,7 @@ +-------------------------------------------------------------------- +Mon Jul 03 13:01:53 MST 2006 - jnorman@novell.com +- Bug 164181. Prevent multiple instances of CASAManager on windows. + -------------------------------------------------------------------- Tue Jun 27 14:22:53 MST 2006 - jnorman@novell.com - Added miCASARemoveKey API to dll. diff --git a/CASA/gui/CASAManager.csproj b/CASA/gui/CASAManager.csproj index ac062d62..c8437db3 100644 --- a/CASA/gui/CASAManager.csproj +++ b/CASA/gui/CASAManager.csproj @@ -104,40 +104,40 @@ Project = "{E21DD887-22F4-4935-9851-409715F663B0}" Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" /> - - - + + + @@ -198,6 +198,11 @@ SubType = "Code" BuildAction = "Compile" /> + - + + /// Summary description for SingleApp. + /// + public class SingleApplication + { + public SingleApplication() + { + + } + /// + /// Imports + /// + + [DllImport("user32.dll")] + private static extern int ShowWindow(IntPtr hWnd, int nCmdShow); + + [DllImport("user32.dll")] + private static extern int SetForegroundWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern int IsIconic(IntPtr hWnd); + + /// + /// GetCurrentInstanceWindowHandle + /// + /// + private static IntPtr GetCurrentInstanceWindowHandle() + { + IntPtr hWnd = IntPtr.Zero; + Process process = Process.GetCurrentProcess(); + Process[] processes = Process.GetProcessesByName(process.ProcessName); + foreach(Process _process in processes) + { + // Get the first instance that is not this instance, has the + // same process name and was started from the same file name + // and location. Also check that the process has a valid + // window handle in this session to filter out other user's + // processes. + if (_process.Id != process.Id && + _process.MainModule.FileName == process.MainModule.FileName && + _process.MainWindowHandle != IntPtr.Zero) + { + hWnd = _process.MainWindowHandle; + break; + } + } + Console.WriteLine("Window Handle: " + hWnd.ToString()); + return hWnd; + } + /// + /// SwitchToCurrentInstance + /// + public static bool SwitchToCurrentInstance() + { + IntPtr hWnd = GetCurrentInstanceWindowHandle(); + if (hWnd != IntPtr.Zero) + { + // Restore window if minimised. Do not restore if already in + // normal or maximised window state, since we don't want to + // change the current state of the window. + if (IsIconic(hWnd) != 0) + { + ShowWindow(hWnd, SW_RESTORE); + } + + // Set foreground window. + SetForegroundWindow(hWnd); + return true; + } + else + return false; + } + + /// + /// Execute a form base application if another instance already running on + /// the system activate previous one + /// + /// main form + /// true if no previous instance is running + public static bool Run(System.Windows.Forms.Form frmMain) + { + if(IsAlreadyRunning()) + { + //set focus on previously running app + SwitchToCurrentInstance(); + return false; + } + Application.Run(frmMain); + return true; + } + + /// + /// for GUI + /// + /// + public static bool Run() + { + if(IsAlreadyRunning()) + { + return true; + } + return false; + } + + /// + /// check if given exe alread running or not + /// + /// returns true if already running + private static bool IsAlreadyRunning() + { + string strLoc = Assembly.GetExecutingAssembly().Location; + FileSystemInfo fileInfo = new FileInfo(strLoc); + string sExeName = fileInfo.Name; + bool bCreatedNew; + + mutex = new Mutex(true, "Global\\"+sExeName, out bCreatedNew); + if (bCreatedNew) + mutex.ReleaseMutex(); + + return !bCreatedNew; + } + + static Mutex mutex; + const int SW_RESTORE = 9; + } +}