Java:WinAppDriver。请求的操作需要提升

Posted

技术标签:

【中文标题】Java:WinAppDriver。请求的操作需要提升【英文标题】:Java: WinAppDriver. The requested operation requires elevation 【发布时间】:2021-11-17 03:36:03 【问题描述】:

我正在尝试直接在我的 Java 程序中打开 Windows 应用程序驱动程序,因为它可以与所有其他程序一起使用,但只有管理员才能获得运行它的权限。我在网上查过,但这些解决方案似乎都不起作用

String wadServerPath = "C:\\Program Files\\Windows Application Driver\\WinAppDriver.exe";

ProcessBuilder builder = new ProcessBuilder(wadServerPath).inheritIO();
Process process = builder.start();

错误信息:

Caused by: org.openqa.selenium.WebDriverException: The requested operation requires elevation. (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 360 milliseconds
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'

【问题讨论】:

【参考方案1】:

这个问题的解决方案有点棘手,首先我们将使用 JNA 库。如果您使用的是 maven,则可以使用此依赖项

<dependency>
  <groupId>net.java.dev.jna</groupId>
  <artifactId>jna</artifactId>
  <version>4.5.0</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna-platform</artifactId>
    <version>4.5.0</version>
</dependency>

至于代码,我们实现了“Shell32”接口,以便直接访问windows的shell。

import java.util.Arrays;
import java.util.List;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.Shell32;
import com.sun.jna.platform.win32.WinDef.HINSTANCE;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinReg.HKEY;
import com.sun.jna.win32.W32APIOptions;

public interface Shell32X extends Shell32 
    Shell32X INSTANCE = (Shell32X) Native.loadLibrary("shell32", Shell32X.class, W32APIOptions.UNICODE_OPTIONS);

    int SW_HIDE = 0;
    int SW_MAXIMIZE = 3;
    int SW_MINIMIZE = 6;
    int SW_RESTORE = 9;
    int SW_SHOW = 5;
    int SW_SHOWDEFAULT = 10;
    int SW_SHOWMAXIMIZED = 3;
    int SW_SHOWMINIMIZED = 2;
    int SW_SHOWMINNOACTIVE = 7;
    int SW_SHOWNA = 8;
    int SW_SHOWNOACTIVATE = 4;
    int SW_SHOWNORMAL = 1;

    /** File not found. */
    int SE_ERR_FNF = 2;

    /** Path not found. */
    int SE_ERR_PNF = 3;

    /** Access denied. */
    int SE_ERR_ACCESSDENIED = 5;

    /** Out of memory. */
    int SE_ERR_OOM = 8;

    /** DLL not found. */
    int SE_ERR_DLLNOTFOUND = 32;

    /** Cannot share an open file. */
    int SE_ERR_SHARE = 26;

    int SEE_MASK_NOCLOSEPROCESS = 0x00000040;

    int ShellExecute(int i, String lpVerb, String lpFile, String lpParameters, String lpDirectory, int nShow);

    boolean ShellExecuteEx(SHELLEXECUTEINFO lpExecInfo);

    public static class SHELLEXECUTEINFO extends Structure 
        /*
        * DWORD cbSize; ULONG fMask; HWND hwnd; LPCTSTR lpVerb; LPCTSTR lpFile; LPCTSTR
        * lpParameters; LPCTSTR lpDirectory; int nShow; HINSTANCE hInstApp; LPVOID
        * lpIDList; LPCTSTR lpClass; HKEY hkeyClass; DWORD dwHotKey; union  HANDLE
        * hIcon; HANDLE hMonitor;  DUMMYUNIONNAME; HANDLE hProcess;
        */

        public int cbSize = size();
        public int fMask;
        public HWND hwnd;
        public WString lpVerb;
        public WString lpFile;
        public WString lpParameters;
        public WString lpDirectory;
        public int nShow;
        public HINSTANCE hInstApp;
        public Pointer lpIDList;
        public WString lpClass;
        public HKEY hKeyClass;
        public int dwHotKey;

        /*
        * Actually: union  HANDLE hIcon; HANDLE hMonitor;  DUMMYUNIONNAME;
        */
        public HANDLE hMonitor;
        public HANDLE hProcess;

        protected List getFieldOrder() 
            return Arrays.asList(new String[]  "cbSize", "fMask", "hwnd", "lpVerb", "lpFile", "lpParameters",
                    "lpDirectory", "nShow", "hInstApp", "lpIDList", "lpClass", "hKeyClass", "dwHotKey", "hMonitor",
                    "hProcess", );
        
    


然后我们将所有内容实现到一个方法中,该方法将允许执行我们正在寻找的操作。

public static void executeAsAdministrator(String command, String args)

    Shell32X.SHELLEXECUTEINFO execInfo = new Shell32X.SHELLEXECUTEINFO();
    execInfo.lpFile = new WString(command);
    if (args != null)
        execInfo.lpParameters = new WString(args);
    execInfo.nShow = Shell32X.SW_SHOWDEFAULT;
    execInfo.fMask = Shell32X.SEE_MASK_NOCLOSEPROCESS;
    execInfo.lpVerb = new WString("runas");
    boolean result = Shell32X.INSTANCE.ShellExecuteEx(execInfo);

    if (!result)
    
        int lastError = Kernel32.INSTANCE.GetLastError();
        String errorMessage = Kernel32Util.formatMessageFromLastErrorCode(lastError);
        throw new RuntimeException("Error performing elevation: " + lastError + ": " + errorMessage + " (apperror=" + execInfo.hInstApp + ")");
    

然后在需要的地方调用它

String wadServerPath = "C:\\Program Files\\Windows Application Driver\\WinAppDriver.exe";

    //ProcessBuilder builder = new ProcessBuilder(wadServerPath).inheritIO();
    //Process process = builder.start();
    executeAsAdministrator(wadServerPath, "");

【讨论】:

以上是关于Java:WinAppDriver。请求的操作需要提升的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 WinAppDriver 和 Node 输入文本?

Sendkeys 在使用 Appium 的 Winappdriver 中不起作用

WinAppDriver中的拖放不起作用

使用 winappdriver 最大化桌面窗口无法正常工作

UWP UI自动化测试------WinAppDriver/Inspect.exe demo

我们可以使用“WinAppDriver”自动化Slack和Trello窗口存储应用程序吗?