[英]Change username and password for an existing Windows service in Java via Advapi32 (JNA API)
[英]Java JNA call to function “InitiateSystemShutdown” in dll Advapi32 don't work
我使用Java jna對此Advapi32 dll的函數“ InitiateSystemShutdown”進行了調用,但它不起作用:
public interface JNAApiInterface extends StdCallLibrary {
JNAApiInterface INSTANCE = (JNAApiInterface) Native.loadLibrary("Advapi32", JNAApiInterface.class);
public boolean InitiateSystemShutdown(String machine, String message, short timeout, boolean forceAppClose, boolean rebootAfterShutdown);
}
public class JNABucket {
public static void main(String args[]) {
System.setProperty("jna.library.path", "C:\\Windows\\System32");
JNAApiInterface jnaLib = JNAApiInterface.INSTANCE;
jnaLib.InitiateSystemShutdown(null, null, (short)0, true, true);
}
}
錯誤是:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up
function 'InitiateSystemShutdown': No se encontró el proceso especificado.
at com.sun.jna.Function.<init>(Function.java:179)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:430)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:410)
at com.sun.jna.Library$Handler.invoke(Library.java:205)
at com.sun.proxy.$Proxy0.InitiateSystemShutdown(Unknown Source)
at es.tecnocom.pruebas.JNABucket.main(JNABucket.java:9)
有人可以幫我嗎?
如果將功能更改為“ InitiateSystemShutdownA”或“ InitiateSystemShutdownW”后仍無法正常工作,則可能是權限問題,如@cubrr所建議。
嘗試添加以下內容:
HANDLEByReference hToken = new HANDLEByReference();
LUID luid = new LUID();
Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), WinNT.TOKEN_ADJUST_PRIVILEGES, hToken);
Advapi32.INSTANCE.LookupPrivilegeValue("", WinNT.SE_SHUTDOWN_NAME, luid);
TOKEN_PRIVILEGES tp = new TOKEN_PRIVILEGES(1);
tp.Privileges[0] = new LUID_AND_ATTRIBUTES(luid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
Advapi32.INSTANCE.AdjustTokenPrivileges(hToken.getValue(), false, tp, tp.size(), null, new IntByReference());
在此函數調用之前:
jnaLib.InitiateSystemShutdown(null, null, (short)0, true, true);
如果查看InitiateSystemShutdown
的文檔頁面,您會在底部注意到實際的函數名稱是InitiateSystemShutdownW
(Unicode)和InitiateSystemShutdownA
(ANSI)。 大多數處理字符串的WinAPI函數都定義為預處理器符號,這些符號可以解析為* A或* W結尾函數,具體取決於是否在編譯時定義了UNICODE
。
使用字符串的示例:
#ifdef UNICODE
#define SetWindowText SetWindowTextW
#else
#define SetWindowText SetWindowTextA
#endif
將函數重命名為InitiateSystemShutdownA
或InitiateSystemShutdownW
,具體取決於您要使用的編碼。 我個人一直使用ANSI變體,因此如果使用* W變體,我不知道是否需要手動指定Unicode編碼。
public interface JNAApiInterface extends StdCallLibrary {
JNAApiInterface INSTANCE = (JNAApiInterface) Native.loadLibrary("Advapi32", JNAApiInterface.class);
public boolean InitiateSystemShutdownA(String machine, String message, short timeout, boolean forceAppClose, boolean rebootAfterShutdown);
}
還要注意,您需要某些特權才能重新啟動計算機。 文檔摘錄:
要關閉本地計算機,調用線程必須具有SE_SHUTDOWN_NAME特權。 若要關閉遠程計算機,調用線程必須在遠程計算機上具有SE_REMOTE_SHUTDOWN_NAME特權。 默認情況下,用戶可以在他們登錄的計算機上啟用SE_SHUTDOWN_NAME特權,而管理員可以在遠程計算機上啟用SE_REMOTE_SHUTDOWN_NAME特權。 有關更多信息,請參見以特殊特權運行。
失敗的常見原因包括無效或不可訪問的計算機名稱或特權不足。 如果指定計算機上的關機正在進行,則返回錯誤ERROR_SHUTDOWN_IN_PROGRESS。 如果啟用了快速用戶切換但沒有用戶登錄,則可以返回錯誤ERROR_NOT_READY。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.