CreateProcess zeigt kein Fenster



  • Hallo,

    ich bin mir nicht ganz sicher ob der Beitrag noch hier gehört oder ins API Forum...

    Ich hab einen Dienst erstellt der eine Anwendung überwachen soll. Unter anderem soll der Dienst die Anwendung starten und stoppen können. Wenn die die Funktionen in einer "Normalen" Applikation ausführe funktioniert das Starten und Stoppen. Wenn ich die aber vom Dienst aus starte, wird zwar die Anwendung gestartet (im Tastmanager zu sehen), aber kein Fenster angezeigt.

    STARTUPINFO si;
    	PROCESS_INFORMATION pi;
    
    	ZeroMemory( &si, sizeof(si) );
    	si.cb = sizeof(si);
    	ZeroMemory( &pi, sizeof(pi) );
    
    	CreateProcess( NULL,   // No module name (use command line)
    		L"D:\\SCB_Scan.exe",        // Anwendung
    		NULL,           // Process handle not inheritable
    		NULL,           // Thread handle not inheritable
    		FALSE,          // Set handle inheritance to FALSE
    		CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS,              // creation flags
    		NULL,           // Use parent's environment block
    		L"D:\\",           // Use parent's starting directory
    		&si,            // Pointer to STARTUPINFO structure
    		&pi );           // Pointer to PROCESS_INFORMATION structure
    

    Wie bring ich CreateProzess dazu das Fenster an zu zeigen?



  • Ein Dienst hat kein Fenster, deshalb wird vermutlich auch bei CreateProcess() keines automatisch erzeugt.

    Setzte mal die beiden Flags in der StartupInfo.

    startupInfo.dwFlags = STARTF_USESHOWWINDOW;
    startupInfo.wShowWindow = SW_SHOWDEFAULT;
    

    Damit sollte es gehen.

    MfG Stephan



  • Hatte ich schon getestet. Das funktioniert leider auch nicht. 😞



  • Kenn mich da auch nicht im Detail aus, aber ein (nicht-interaktiver) Service läuft in einer anderen Windowstation mit eigenem Desktop und vererbt diese Eigenschaften auch an alle Kindprozesse. Um ein Fenster anzuzeigen muss dein Prozess auf die User-Windowstation und den User Desktop wechseln.
    Wirf mal einen Blick in die Window Station und Desktop API, vielleicht werden da auch irgendwo Beispiele verlinkt.



  • Fragemann123 schrieb:

    Hatte ich schon getestet. Das funktioniert leider auch nicht. 😞

    Ok, sorry da hatte ich mich getäuscht.
    Das ganze ist nicht wirklich einfach, dein Dienst muß sich als Benutzer anmelden, sonst klappt das ganze nicht wirklich.
    Habe die Funktion von unten im Einsatz (keine Ahnung wo die einzelnen Teile wirklich her waren).
    Damit sollte es zumindest funktionieren.

    DWORD StartInteractiveClientProcess (
        LPTSTR lpszUsername,    // client to log on
        LPTSTR lpszDomain,      // domain of client's account
        LPTSTR lpszPassword,    // client's password
        LPTSTR lpCommandLine    // command line to execute
    )
    {
       HANDLE      hToken;
       HDESK       hdesk = NULL;
       HWINSTA     hwinsta = NULL, hwinstaSave = NULL;
       PROCESS_INFORMATION pi;
       PSID pSid = NULL;
       STARTUPINFO si;
       DWORD iResult = FALSE;
    
    // Log the client on to the local computer.
    
       if (!LogonUser(
               lpszUsername,
               lpszDomain,
               lpszPassword,
               LOGON32_LOGON_INTERACTIVE,
               LOGON32_PROVIDER_DEFAULT,
               &hToken) )
       {
          L.GetSystemErrorMessage(L"%s LogonUser()", ERROR_AT);
          goto Cleanup;
       }
    
    // Save a handle to the caller's current window station.
    
       if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)
       {
          L.GetSystemErrorMessage(L"%s GetProcessWindowStation()", ERROR_AT);
          goto Cleanup;
       }
    
    // Get a handle to the interactive window station.
    
       hwinsta = OpenWindowStation(
           L"winsta0",                   // the interactive window station
           FALSE,                       // handle is not inheritable
           READ_CONTROL | WRITE_DAC);   // rights to read/write the DACL
    
       if (hwinsta == NULL)
       {
          L.GetSystemErrorMessage(L"%s OpenWindowStation()", ERROR_AT);
          goto Cleanup;
       }
    
    // To get the correct default desktop, set the caller's
    // window station to the interactive window station.
    
       if (!SetProcessWindowStation(hwinsta))
       {
          L.GetSystemErrorMessage(L"%s SetProcessWindowStation()", ERROR_AT);
          goto Cleanup;
       }
    
    // Get a handle to the interactive desktop.
    
       hdesk = OpenDesktop(
          L"default",     // the interactive window station
          0,             // no interaction with other desktop processes
          FALSE,         // handle is not inheritable
          READ_CONTROL | // request the rights to read and write the DACL
          WRITE_DAC |
          DESKTOP_WRITEOBJECTS |
          DESKTOP_READOBJECTS);
    
       if (hdesk == NULL)
       {
          L.GetSystemErrorMessage(L"%s OpenDesktop()", ERROR_AT);
          goto Cleanup;
       }
    
    // Restore the caller's window station.
    
       if (!SetProcessWindowStation(hwinstaSave))
       {
          L.GetSystemErrorMessage(L"%s SetProcessWindowStation()", ERROR_AT);
          goto Cleanup;
       }
    
    // Get the SID for the client's logon session.
    
       if (!GetLogonSID(hToken, &pSid))
       {
          L.GetSystemErrorMessage(L"%s GetLogonSID()", ERROR_AT);
          goto Cleanup;
       }
    
    // Allow logon SID full access to interactive window station.
    
       if (! AddAceToWindowStation(hwinsta, pSid) )
       {
          L.GetSystemErrorMessage(L"%s AddAceToWindowStation()", ERROR_AT);
          goto Cleanup;
       }
    
    // Allow logon SID full access to interactive desktop.
    
       if (! AddAceToDesktop(hdesk, pSid) )
       {
          L.GetSystemErrorMessage(L"%s AddAceToDesktop()", ERROR_AT);
          goto Cleanup;
       }
    
    // Impersonate client to ensure access to executable file.
    
       if (! ImpersonateLoggedOnUser(hToken) )
       {
          L.GetSystemErrorMessage(L"%s ImpersonateLoggedOnUser()", ERROR_AT);
          goto Cleanup;
       }
    
    // Initialize the STARTUPINFO structure.
    // Specify that the process runs in the interactive desktop.
    
       ZeroMemory(&si, sizeof(STARTUPINFO));
       si.cb= sizeof(STARTUPINFO);
       si.lpDesktop = TEXT("winsta0\\default");
    
    // Launch the process in the client's logon session.
    
       iResult = CreateProcessAsUser(
          hToken,            // client's access token
          NULL,              // file to execute
          lpCommandLine,     // command line
          NULL,              // pointer to process SECURITY_ATTRIBUTES
          NULL,              // pointer to thread SECURITY_ATTRIBUTES
          FALSE,             // handles are not inheritable
          NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,   // creation flags
          NULL,              // pointer to new environment block
          NULL,              // name of current directory
          &si,               // pointer to STARTUPINFO structure
          &pi                // receives information about new process
       );
    
       if(iResult == 0)
       {
          L.GetSystemErrorMessage(L"%s CreateProcessAsUser()", ERROR_AT);
       }
    
    // End impersonation of client.
    
       RevertToSelf();
    
       if (iResult && pi.hProcess != INVALID_HANDLE_VALUE)
       {
          unsigned long ExitCode;
          WaitForSingleObject(pi.hProcess, INFINITE);
          GetExitCodeProcess(pi.hProcess, &ExitCode);
          CloseHandle(pi.hProcess);
          iResult = ExitCode;
       }
    
       if (pi.hThread != INVALID_HANDLE_VALUE)
          CloseHandle(pi.hThread);
    
    Cleanup:
    
       if (hwinstaSave != NULL)
          SetProcessWindowStation (hwinstaSave);
    
    // Free the buffer for the logon SID.
    
       if (pSid)
          FreeLogonSID(&pSid);
    
    // Close the handles to the interactive window station and desktop.
    
       if (hwinsta)
          CloseWindowStation(hwinsta);
    
       if (hdesk)
          CloseDesktop(hdesk);
    
    // Close the handle to the client's access token.
    
       if (hToken != INVALID_HANDLE_VALUE)
          CloseHandle(hToken);
    
       return iResult;
    }
    

    Viel Erfolg.


Anmelden zum Antworten