我使用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)有人能帮我吗?
发布于 2017-05-03 22:45:40
如果将函数更改为"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);发布于 2017-05-03 20:45:33
如果您查看一下InitiateSystemShutdown的文档页面,您会注意到在底部实际的函数名称是InitiateSystemShutdownW (Unicode)和InitiateSystemShutdownA (ANSI)。大多数(全部?)处理字符串的WinAPI函数被定义为预处理器符号,根据编译时是否定义了UNICODE,这些符号可以解析为*A或*W结束函数。
来自的示例
#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);
}另请注意,您需要某些权限才能重新启动计算机。摘自documentation
若要关闭本地计算机,调用线程必须具有SE_SHUTDOWN_NAME权限。若要关闭远程计算机,调用线程必须具有远程计算机上的SE_REMOTE_SHUTDOWN_NAME特权。默认情况下,用户可以在他们登录的计算机上启用SE_SHUTDOWN_NAME权限,管理员可以在远程计算机上启用SE_REMOTE_SHUTDOWN_NAME权限。有关更多信息,请参见使用特殊权限运行。
失败的常见原因包括无效或无法访问的计算机名称或权限不足。如果指定的计算机上已在关机,则返回错误ERROR_SHUTDOWN_IN_PROGRESS。如果启用了快速用户切换,但没有用户登录,则会返回错误ERROR_NOT_READY。
https://stackoverflow.com/questions/43756796
复制相似问题