Java 通过UAC提升ProcessBuilder流程?

Java 通过UAC提升ProcessBuilder流程?,java,processbuilder,elevation,Java,Processbuilder,Elevation,我试图运行一个外部可执行文件,但显然它需要提升。代码如下所示,根据使用ProcessBuilder的示例修改(因此数组只有一个参数): 它在运行时返回以下内容: Exception in thread "main" java.io.IOException: Cannot run program "C:\Users\Gilliane\Downloads\bsdiff4.3-win32\bspatch.exe": CreateProcess error=740, The requested oper

我试图运行一个外部可执行文件,但显然它需要提升。代码如下所示,根据使用ProcessBuilder的示例修改(因此数组只有一个参数):

它在运行时返回以下内容:

Exception in thread "main" java.io.IOException: Cannot run program "C:\Users\Gilliane\Downloads\bsdiff4.3-win32\bspatch.exe": CreateProcess error=740, The requested operation requires elevation
我浏览了一下,知道在C#中,您可以通过这样做请求高程(从中可以看到):

但是,我在ProcessBuilder中没有看到类似的情况。另一种方法是在目标系统上安装,并使用ProcessBuilder调用“提升”提示符。但是,我不想强迫使用我的程序的人也安装这些提升工具


还有其他方法吗?

这不能用ProcessBuilder完成,您需要调用Windows API

我曾经使用类似于以下的代码来实现这一点:

Shell32X.java

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",
            });
        }
    }

}
package test;

import test.Shell32X.SHELLEXECUTEINFO;

import com.sun.jna.WString;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;

public class Elevator
{
    public static void main(String... args)
    {
        executeAsAdministrator("c:\\windows\\system32\\notepad.exe", "");
    }

    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 + ")");
        }
    }
}
lifter.java

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",
            });
        }
    }

}
package test;

import test.Shell32X.SHELLEXECUTEINFO;

import com.sun.jna.WString;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;

public class Elevator
{
    public static void main(String... args)
    {
        executeAsAdministrator("c:\\windows\\system32\\notepad.exe", "");
    }

    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 + ")");
        }
    }
}
的答案对我来说很好。但在做了更多的研究之后,我发现了另一种使用vb脚本和批处理文件的方法。我更喜欢这种方法,因为使用vb脚本不会导致每次打开应用程序时都弹出黑色的cmd窗口

  • 创建普通bat文件以打开外部可执行文件。 我将打开一个MySQL服务器可执行文件

    @echo off
    cd "C:\Program Files (x86)\MySQL\MySQL Server 5.6\bin"
    :: Title not needed:
    start /MIN  mysqld.exe
    exit
    
  • 另存为mysql.bat

  • 现在创建一个具有管理员权限的vb脚本,并在最后添加脚本以打开mysql.bat文件

  • 在CreateObject(“Wscript.Shell”)的末尾,Run运行bat文件mysql.bat

    Set WshShell = WScript.CreateObject("WScript.Shell")'
     If WScript.Arguments.length = 0 Then
        Set ObjShell = CreateObject("Shell.Application")
        ObjShell.ShellExecute "wscript.exe", """" & _
        WScript.ScriptFullName & """" &_
        " RunAsAdministrator", , "runas", 1
        Wscript.Quit
        End if
        CreateObject("Wscript.Shell").Run "C:\Users\Shersha\Documents\NetBeansProjects\Berries\batch\mysql.bat",0,True
    
  • 现在将此文件另存为mysql_start.vbs
  • 最后从java运行vb脚本
  • 就这样

     try {
        Runtime.getRuntime().exec("wscript C:\\\\Users\\\\Shersha\\\\Documents\\\\NetBeansProjects\\\\Berries\\\\batch\\\\mysql_start.vbs");
            } catch (IOException e) {
                                System.out.println(e);
                                System.exit(0);
            }
    

    谢谢你的快速回复!我将在我的应用程序的范围内对此进行测试,并让您知道它是如何工作的。是否有任何方法可以通过使用代码中的某些内容来避免出现确认弹出窗口(以管理员身份运行)?我不愿意尝试这一个,因为我不理解代码,但它工作得非常完美。谢谢分享@用户1813222你做了什么?我没有发现任何错误