Java JNA 对 dll Advapi32 中的函数"InitiateSystemShutdown"的调用不起作用



我对advapi32 dll的java jna的启动"启动"启动呼叫,但它不起作用:

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 variant的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特权。有关更多信息,请参阅具有特殊特权的运行。

失败的常见原因包括无效或无法访问的计算机名称或特权不足。如果在指定的计算机上已经进行了关闭,则返回错误的错误_shutdown_in_progress。如果启用了快速用户切换,则可以返回错误rorror_not_ready,但没有登录用户。

最新更新