2012-03-28 104 views
8

我想能夠從控制檯分離我的程序,就像wget -b。代碼片段可能看起來像C#關閉標準輸出

static void Main(string[] args) 
{ 
    var settings = new Settings(args); 
    if (settings.Background) 
    { 
     /*Tell the user what's going on.*/ 
     System.Console.WriteLine("Detatching from console. The program will still be running."); 
     System.Console.Out.Close(); 
    } 
    /*do work then exit.*/ 
} 

但是System.Console.Out.Close();並沒有做正確的事情。

要澄清,「正確的事情」是,從控制檯運行該程序時,提示應該重新出現。或者,從explorer.exe運行該程序時,控制檯窗口應該關閉。

如果我不清楚,請讓我知道。

+0

可以肯定的是,我明白了你的問題:如果你在cmd窗口中鍵入yourprogram.exe,應該會出現一個新的。如果你在資源管理器中雙擊應用程序,那麼你想讓控制檯關閉?你想用你的應用程序做什麼? – 2012-03-28 18:00:47

+0

沒有控制檯的控制檯應用程序?等不及要看到這個答案... – 2012-03-28 18:00:58

+1

如果你想要一個長時間運行的應用程序停留在後臺,你需要一個Windows服務。如果您只是想定期啓動應用程序,則可以考慮使用任務計劃程序啓動它。 – jlafay 2012-03-28 18:01:27

回答

1

您提到的wget的來源可用here。你會注意到,在mswindows.c的第193 - 314行中,實現了一個fork程序。他們產生了一個新的wget實例並傳遞相同的參數。

的意見是知識性,太:

Windows不支持fork()的調用;所以我們通過調用Wget的另一個副本並使用與之相同的參數來僞造它。

和在線102:

在Windows 9x下,如果我們從一個16位進程中啓動......父進程應該恢復的時候了。在新臺幣下......這是一種徒勞的姿態,因爲家長會在恢復之前等待我們終止。

簡短答案似乎是「不要那樣做」。

+0

是的 - 你可以僞造它或者非常接近,但它是非常嚴格的'不鼓勵' – 2012-03-28 19:20:12

+0

你能想到另一種實現嗎? – 2012-03-28 19:43:56

+0

如果你不介意我問 - 在做什麼之前打印某些東西/返回一些東西給控制檯的目的是什麼......控制檯的其餘部分是幹什麼的?將兩個分開是合理的嗎?一個正在運行的服務,命令行組件可以發送一個命令,然後終止是否有意義? – 2012-03-28 19:49:52

1

有3個通道可用於任何正在運行的控制檯應用程序:STDIN,STDOUT,STDERR。傳統上,需要關閉所有3個應用才能釋放控制檯。

在Windows中,似乎有這樣做的API方法:FreeConsole ...和pinvoke.net

編輯:另一個SO帖子說,不開始後臺進程是不可能的:How to make a windowless/command-line application return but continue executing in background? ...在Unix中,只需一個fork();即可。

+0

這不起作用。 'static void Main(string [] args){System.Console.Out.Close(); System.Console.In.Close(); System.Console.Error.Close(); System.Console.WriteLine(「detatched。」);}'顯示控制檯未分離。 – 2012-03-28 18:51:48

+0

我嘗試過'FreeConsole'。它似乎*幾乎*工作。釋放它後,我不能再使用控制檯寫入標準輸出,但命令解釋程序仍然無法返回控制檯。 – 2012-03-28 18:53:26

+0

@LimitedAtonement是否通過運行cmd.exe啓動應用程序,然後運行應用程序?爲了回到shell,你需要連接到同一個控制檯的cmd.exe副本。 – 2012-03-28 19:14:49

0

要澄清,「正確的事情」是,從控制檯運行該程序時,提示應該重新出現。或者,從explorer.exe運行此程序時,控制檯窗口應關閉。

這不是你想讓「控制檯窗口[關閉]」,你希望它不存在。有一個非常簡單的方法來獲得你想要的東西:不要構建一個控制檯應用程序。 :-)

如果從命令行構建,請使用CSC /target:winexe ...。這將創建一個永遠不會與任何命令行關聯的Windows程序。

+0

這不完全是我的意圖。我想要一個控制檯一會兒,然後我想分離它。我剛纔編輯了這個問題來澄清這個要求。代碼示例現在可能更清晰。 – 2012-03-28 18:46:12

1

而不是創建一個控制檯應用程序,然後有與調用FreeConsole問題的,你也許可以得到你想要的東西通過創建一個正常的Windows應用程序,沒有圖形用戶界面,使用AllocConsole/AttachConsole/FreeConsole需要。

這樣你就可以在後臺運行一個應用程序,但可以根據需要顯示和隱藏控制檯窗口。雖然據我所知,這些控制檯窗口和正常的Windows命令提示符有一些區別,所以它可能不適用於你想要的。

+0

感謝您的回答。打開一個新的控制檯窗口當然是一個想法,但我希望只能與現有的控制檯窗口進行交互。我認爲我對FreeConsole沒有問題;它的行爲是「應該的」。我知道'AllocConsole'等問題的真正原因是命令解釋程序(cmd或powershell)在返回到命令解釋程序之前等待*進程*結束。再次感謝。 – 2012-03-30 20:27:49