简体   繁体   中英

Java JNA call to function “InitiateSystemShutdown” in dll Advapi32 don't work

I have this call to the function "InitiateSystemShutdown" of the Advapi32 dll with java jna but it didn't work:

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);
     }
}

The error is:

 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)

Someone can help me?

If after changing the funcion to "InitiateSystemShutdownA" or "InitiateSystemShutdownW" still isn't working, it's probably a permissions issue, as @cubrr suggested.

Try adding this:

    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());

just before this call to the function:

jnaLib.InitiateSystemShutdown(null, null, (short)0, true, true);

If you take a look at the documentation page for InitiateSystemShutdown , you'll notice at the bottom that the actual function names are InitiateSystemShutdownW (Unicode) and InitiateSystemShutdownA (ANSI). Most (all?) WinAPI functions which deal with strings are defined as preprocessor symbols which resolve to either the *A or *W ending function, depending on whether UNICODE is defined at compile time.

Example from Working with Strings :

#ifdef UNICODE
#define SetWindowText  SetWindowTextW
#else
#define SetWindowText  SetWindowTextA
#endif 

Rename your function to InitiateSystemShutdownA or InitiateSystemShutdownW , depending on which encoding you want to use. I've personally always used the ANSI variants, so I don't know if you need to specify the Unicode encoding manually if you go with the *W variant.

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);
}

Notice also that you need certain privileges to restart a computer. Excerpt from the documentation :

To shut down the local computer, the calling thread must have the SE_SHUTDOWN_NAME privilege. To shut down a remote computer, the calling thread must have the SE_REMOTE_SHUTDOWN_NAME privilege on the remote computer. By default, users can enable the SE_SHUTDOWN_NAME privilege on the computer they are logged onto, and administrators can enable the SE_REMOTE_SHUTDOWN_NAME privilege on remote computers. For more information, see Running with Special Privileges.

Common reasons for failure include an invalid or inaccessible computer name or insufficient privilege. The error ERROR_SHUTDOWN_IN_PROGRESS is returned if a shutdown is already in progress on the specified computer. The error ERROR_NOT_READY can be returned if fast-user switching is enabled but no user is logged on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM