Java: WinAppDriver。请求的操作需要提升
Java: WinAppDriver. The requested operation requires elevation
我正在尝试直接在我的 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'
这个问题的解决方案有点棘手,首先我们将使用 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 程序中打开 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'
这个问题的解决方案有点棘手,首先我们将使用 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, "");