簡體   English   中英

DLL Advapi32中對函數“ InitiateSystemShutdown”的Java JNA調用不起作用

[英]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 

將函數重命名為InitiateSystemShutdownAInitiateSystemShutdownW ,具體取決於您要使用的編碼。 我個人一直使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM