2011-11-25 116 views
1

我試圖運行該應用程序是隱藏的,但應用程序窗體仍然可見。德爾福:shellexecute和sw_hide

ShellExecute(Handle, nil, 'app.exe', nil, nil, SW_HIDE); 

如何在Delphi中運行隱藏的應用程序?

+2

ShellExecute上的SW_HIDE功能不大。這只是一個建議,而不是一個需求。它是否隱藏取決於應用程序。就像@Pateman的解決方案一樣,您可以在這裏獲得流程的處理並在啓動後隱藏它,這將更加可靠。 – hatchet

回答

6

我建議使用CreateProcess來代替,因爲它會返回新啓動的應用程序的進程ID,您可以使用它來獲取窗口的句柄。這是我一直在使用的功能,也許你可以拿走不必要的碎片並根據需要調整它。

{$HINTS OFF} 
{ .: ExecNewProcess :. } 
function ExecNewProcess(const ProgramName: String; 
    const StartHidden, WaitForInput: Boolean; out WndInfo: TWndInfo): Boolean; 
var 
    StartInfo: TStartupInfo; 
    ProcInfo: TProcessInformation; 
    R: TRect; 
    SL: TStringList; 

    {$REGION 'EnumProcess'} 
    function EnumProcess(hHwnd: HWND; lParam: Integer): Boolean; stdcall; 
    var 
    WndInfo: PWndInfo; 
    pid: DWORD; 
    begin 
    Result := True; 

    WndInfo := PWndInfo(lParam); 
    if (WndInfo = nil) or (hHwnd = 0) then 
     exit; 

    GetWindowThreadProcessId(hHwnd, pid); 
    if (pid = WndInfo.PID) then 
    begin 
     if (WndInfo.WndHandle = 0) and (IsWindowVisible(hHwnd)) then 
     WndInfo.WndHandle := hHwnd; 
     //Result := False; 
    end; 
    end; 
    {$ENDREGION} 

begin 
    Result := False; 

    ZeroMemory(@StartInfo, SizeOf(TStartupInfo)); 
    ZeroMemory(@ProcInfo, SizeOf(TProcessInformation)); 

    StartInfo.cb := SizeOf(TStartupInfo); 
    StartInfo.dwFlags := STARTF_USESTDHANDLES; 
    if StartHidden then 
    begin 
    StartInfo.dwFlags := STARTF_USESHOWWINDOW or StartInfo.dwFlags; 
    StartInfo.wShowWindow := SW_SHOWMINNOACTIVE; 
    end; 

    Result := CreateProcess(PChar(ProgramName), nil, nil, nil, False, 0, nil, 
    nil, StartInfo, ProcInfo); 
    try 
    if Result then 
    begin 
     WndInfo.WndHandle := 0; 
     WndInfo.PID := ProcInfo.dwProcessId; 

     if WaitForInput then 
     WaitForInputIdle(ProcInfo.hProcess, INFINITE); 

     EnumWindows(@EnumProcess, Integer(@WndInfo)); 
     if (WndInfo.WndHandle <> 0) then 
     begin 
     if (StartHidden) then 
      ShowWindow(WndInfo.WndHandle, SW_HIDE); 
     Windows.GetWindowRect(WndInfo.WndHandle, R); 

     WndInfo.Width := R.Right - R.Left; 
     WndInfo.Height := R.Bottom - R.Top; 
     end; 
    end; 
    finally 
    CloseHandle(ProcInfo.hProcess); 
    CloseHandle(ProcInfo.hThread); 
    end; 
end; 
{$HINTS ON} 
+0

[DCC錯誤] Unit1.pas(28):E2003未聲明的標識符:'TWndInfo' – dedoki

+0

這只是我用來返回一些信息供以後使用的記錄。你並不需要它。基本上從我發佈的代碼片段中刪除重要部分。 – Pateman

2

正如你可以在這裏閱讀

http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153%28v=vs.85%29.aspx

它是由應用程序來決定如何處理SW_HIDE。因此,應用程序必須獲取消息並隱藏自身,據我所知...

+0

在**一些**的情況下,如果其他應用程序允許,您可以使用新進程的進程ID並告訴Windows將其隱藏(由上面的Pateman發佈)。但是,是的,如果目標應用程序不是你的(沒有源代碼),並且目標應用程序喜歡強制顯示其自身,那麼不能將其從另一個應用程序隱藏。但是它可以像啓動它之後一樣簡單,告訴windows隱藏它。 –