我有一个简单的应用程序,我想通过开关实现自动化。但是当我通过开关运行它时,我真的不希望显示用户界面。我只想让它运行,完成它的工作,在控制台中打印出内容,然后退出。另一方面,如果我不使用任何开关运行它,我希望弹出用户界面。在这种情况下,我真的不希望控制台窗口挂在后台。
有什么办法可以做到这一点,还是必须创建两个单独的项目,一个控制台应用程序和一个 Windows 应用程序?
I have a simple application that I would like to sort of automate via switches. But when I do run it via switches I don't really want a user interface showing. I just want it to run, do it's job, print stuff out in the console, and exit. On the other hand if I don't run it with any switches I want the user interface to pop up. And in this case I don't really want a console window hanging around in the background.
Is there any way I can do this, or do I have to create two separate projects, one Console Application and one Windows Application?
发布评论
评论(7)
虽然不完全符合您的要求,但我过去已经通过使用外观 .FreeConsole" rel="noreferrer">FreeConsole pInvoke 删除控制台窗口。
您将项目的输出类型设置为控制台应用程序。然后,您定义对
FreeConsole
的外部调用:然后,在您的
Main
方法中,根据您的条件进行切换。如果您需要 UI,请在打开表单之前调用FreeConsole
以清除控制台窗口。启动时控制台窗口确实会短暂出现,但就我而言,这是可以接受的。
这有点像黑客,而且有难闻的气味,所以我会认真考虑你是否确实想走这条路。
Whilst not exactly what you have asked, I've achieved the appearance of this behaviour in the past by using the FreeConsole pInvoke to remove the console window.
You set the output type of the project to be a console application. You then define the extern call to
FreeConsole
:Then, in you
Main
method you switch based on your conditions. If you want a UI, callFreeConsole
before opening the form to clear the console window.A console window does briefly appear at startup, but in my case it was acceptable.
This is a bit of a hack though and has a bad smell, so I'd seriously consider whether you do want to go down this route.
来自“旧新事物”
如何我是否可以编写一个可以作为控制台或 GUI 应用程序运行的程序?
你不能。
(我会让你点击文章了解如何伪造它的详细信息)
From 'The Old New Thing'
How do I write a program that can be run either as a console or a GUI application?
You can't.
(I'll let you click on the article for the details of how to fake it)
当然,只需根据命令行中传递的参数在静态 main(string[] args) 中放置一个 switch 语句(或 if else 构造)即可。我还这样做是为了在作为服务或作为控制台执行之间切换...
注意:将项目类型设置为控制台应用程序
编辑:感谢 Adrian Bank 的回答,FreeConsole() 是使用控制台窗口“分配”的更好方法,而不仅仅是最小化它...
Sure, just put a switch statement (or if else construction) in the static main(string[] args), based on arguments passed in command line. I also do this to switch between executing as a service or as a console...
NOTE: Set project type as Console App
EDIT: Thanks to Adrian Bank's answer, FreeConsole() is much better approach to "dispense" with Console window than just minimizing it...
它们是两种不同的范例,我认为使用这样的命令行开关不是一个好主意。为什么不将核心逻辑构建到控制台应用程序中,然后在需要时从 GUI 中调用它?这可以很好地将 UI 与实现分开,但仍然提供一种在需要时独立使用控制台应用程序的方法。
They are two different paradigms, I don't think that using a command line switch like this is a good idea. Why not build the core logic into a console application and then call that from the GUI when needed? This would nicely separate the UI from the implementation but would still provide a way to use the Console app stand alone when needed.
我相信答案是否定的,或者这是我上次研究这个问题的时候。
可执行文件被标记为窗口应用程序或控制台应用程序。您可以在 Visual Studio 中的项目属性中的应用程序、输出类型下看到这一点
。您可以通过使用两个应用程序(一个控制台应用程序,如果不带参数执行该控制台应用程序,则启动 GUI 应用程序)来模拟行为。您可能会看到控制台窗口闪烁,除非您是从已经打开的控制台运行的。
I believe the answer is no, or it was last time I looked into this problem.
The executable is marked as either a windowed application or a console application. You can see this in the properties for you project in Visual Studio, under application, Output type
You could simulate the behavior by having two application, a console application that if executed with no arguments launches the GUI application. You may see a console window flash, unless you ran in from an already open console.
如果不实现您自己版本的控制台窗口,答案是否定的。当 Windows 加载您的可执行文件时,它会根据 PE 标头中的数据决定是否为您提供控制台窗口。因此,您可以使窗口应用程序没有窗口,但不能使窗口应用程序具有控制台。
Without implementing your own version of a console window the answer is no. When Windows loads you executable it decides whether or not to give you a console window based on data in the PE header. So you can make a windowed app not have a window but you can't make a windoed app have a console.
可以,但有一些缺点:
如果为 Windows 子系统进行编译,则可以防止启动时出现此黑窗口。
但随后您必须通过 AttachConsole(-1) 手动将进程附加到调用控制台 (cmd.exe)
http://msdn.microsoft .com/en-us/library/windows/desktop/ms681952%28v=vs.85%29.aspx
仅此一项并不能完成这项工作。您还必须通过这些调用将三个 std 流重定向到控制台:
示例来自: http://cygwin.com/ml/cygwin/2004-05/msg00215.html
WinMain 调用的问题是 Windows 已经分叉出您的进程,因此调用 cmd.exe 控制台将从您的.exe 已经存在并继续执行下一个命令。
为了防止这种情况,您可以使用
start /wait myexe.exe
调用您的 exe这样您还可以获得应用程序的返回值,并且可以像往常一样使用 %errorlevel% 检查它。
如果有一种方法可以防止该进程与子系统窗口分叉,请告诉我。
希望这有帮助。
You can, but with some drawbacks:
You can prevent having this black window on start up if you compile for subsystem Windows.
But then you have to attach the process to the calling console (cmd.exe) manually via AttachConsole(-1)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681952%28v=vs.85%29.aspx
This alone does not do the job. You also have to redirect the three std streams to the console via these calls:
Sample from: http://cygwin.com/ml/cygwin/2004-05/msg00215.html
The problem with your WinMain call is that windows already has forked out your process so the calling cmd.exe console will have returned from your .exe already and proceed with the next command.
To prevent that you can call your exe with
start /wait myexe.exe
This way you also get the return value of your app and you can check it with %errorlevel% as usual.
If there is a way to prevent that process forking with subsystem windows please let me know.
Hope this helps.