import os, subprocess, ctypes, struct
# TODO: consolidate tray refresher methods into class
WM_MOUSEMOVE = 0x200
winapi = ctypes.windll.user32
class Rectangle(ctypes.Structure):
_fields_ = [("left", ctypes.c_int32),
("top", ctypes.c_int32),
("right", ctypes.c_int32),
("bottom", ctypes.c_int32)]
def _atLeastWin7():
packed_version = ctypes.windll.kernel32.GetVersion()
(major, minor, build) = struct.unpack('<BBH', struct.pack('<L', packed_version))
return major > 6 or (major == 6 and minor >= 1)
def _findWindow(parent, winclass):
return winapi.FindWindowExW(parent, None, winclass, None)
def _findTray():
hwnd1 = _findWindow(None, "Shell_TrayWnd")
if hwnd1:
hwnd2 = _findWindow(hwnd1, "TrayNotifyWnd")
if hwnd2:
hwnd3 = _findWindow(hwnd2, "SysPager")
if hwnd3:
return _findWindow(hwnd3, "ToolbarWindow32")
def _findOverflowTray():
hwnd1 = _findWindow(None, "NotifyIconOverflowWindow")
if hwnd1:
return _findWindow(hwnd1, "ToolbarWindow32")
def _fakeCursorMovement(hwnd, x, y):
# XXX: check that x, y are short ints
return winapi.SendMessageW(hwnd, WM_MOUSEMOVE, 0, (y << 16) + x) == 0
def _touchWindow(hwnd):
r = Rectangle()
if winapi.GetClientRect(hwnd, ctypes.byref(r)):
for x in range(0, r.right, 5):
for y in range(0, r.bottom, 5):
_fakeCursorMovement(hwnd, x, y)
def refreshTray():
hwnd = _findTray()
if hwnd:
_touchWindow(hwnd)
if _atLeastWin7():
hwnd = _findOverflowTray()
if hwnd:
_touchWindow(hwnd)
if __name__ == '__main__':
print("Killing Dropbox...")
os.system("taskkill /F /IM Dropbox.exe")
print("Refreshing tray...")
refreshTray()
print("Restarting Dropbox...")
app = os.environ["APPDATA"] + "\\Dropbox\\bin\\Dropbox.exe"
subprocess.Popen([app, "/systemstartup"])
Comments