CreateProcessW geht nicht immer



  • Hi,

    schreibe gerade eine MFC Applikation wo ich mit CreateProcessW
    ein anderes Programm aufrufen muss.

    Ich habe zwei verschiedene Applikationen getestet.
    Die eine funktioniert, wurde ebenfalls von mir in MFC (VS 8.0) geschrieben.
    Die andere,fremde, Applikation ebenfalls eine MFC (VC++ 6) kann ich mit CreateProcessW nicht anzeigen.

    Mit anzeigen meine ich dass CreateProcessW nicht false liefert, jedoch das Programm nicht anzeigt.

    Woran könnte es liegen?

    Näheres zum fremden Programm:

    Es besteht nur aus MessageBox Meldungen...hat sozusagen kein richtiges Dialog Fenster. Vielleicht hat es damit was zu tun.

    ....
    	SECURITY_ATTRIBUTES secur;
    	STARTUPINFO si;
    	PROCESS_INFORMATION piProc;
    
    	ZeroMemory(&si, sizeof(si));
    	si.cb = sizeof(si);
    	si.dwFlags = STARTF_USESHOWWINDOW;
    	si.wShowWindow = SW_SHOWNORMAL;
    	ZeroMemory(&piProc, sizeof(piProc));
    
    	secur.nLength = sizeof(secur);
    	secur.lpSecurityDescriptor = NULL;
    	secur.bInheritHandle = true;
    
    	if(!CreateProcessW(_T("D:\\bla\\Application.exe"),NULL,&secur,NULL,TRUE,0,NULL,NULL,&si,&piProc))
    {
    			msg.Format(_T("%d"),GetLastError());
    			MessageBoxW(msg,0,0);
    }
    
    ...
    


  • Warum verwendest Du "CreateProcessW" zusammen mit dem _T Makro?
    Das macht nun mal gar keinen Sinn.
    Entweder "CreateProcessW" und L"..."
    oder "CreateProcess" und _T Makro.

    Auch würde ich den ersten Parameter auf "NULL" setzen und den Pfad zur EXE im zweiten übergeben. Einige Programme kommen nicht ganz klar damit, wenn gar keine Kommandozeilen-Parameter vorhanden sind (i.d.R. ist immer argv[0] vorhanden (Prozessname), was bei Dir aber nicht der Fall ist).
    Wenn Du es aber im 2.Parameter übergibst, musst Du einen "beschreibbaren" String übergeben! (also kein String-Literal!).



  • danke,

    habs korrigiert.
    Ich hätte da ne andere Frage.. kann ich ein fremdes MFC Programm welches ich mit createprocess starte, direkt beim starten verstecken ?

    Habe folgendes probiert, geht aber leider nicht.

    ...
    STARTUPINFO si;
    ...
    
    si.wShowWindow = SW_HIDE;
    ...
    

    So wie ich das gerade mache ist meiner Meinung nach die unschöne variante.
    Ich mache ein FindWindowW, wenn nötig ein GetParent() dann wende ich
    ShowWindow(SW_HIDE) auf alle auftauchenden Fenster an.

    Man sieht hierbei dass irgendwelche Fenster für Bruchteile von Sekunden aufgebaut und wieder versteckt werden. Ist nicht so schön.

    Geht es auch anders?



  • Das mit der Startup-Info geht nur, wenn es das Programm auch unterstüzt! Also es muss "GetStartupInfo" aufrufen und dann auch das machen was dort steht... die meisten ignorieren es aber oder rufen explizit ShowWindow(SW_SHOW) auf...



  • also ne andere möglichkeit gibt es nicht?

    schade , ich finde es einfach blöd dass die fenster immer kurz "aufflackern" und wieder versteckt werden.



  • Wenn Du das Fenster gar nicht haben willst, dann starten den Prozess doch auf einem anderen (unsichtbaren) Desktop / oder einer anderen Session...



  • die beiden methoden kenn ich garnicht.
    könntest du mir Beispiele zeigen wie man die beiden umsetzt.
    Das wäre super.

    vielen dank!



  • habe mich für die createdesktop variante entschieden.
    Jedoch klappt FindWindow in zusammenhang mit dem Desktop handle nicht.

    Wie suche ich in diesem neuen Desktop nach Fenstern ohne SwitchDesktop zu machen.
    Ich will schon im alten Desktop bleiben nur das Progrämmchen im zweiten Desktop laufen lassen.

    Zum suchen könnt ich FindWindowEx nehmen, der jedoch ein window handle braucht der auf dem zweiten Desktop ist.

    Wie kriege ich diesen window Handle (hwndParent) um FindWindowEx benutzen zu können?

    danke!



  • soo jetzt läuft es endlich:

    Kann sein dass ich es etwas chaotisch gemacht habe. Falls es einfacher/besser geht sagt mir ruhig bescheid.

    WCHAR strDesk[] = L"NewDesk";
    
    	HDESK hdesk = CreateDesktopW(strDesk,NULL,NULL,DF_ALLOWOTHERACCOUNTHOOK,GENERIC_ALL,&secDesk);
    .
    .
    .
    brc = EnumDesktopWindows(hdesk,EnumWindowsProc,(LPARAM) &wi);
    .
    .
    .
    if(wi.hWnd)
    {
    	CWnd* pWnd1 = CWnd::FromHandle( wi.hWnd );
    	wnd_a = pWnd1;
    }
    .
    .
    .
    pstatic = FindWindowExW(wnd_a->GetSafeHwnd(),temphnd->GetSafeHwnd(),L"Static",NULL);
    

    EnumWindowsProc:

    BOOL CALLBACK CProgDlg::EnumWindowsProc(HWND hwnd, LPARAM lParam)
    {
      WNDINFO*    pWndInfo = (WNDINFO*)(lParam);
      DWORD       dwProcessID;
    
      ::GetWindowThreadProcessId(hwnd, &dwProcessID);
      if (dwProcessID == pWndInfo->dwProcessID)
      {
        pWndInfo->hWnd = hwnd;
        return false;
      } 
    	return true;
    }
    

Log in to reply