首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态链接库Advapi32中对函数"InitiateSystemShutdown“的Java JNA调用不起作用

动态链接库Advapi32中对函数"InitiateSystemShutdown“的Java JNA调用不起作用
EN

Stack Overflow用户
提问于 2017-05-03 17:56:51
回答 2查看 293关注 0票数 0

我使用java jna调用了Advapi32 dll的函数"InitiateSystemShutdown“,但它不起作用:

代码语言:javascript
复制
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);
     }
}

错误是:

代码语言:javascript
复制
 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)

有人能帮我吗?

EN

回答 2

Stack Overflow用户

发布于 2017-05-03 22:45:40

如果将函数更改为"InitiateSystemShutdownA“或"InitiateSystemShutdownW”后仍然不起作用,可能是权限问题,正如@cubrr所建议的那样。

尝试添加以下内容:

代码语言:javascript
复制
    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());

就在此函数调用之前:

代码语言:javascript
复制
jnaLib.InitiateSystemShutdown(null, null, (short)0, true, true);
票数 2
EN

Stack Overflow用户

发布于 2017-05-03 20:45:33

如果您查看一下InitiateSystemShutdown的文档页面,您会注意到在底部实际的函数名称是InitiateSystemShutdownW (Unicode)和InitiateSystemShutdownA (ANSI)。大多数(全部?)处理字符串的WinAPI函数被定义为预处理器符号,根据编译时是否定义了UNICODE,这些符号可以解析为*A或*W结束函数。

来自的示例

代码语言:javascript
复制
#ifdef UNICODE
#define SetWindowText  SetWindowTextW
#else
#define SetWindowText  SetWindowTextA
#endif 

根据要使用的编码,将函数重命名为InitiateSystemShutdownAInitiateSystemShutdownW。我个人一直使用ANSI变体,所以我不知道如果您使用*W变体,是否需要手动指定Unicode编码。

代码语言:javascript
复制
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);
}

另请注意,您需要某些权限才能重新启动计算机。摘自documentation

若要关闭本地计算机,调用线程必须具有SE_SHUTDOWN_NAME权限。若要关闭远程计算机,调用线程必须具有远程计算机上的SE_REMOTE_SHUTDOWN_NAME特权。默认情况下,用户可以在他们登录的计算机上启用SE_SHUTDOWN_NAME权限,管理员可以在远程计算机上启用SE_REMOTE_SHUTDOWN_NAME权限。有关更多信息,请参见使用特殊权限运行。

失败的常见原因包括无效或无法访问的计算机名称或权限不足。如果指定的计算机上已在关机,则返回错误ERROR_SHUTDOWN_IN_PROGRESS。如果启用了快速用户切换,但没有用户登录,则会返回错误ERROR_NOT_READY。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43756796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档