通过使用Python在管理模式下打开应用程序实现自动化

通过使用Python在管理模式下打开应用程序实现自动化,python,python-2.7,automation,pyautogui,pywinauto,Python,Python 2.7,Automation,Pyautogui,Pywinauto,要求: 使用脚本在管理模式下打开应用程序并自动执行其活动。 活动包括打开文件菜单->加载文件并执行所需任务 关于应用程序: 我试图自动化的应用程序是用C++ java、WPF和C++库开发的。 用于自动化的语言:Python 版本:2.7.14 使用的模块:Pywinauto、Pyautogui 尝试完成: 在应用程序的兼容性方面,它被设置为以管理员身份运行,并尝试使用以下代码打开应用程序,但导致了一组运行时错误 先决条件: 使用的代码: from pywinauto.application

要求: 使用脚本在管理模式下打开应用程序并自动执行其活动。 活动包括打开文件菜单->加载文件并执行所需任务

关于应用程序: 我试图自动化的应用程序是用C++ java、WPF和C++库开发的。 用于自动化的语言:Python

版本:2.7.14

使用的模块:Pywinauto、Pyautogui

尝试完成:
  • 在应用程序的兼容性方面,它被设置为以管理员身份运行,并尝试使用以下代码打开应用程序,但导致了一组运行时错误

    先决条件:

  • 使用的代码:

    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()
    
    错误: 引发AppStartError(消息) pywinauto.application.AppStartError:无法创建进程“C:\Program Files*sample*.exe” CreateProcess返回错误:(740,“CreateProcess”,“请求的操作需要提升”。)


  • 尝试使用以下引用在管理模式下打开应用程序: 但我不能按要求实现自动化

    结果:我能够以管理员权限打开应用程序,但pywinauto和pyautogui脚本失败

    错误:无法将Pyautogui和pywinauto脚本与runAsAdmin()一起使用

    注意:为了打开应用程序并进行自动化,使用Pywinauto并尝试与应用程序菜单交互,失败了,因此制作了一个Pyautogui获取坐标的脚本

  • 代码:

    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())
    
    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)
    
    3.尝试在没有管理员权限的情况下打开应用程序尝试使用自动化Pywinauto并尝试与应用程序菜单交互,但失败

    代码:

    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())
    
    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)
    
    如果有人能使用Pywinauto来帮助脚本实现自动化,包括在管理模式下打开应用程序并与其中的菜单交互,那就太好了


    提前感谢

    您必须在操作系统设置中手动禁用UAC。UAC确认对话框不能由操作系统设计自动执行(当然!)。禁用UAC后,您将看不到确认对话框,您的帖子中的配方(2)将起作用


    但是请注意,最好以admin的身份重新启动脚本,而不仅仅是以admin的身份启动应用程序。因为否则pywinauto非特权进程将无法访问应用程序的管理进程。

    嗨,vasily ryabov,感谢您的回复。关于管理模式,我将尝试您的建议并返回。我已尝试使用Pyuac脚本打开应用程序:,效果很好。但我无法使用Pywinauto的应用程序模块继续进行菜单选择。