1

Requirement : Open an application in admin mode using the script and automate its activities. Activities includes opening the File Menu -> Load a file and do the required tasks.

About the Application : The application I am trying to automate is developed using C#, WPF with C++ and Java Libraries.

Language used for automation : Python.

Version : 2.7.14

Modules used : Pywinauto, Pyautogui

Attempts done :

  1. In the compatability of the application, it was set to Run as Admin and tried to open the application using the following code, but resulted in a Set of runtime errors.

    Prerequisite :

    enter image description here

Code used :

from pywinauto.application import Application
import time
app = Application(backend="uia").start("C:\Program Files\**sample**.exe")
#app = Application(backend="uia").connect("C:\Program Files\**sample**.exe")
dlg = app.Update
time.sleep(2)
app.windows()
window = app.top_window()
print app.windows()
print('printing the control identifiers')
window.print_control_identifiers()

Error : raise AppStartError(message) pywinauto.application.AppStartError: Could not create the process "C:\Program Files*sample*.exe" Error returned by CreateProcess: (740, 'CreateProcess', 'The requested operation requires elevation.')


  1. Tried opening the Application in Admin mode using the following reference : How to run python script with elevated privilege on windows But I am not able to do the automation as desired.

    Outcome : I am able to open the application with Admin Privilege, but the pywinauto and pyautogui scripts are failing.

    Error : Not able to use Pyautogui and pywinauto scripts with runAsAdmin()

    Note : In order to open the application and do the automation Pywinauto was used and tried to interact with the application menus, it failed, so made a script with Pyautogui taking coordinates.

Code :

import sys, os, traceback, types
import pywinauto.controls.uia_controls
from pywinauto import mouse
import time
import os
import pyautogui
import pywinauto

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."

    import win32api, win32con, win32event, win32process
    from win32com.shell.shell import ShellExecuteEx
    from win32com.shell import shellcon

    python_exe = sys.executable

    if cmdLine is None:
        cmdLine = [python_exe] + 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:\Program Files\**sample**.exe"])
        time.sleep(10)
        pywinauto.mouse.click(button='left', coords=(1199, 478))
        app1 = rc['sample']
        pywinauto.mouse.click(button='left', coords=(42, 33))
        time.sleep(10)
        print(pyautogui.position())

        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())

3.Tried to open the application without admin privileges tried the automation Pywinauto was used and tried to interact with the application menus, it failed.

Code :

import pywinauto
from pywinauto import application, timings
import pyautogui
from pywinauto.keyboard import send_keys
from pywinauto.application import Application
import pywinauto.controls.uia_controls
from pywinauto import mouse
import win32api
import git
import time
import os
app = Application(backend="uia").start("C:\Program Files\**sample**.exe")
#app = Application(backend="uia").connect("C:\Program Files\**sample**.exe")
dlg = app.Update
time.sleep(2)
app.windows()
window = app.top_window()
print app.windows()
print('printing the control identifiers')
window.print_control_identifiers()
app1 = app[u'**sample**']
app2 = Application.connect(title=u'**sample**')
app1.print_control_identifiers()
apps = app1[u'File']
#print apps
dlg_spec = app.Untitled**sample**
print('dlg_spec :')
#print dlg_spec
print('Done sample')
#time.sleep(2)

Would be great if someone can help with a script using Pywinauto to do the automation that includes opening the application in Admin Mode and interacting with the menus in it.

Thanks in Advance

Sonia Mathew
  • 31
  • 1
  • 8

1 Answers1

0

You have to disable UAC in OS settings manually. UAC confirmation dialog is not automatable by OS design (of course!). With disabled UAC you will not see confirmation dialog and the recipe (2) in your post will work.

But please note that it's better to restart the script as admin, not just start the app as admin. Because otherwise pywinauto non-privileged process won't have access to admin process of the app.

Vasily Ryabov
  • 9,386
  • 6
  • 25
  • 78
  • Hi vasily-ryabov, Thanks for the response. Regarding the Admin mode, I will try your suggestions and get back. – Sonia Mathew Nov 09 '20 at 06:44
  • 1
    I have tried opening the application by using Pyuac script : https://pypi.org/project/pyuac/ , and it worked fine. But I am not able to proceed with my menu selections with Application module of Pywinauto. – Sonia Mathew Nov 10 '20 at 11:14
  • Thanks for the link to PyUAC. Sorry, I'm constantly overloaded last year. If it's still actual, can you post new question with more details on the menu? Menu structure highly depends on application type (WPF, WinForms, Qt5 or something else). – Vasily Ryabov Jun 25 '21 at 09:42