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(' 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"])