From c2f3031a39877db9312571a7b8b627d354cc63e6 Mon Sep 17 00:00:00 2001 From: Etienne LAFARGE Date: Tue, 15 Sep 2015 00:45:56 -0400 Subject: [PATCH 1/2] [Windows] Have a single instance of Agent Manager --- win32/gui.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/win32/gui.py b/win32/gui.py index 63381630db..6021b3a8e0 100644 --- a/win32/gui.py +++ b/win32/gui.py @@ -92,8 +92,16 @@ # Windows management # Import Windows stuff only on Windows if Platform.is_windows(): + import win32api + import win32con + import win32process import win32serviceutil import win32service + + # project + from utils.pidfile import PidFile + from utils.process import pid_exists + WIN_STATUS_TO_AGENT = { win32service.SERVICE_RUNNING: AGENT_RUNNING, win32service.SERVICE_START_PENDING: AGENT_START_PENDING, @@ -791,7 +799,53 @@ def info_popup(message, parent=None): QMessageBox.information(parent, 'Message', message, QMessageBox.Ok) +def kill_old_process(): + """ Kills or brings to the foreground (if possible) any other instance of this program. It + avoids multiple icons in the Tray on Windows. On OSX, we don't have to do anything: icons + don't get duplicated. """ + # On Windows, if a window is already opened, let's just bring it on the foreground + if Platform.is_windows(): + # Is there another Agent Manager process running ? + pidfile = PidFile('agent-manager-gui').get_path() + + old_pid = None + try: + pf = file(pidfile, 'r') + old_pid = int(pf.read().strip()) + pf.close() + except IOError: + pass + except ValueError: + pass + + if old_pid is not None and pid_exists(old_pid): + handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, False, old_pid) + exe_path = win32process.GetModuleFileNameEx(handle, 0) + + # If (and only if) this process is indeed an instance of the GUI, let's kill it + if 'agent-manager.exe' in exe_path: + win32api.TerminateProcess(handle, -1) + + win32api.CloseHandle(handle) + + # If we reached that point it means the current process should be the only running + # agent-manager.exe, let's save its pid + pid = str(os.getpid()) + try: + fp = open(pidfile, 'w+') + fp.write(str(pid)) + fp.close() + except Exception, e: + msg = "Unable to write pidfile: %s" % pidfile + log.exception(msg) + sys.stderr.write(msg + "\n") + sys.exit(1) + + if __name__ == '__main__': + # Let's kill any other running instance of our GUI/SystemTray before starting a new one. + kill_old_process() + app = QApplication([]) if Platform.is_mac(): add_image_path(osp.join(os.getcwd(), 'images')) From 381943df45baf06e1ca605485a48d0fad2befc66 Mon Sep 17 00:00:00 2001 From: Etienne LAFARGE Date: Thu, 17 Sep 2015 12:01:28 -0400 Subject: [PATCH 2/2] [windows] Slight code cleanup in GUI code Unfortunately I can't squash this commit into the previous one since the branch has already been merged into the `etienne/windows-omnibus4` branch. --- win32/gui.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/win32/gui.py b/win32/gui.py index 6021b3a8e0..1e514f2eb4 100644 --- a/win32/gui.py +++ b/win32/gui.py @@ -813,9 +813,7 @@ def kill_old_process(): pf = file(pidfile, 'r') old_pid = int(pf.read().strip()) pf.close() - except IOError: - pass - except ValueError: + except (IOError, ValueError): pass if old_pid is not None and pid_exists(old_pid): @@ -843,8 +841,9 @@ def kill_old_process(): if __name__ == '__main__': - # Let's kill any other running instance of our GUI/SystemTray before starting a new one. - kill_old_process() + if Platform.is_windows(): + # Let's kill any other running instance of our GUI/SystemTray before starting a new one. + kill_old_process() app = QApplication([]) if Platform.is_mac():