2009-02-04 35 views
34

我必須創建一個需要特定參數的控制檯應用程序。如果他們缺少或錯誤,我會打印出一條錯誤消息。Win32控制檯應用程序是否可以檢測是否已從資源管理器運行?

現在問題:如果有人通過雙擊控制檯窗口從資源管理器啓動程序,則立即消失。 (但該應用程序不是完全沒有用的資源管理器,你可以拖動文件到它,它會工作)

我可以總是等待按鍵,但我不希望如果用戶確實啓動它從命令行。

有什麼方法可以區分這些情況嗎?

+1

+1!剛剛創建時問了一個類似的Q. – 2013-01-21 10:11:54

回答

27

請參閱http://support.microsoft.com/kb/99115,「INFO:防止控制檯窗口消失」。

想法是使用GetConsoleScreenBufferInfo來確定光標沒有從最初的0,0位置移動。從@tomlogic

代碼示例的基礎上,引用的知識庫文章:

// call in main() before printing to stdout 
// returns TRUE if program is in its own console (cursor at 0,0) or 
// FALSE if it was launched from an existing console. 
// See http://support.microsoft.com/kb/99115 
#include <stdio.h> 
#include <windows.h> 
int separate_console(void) 
{ 
    CONSOLE_SCREEN_BUFFER_INFO csbi; 

    if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) 
    { 
     printf("GetConsoleScreenBufferInfo failed: %lu\n", GetLastError()); 
     return FALSE; 
    } 

    // if cursor position is (0,0) then we were launched in a separate console 
    return ((!csbi.dwCursorPosition.X) && (!csbi.dwCursorPosition.Y)); 
} 
+1

這相當原始:) 雖然這是一個黑客它正是我所需要的,它是更簡單,然後獲得PPID。 – 2009-02-05 07:07:14

+0

如果沒有參數傳遞給應用程序,那麼您應該只使用這種方法,這樣您仍然可以從cmd.exe執行「cls&app filename」 – Anders 2009-02-16 02:31:36

3

我相信cmd.exe設置CMDCMDLINE和CMDEXTVERSION environemntal變量時,它啓動。所以如果這些設置你的程序最可能是從一個shell啓動。

這不是萬無一失,但它是一些東西。

也可以用一些令人費解和可能不可靠的方式來確定您的家長PID,或者我可以收集。你可能想看看。

+1

我嘗試了環境變量,它們不存在,既不是從cmd.exe運行,也不是從外部運行時。然而,輸入`echo%cmdcmdline%`確實會產生一些東西,所以這個變量顯然只在cmd.exe本身有效,而不是它的子進程。 – Timwi 2010-08-20 02:10:12

0

如何在顯示錯誤消息時等待按鍵,而不是其他時間?

5

GetConsoleTitle()

我見過的代碼執行

if (!GetConsoleTitle(NULL, 0) && GetLastError() == ERROR_SUCCESS) { 
    // Console 
} else { 
    // GUI 
} 

但是...我ve發現AttachConsole()更有幫助

在C++(關閉我的頭頂,我不是C++程序員)

if (!AttachConsole(ATTACH_PARENT_PROCESS)) { 
    // GUI 
} else { 
    // Console, and you have a handle to the console that already exists. 
} 

更有效。此外,如果您發現自己處於GUI環境中並希望儘可能長時間待在那裏,但後來發現一些災難性事件可能真正將轉儲用於控制檯窗口(無法編寫編輯框窗口將其批註或附加到NT系統日誌並拋出MessageBox()),那麼當GUI方法失敗時,稍後您可以在AllocConsole()之後進行此操作。

0

這就像一個魅力:

@echo off 
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" goto nonconsole 

:console 
<do something> 
goto exit 

:nonconsole 
<do something> 
pause 

:exit 

this thread複製。我也嘗試過自己評估%cmdcmdline%,但是有一個關於引號字符(「)的問題,如果」%cmdcmdline%「==」%ComSpec%「goto [target]無法正常工作,則會阻止類似之類的內容。

相關問題