У меня есть приложение, которое использует JNA
для выполнения любого другого приложения с использованием CreateProcess
api. Это работает очень хорошо, но когда мне нужно выполнить 32-разрядную версию собственного приложения для системы, выполняется 64-разрядная версия (присутствует в папке SysWOW64), например: notepad.exe 64 бит.JNA: Как использовать CreateProcess для выполнения 32-разрядной версии системного родного приложения в 64-битных системах?
Итак, существует какой-то способ решить эту проблему?
Я пробовал использовать Wow64DisableWow64FsRedirection
, но, похоже, не работает.
Мой код:
Execute класс:
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.WString;
import static com.sun.jna.platform.win32.WinBase.STARTF_USESHOWWINDOW;
import static com.sun.jna.platform.win32.WinUser.SW_HIDE;
import com.sun.jna.win32.StdCallLibrary;
import java.util.Arrays;
import java.util.List;
public class Execute {
public interface Kernel32 extends StdCallLibrary {
Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
boolean CreateProcessA(
String lpApplicationName
, String lpCommandLine
, Structure lpProcessAttributes
, Structure lpThreadAttributes
, boolean bInheritHandles
, int dwCreationFlags
, Structure lpEnvironment
, String lpCurrentDirectory
, Structure lpStartupInfo
, Structure lpProcessInformation);
}
public static class ProcessInformation extends Structure {
public Pointer hProcess;
public Pointer hThread;
public int dwProcessId;
public int dwThreadId;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "hProcess", "hThread", "dwProcessId", "dwThreadId" });
}
}
public static class StartupInfoA extends Structure {
public int cb;
public WString lpReserved;
public WString lpDesktop;
public WString lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public short wShowWindow;
public short cbReserved2;
public Pointer lpReserved2;
public Pointer hStdInput;
public Pointer hStdOutput;
public Pointer hStdError;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "cb", "lpReserved", "lpDesktop", "lpTitle", "dwX", "dwY", "dwXSize", "dwYSize", "dwXCountChars", "dwYCountChars", "dwFillAttribute", "dwFlags", "wShowWindow", "cbReserved2", "lpReserved2", "hStdInput", "hStdOutput", "hStdError" });
}
}
public static void ExecuteProc(String software){
ProcessInformation processInformation = new ProcessInformation();
StartupInfoA startupInfo = new StartupInfoA();
startupInfo.dwFlags = STARTF_USESHOWWINDOW;
startupInfo.wShowWindow = SW_HIDE;
Kernel32.INSTANCE.CreateProcessA(software, null
, null
, null
, true
, 0
, null
, "C:\\Windows\\System32\\"
, startupInfo
, processInformation);
}
}
Main:
public static native boolean Wow64DisableWow64FsRedirection(PointerByReference OldValue);
public static void Exec() {
PointerByReference lpBuffer = new PointerByReference();
Wow64DisableWow64FsRedirection(lpBuffer); // fails here
String sysdir = System.getenv("WINDIR") + "\\System32\\";
ExecuteProc(sysdir + "notepad.exe");
}
Вы должны использовать 32-битную версию JRE для выполнения 32-битного кода в 64-битных операционных системах. –