开发者

CreateProcessAsUser win api is not working on non win7 platforms

i am using the win-api functions: logonUser loadProfile CreateProcessAsUser

using java and jniwrapper.

i run my application as service process (local system account).

if i am using the CreateProcessWithLogon - it works only if i am not running from service (just regular stand alone application).

the process created successfully on windows 7, and doesn't on win xp and win 2003 server.

do you have any clue? how do i manage the 开发者_StackOverflowprocess / user privileges on win platform?

thanks....


They way windows deals with services and how they can interact changed around NT 6.0 (Vista, Server 2003 R2). It is usually a complicated subject, because it involves the creation of processes and especially UI from a something that is supposed to be non interactive. Making sense out of it often involves good knowledge of what is a Session, a Winsta and a Desktop on Windows.

The change (named "Session 0 isolation") is documented here: http://msdn.microsoft.com/en-us/windows/hardware/gg463353. It states that the correct way to display UI from a service is spawn a new process using CreateProcessAsUser, but you already knew that since your Windows 7 machine runs.

If I remember correctly, the behaviour of CreateProcessAsUser changed too: in previous versions, it did NOT added automatically the user to the winsta and desktop (which are securable objects, i.e. objects with an ACL, like files):

"If the application specifies a desktop in the lpDesktop member, it is the responsibility of the application to add permission for the specified user account to the specified window station and desktop."

This quote is taken from here: http://support.microsoft.com/kb/165194 Very useful article! Includes code samples on how to do all the ACL stuff (unfortunately, unmanaged code...)

Also, you may find additional same info here: http://msdn.microsoft.com/en-us/library/aa379608%28v=vs.85%29.aspx


With Java you can now use the JNA-API to execute the CreateProcess function on a windows system -

This starts a cmd console on the current users desktop (from a windows service running on session 0) that runs a program - tested windows 7-11

Use like

new CreateProcessAsUser("notepad.exe");
new CreateProcessAsUser("start PowerShell ");
import com.sun.jna.*;
import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.WinBase.*;

public class CreateProcessAsUser
{
    public CreateProcessAsUser(String toExecute)
    {
        WString nullW = null;
        PROCESS_INFORMATION processInformation = new PROCESS_INFORMATION();
        STARTUPINFO startupInfo = new STARTUPINFO();
        boolean result = MoreAdvApi32.INSTANCE.CreateProcessWithLogonW
                                                      (new WString("username"),                         // user
                                                              nullW,                                           // domain , null if local
                                                              new WString("password"),                         // password
                                                              MoreAdvApi32.LOGON_WITH_PROFILE,                 // dwLogonFlags
                                                              nullW,                                           // lpApplicationName
                                                              new WString("c:\\windows\\system32\\cmd.exe /c " + toExecute),   // command line
                                                              MoreAdvApi32.CREATE_NEW_CONSOLE,                 // dwCreationFlags
                                                              null,                                            // lpEnvironment
                                                              nullW,                   // directory
                                                              startupInfo,
                                                              processInformation);
        
        if (!result)
        {
            int error = Kernel32.INSTANCE.GetLastError();
            System.out.println("OS error #" + error);
            System.out.println(Kernel32Util.formatMessageFromLastErrorCode(error));
        }
    }
}

interface MoreAdvApi32 extends Advapi32
{
    MoreAdvApi32 INSTANCE =
            (MoreAdvApi32) Native.loadLibrary("AdvApi32", MoreAdvApi32.class);
    
    /*
     * BOOL WINAPI CreateProcessWithLogonW( __in LPCWSTR lpUsername,
     * __in_opt LPCWSTR lpDomain, __in LPCWSTR lpPassword, __in DWORD
     * dwLogonFlags, __in_opt LPCWSTR lpApplicationName, __inout_opt LPWSTR
     * lpCommandLine, __in DWORD dwCreationFlags, __in_opt LPVOID
     * lpEnvironment, __in_opt LPCWSTR lpCurrentDirectory, __in
     * LPSTARTUPINFOW lpStartupInfo, __out LPPROCESS_INFORMATION
     * lpProcessInfo );
     */
    
    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682431%28v=vs.85%29.aspx
    boolean CreateProcessWithLogonW
    (WString lpUsername,
     WString lpDomain,
     WString lpPassword,
     int dwLogonFlags,
     WString lpApplicationName,
     WString lpCommandLine,
     int dwCreationFlags,
     Pointer lpEnvironment,
     WString lpCurrentDirectory,
     STARTUPINFO lpStartupInfo,
     PROCESS_INFORMATION lpProcessInfo);
    
    public static final int LOGON_WITH_PROFILE = 0x00000001;
    public static final int LOGON_NETCREDENTIALS_ONLY = 0x00000002;
    
    
    int CREATE_NO_WINDOW = 0x08000000;
    int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
    int CREATE_NEW_CONSOLE = 0x00000010;
    int DETACHED_PROCESS = 0x00000008;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜