Skip to content

Commit

Permalink
run updater as admin
Browse files Browse the repository at this point in the history
  • Loading branch information
m1lhaus committed Jan 1, 2016
1 parent f8765b5 commit 7bd703a
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 30 deletions.
100 changes: 100 additions & 0 deletions tools/win_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env python
# -*- coding: utf-8

# (C) COPYRIGHT © Preston Landers 2010
# Released under the same license as Python 2.6.5


import sys
import os
import traceback
import types

import win32api
import win32con
import win32event
import win32process

from win32com.shell.shell import ShellExecuteEx
from win32com.shell import shellcon


def isUserAdmin():

if os.name == 'nt':
import ctypes
# WARNING: requires Windows XP SP2 or higher!
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
traceback.print_exc()
print "Admin check failed, assuming not an admin."
return False
elif os.name == 'posix':
# Check for root on Posix
return os.getuid() == 0
else:
raise RuntimeError, "Unsupported operating system for this module: %s" % (os.name,)


def runAsAdmin(cmdLine=None, wait=True):

if os.name != 'nt':
raise RuntimeError, "This function is only implemented on Windows."

python_exe = sys.executable

if cmdLine is None:
# cmdLine = [python_exe] + sys.argv
cmdLine = sys.argv
elif type(cmdLine) not in (types.TupleType, types.ListType):
raise ValueError("cmdLine is not a sequence.")

cmd = '"%s"' % (cmdLine[0],)
# XXX TODO: isn't there a function or something we can call to massage command line params?
params = " ".join(['"%s"' % (x,) for x in cmdLine[1:]])
cmdDir = ''
showCmd = win32con.SW_SHOWNORMAL
#showCmd = win32con.SW_HIDE
lpVerb = 'runas' # causes UAC elevation prompt.

# print "Running", cmd, params

# ShellExecute() doesn't seem to allow us to fetch the PID or handle
# of the process, so we can't get anything useful from it. Therefore
# the more complex ShellExecuteEx() must be used.

# procHandle = win32api.ShellExecute(0, lpVerb, cmd, params, cmdDir, showCmd)

procInfo = ShellExecuteEx(nShow=showCmd,
fMask=shellcon.SEE_MASK_NOCLOSEPROCESS,
lpVerb=lpVerb,
lpFile=cmd,
lpParameters=params)

if wait:
procHandle = procInfo['hProcess']
obj = win32event.WaitForSingleObject(procHandle, win32event.INFINITE)
rc = win32process.GetExitCodeProcess(procHandle)
#print "Process handle %s returned code %s" % (procHandle, rc)
else:
rc = None

return rc


def test():
rc = 0
if not isUserAdmin():
print "You're not an admin.", os.getpid(), "params: ", sys.argv
#rc = runAsAdmin(["c:\\Windows\\notepad.exe"])
rc = runAsAdmin()
else:
print "You are an admin!", os.getpid(), "params: ", sys.argv
rc = 0
x = raw_input('Press Enter to exit.')
return rc


if __name__ == "__main__":
sys.exit(test())
69 changes: 39 additions & 30 deletions updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

import psutil

from tools import full_stack, win_admin


class CopyToLogger(object):
"""
Expand All @@ -57,14 +59,6 @@ def write(self, buf):
for line in buf.rstrip().splitlines():
self.logger.log(self.log_level, line.rstrip())

# if buf == '\n':
# self.orig_output.write(buf)
# else:
# if isinstance(buf, str):
# buf = unicode(buf, u'utf-8')
# for line in buf.rstrip().splitlines():
# self.logger.log(self.log_level, line.rstrip())

def __getattr__(self, name):
return self.orig_output.__getattribute__(name) # pass all other methods to original fd

Expand Down Expand Up @@ -194,26 +188,41 @@ def main():


if __name__ == "__main__":
os.chdir(os.path.dirname(sys.argv[0]))

parser = argparse.ArgumentParser(description="Updater component for Woofer player. Script take downloaded package "
"and updates files in Woofer directory."
"This script should be always used only by Woofer player!")
parser.add_argument("installDir", type=str,
help="Where Woofer player files are stored")
parser.add_argument('pid', type=int,
help="PID of Woofer player process")
parser.add_argument('-r', '--restart', action='store_true',
help="ReOpen Woofer after update")
args = parser.parse_args()

args.installDir = args.installDir.decode(sys.getfilesystemencoding()) # utf8 support
if not os.path.isdir(args.installDir):
raise Exception("Install dir '%s' does NOT exist!" % args.installDir)
if not win_admin.isUserAdmin():
print "Have no admin rights, elevating rights now..."
win_admin.runAsAdmin()
print "Admin script launched, exit 0"

logger = setup_logging(log_dir=os.path.join(args.installDir, "log"))

try:
main()
finally:
time.sleep(3)
else:
exception = False
try:
os.chdir(os.path.dirname(sys.argv[0]))

parser = argparse.ArgumentParser(description="Updater component for Woofer player. Script take downloaded package "
"and updates files in Woofer directory."
"This script should be always used only by Woofer player!")
parser.add_argument("installDir", type=str,
help="Where Woofer player files are stored")
parser.add_argument('pid', type=int,
help="PID of Woofer player process")
parser.add_argument('-r', '--restart', action='store_true',
help="ReOpen Woofer after update")
args = parser.parse_args()

args.installDir = args.installDir.decode(sys.getfilesystemencoding()) # utf8 support
if not os.path.isdir(args.installDir):
raise Exception("Install dir '%s' does NOT exist!" % args.installDir)

logger = setup_logging(log_dir=os.path.join(args.installDir, "log"))
main()

except Exception:
exception = True
print full_stack()
raise

finally:
if exception:
x = raw_input('Press Enter to exit.')
else:
time.sleep(3)

0 comments on commit 7bd703a

Please sign in to comment.