最近在公司做的一个需求,项目进程是64为JDK,但是所依赖的额外程序是基于32位的dll开发的。所以就需要通过COM组件的方式来调用外部可执行文件。
但是在注册COM组件时,因为要修改注册表,我们我们必须是管理员的身份去运行这个EXE程序。
在网上找了很多办法,都试过,没用。
最后在stackoverflow上找到一篇文章讲解如何以管理员身份调用外部可执行文件
https://stackoverflow.com/questions/11041509/elevating-a-processbuilder-process-via-uac
使用ProcessBuilder无法做到这一点,必须得调用Windows API。
使用JNA通过类似于以下代码的代码来实现此目的
/**
* @param command
* @param args
* @DesktopJavaDocable disable
*/
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 + ")");
}
}
public interface Shell32X extends Shell32 {
// https://stackoverflow.com/questions/11041509/elevating-a-processbuilder-process-via-uac
// 不要删除无用的字段,给反射用的
Shell32X INSTANCE = 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;
/*