2012-03-28 101 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