Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows] Have a single instance of Agent Manager #1924

Merged
merged 2 commits into from
Sep 17, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions win32/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -791,7 +799,52 @@ 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or brings to the foreground (if possible) any other instance of this program

It looks like you actually always kill the previous instance in fact.

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():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking but you could check that before calling the function. That would avoid opening a new context for nothing if the platform is not Windows (and wrapping the whole thing in a big if).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are testing Platform.is_windows() two times.

# 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, 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__':
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():
add_image_path(osp.join(os.getcwd(), 'images'))
Expand Down