2014-07-26 64 views
-4

我有一個Win32應用程序創建一個簡單的窗口,我需要從另一個程序(cryengine)調用該程序/窗口。我的應用程序開始於int WINAPI WinMain(...)。我該怎麼做才能做到這一點?動態庫,.exe,靜態庫?我想從另一個應用程序調用Win32應用程序,我該怎麼辦?

我原計劃從我的其他程序中調用.exe。使用.dll會更好嗎?

+0

['CreateProcess()'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v = vs.85).aspx)?更糟糕的是,使用DLL通常不能得到回答。這完全取決於你的具體用例。 –

+0

好的,謝謝。最後我會執行一個新的過程。 –

回答

2

您不必去DLL或靜態庫的方式從另一個程序啓動您的程序。

使用CreateProcess,ShellExecuteShellExecuteEx

如果你的程序可以已經運行,那麼你可以使用FindWindow來獲得應用程序的窗口,並使用SendMessage告訴應用程序激活窗口發送一些信息。

但是,找到&激活(SetForegroundWindow)只會在任務欄中閃爍窗口按鈕,以便獲得用戶的關注。這是由Windows完成的,因此其他應用程序不能中斷並導致可用性問題。

+0

我會這樣做,謝謝 –

1

使用DLL的主要原因是將其託管在與EXE相同的進程中。如果你想啓動另一個程序,那麼你想啓動另一個EXE。

雖然原則上這很容易,但這會產生潛在的問題。

首先,CreateProcess是啓動另一個EXE的最低級別的方式,但只有當目標程序以相同的權限級別運行時纔有效。對於Win32應用程序,您應該使用ShellExecuteEx。確保正確的當前工作目錄也存在問題。

這裏的代碼相當強大的片段,您可以使用:

BOOL Autorun::SpawnProcess(const WCHAR* szExePath, const WCHAR* szExeArgs) 
{ 
    if(!szExePath) 
     return FALSE; 

    // NOTE: szExeArgs can be NULL. 

    // Get working directory from executable path.  
    WCHAR szDirectory[MAX_PATH]; 
    wcscpy_s(szDirectory, szExePath); 
    PathRemoveFileSpec(szDirectory); 

    // ShellExecute or ShellExecuteEx must be used instead of CreateProcess 
    // to permit the shell to display a UAC prompt asking for consent to 
    // elevate when the target executable's manifest specifies a run level 
    // of "requireAdministrator". 
    // 
    // You can only use CreateProcess if you know that the application you 
    // are spawning will be at the same run level as the current process. 
    // Otherwise, you will receive ERROR_ACCESS_DENIED if the elevation 
    // consent could not be obtained. 
    SHELLEXECUTEINFO info; 
    ZeroMemory(&info, sizeof(info)); 
    info.cbSize = sizeof(info); 
    info.lpVerb = L"open"; 
    info.fMask = SEE_MASK_FLAG_NO_UI; 
    info.lpFile = szExePath; 
    info.lpParameters = szExeArgs; 
    info.lpDirectory = szDirectory; 
    info.nShow = SW_SHOW; 
    if(!ShellExecuteEx(&info)) 
     return FALSE; 

    return TRUE; 
} 

這裏的另一個挑戰是,如果你想嘗試跟蹤子進程的「工作」。一些發射器試圖使用「作業對象」來跟蹤子進程本身可能啓動的所有內容。特別的問題是LAUNCHER - > TARGET PROGRAM - > REAL PROGRAM和原來的TARGET PROGRAM退出。問題在於「作業對象」被Windows程序兼容性助手隱式使用,並且無法將進程添加到多個作業。確保創建過程的唯一可靠方法不會添加到PCA作業中,以確保您使用的所有程序都具有適當的清單元素。有關更多信息,請參閱此blog post

對於只關心孩子的過程本身簡化的情況下,可以使用這樣的代碼片段:

BOOL Autorun::SpawnProcessAndWait(const WCHAR *szExePath, const WCHAR *szExeArgs, DWORD *pdwExitCode) 
{ 
    if(!szExePath) 
     return FALSE; 

    // NOTE: szExeArgs can be NULL. 
    // NOTE: pExitCode can be NULL. 

    // Get working directory from executable path.  
    WCHAR szDirectory[MAX_PATH]; 
    wcscpy_s(szDirectory, szExePath); 
    PathRemoveFileSpec(szDirectory); 

    // See SpawnProcess for information why ShellExecute or ShellExecuteEx 
    // must be used instead of CreateProcess. 
    SHELLEXECUTEINFO info; 
    ZeroMemory(&info, sizeof(info)); 
    info.cbSize = sizeof(info); 
    info.lpVerb = L"open"; 
    info.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS; 
    info.lpFile = szExePath; 
    info.lpParameters = szExeArgs; 
    info.lpDirectory = szDirectory; 
    info.nShow = SW_SHOW; 
    if(!ShellExecuteEx(&info)) 
     return FALSE; 

    // Wait for process to finish. 
    WaitForSingleObject(info.hProcess, INFINITE); 

    // Return exit code from process, if requested by caller. 
    if(pdwExitCode) 
     GetExitCodeProcess(info.hProcess, pdwExitCode); 

    CloseHandle(info.hProcess); 
    return TRUE; 
} 

順便說一句,這兩個代碼片段從傳統的DirectX SDK來(2010年6月)樣本「自動運行」。

相關問題