Delphi 同时作为控制台和GUI编程

Delphi 同时作为控制台和GUI编程,delphi,user-interface,console,Delphi,User Interface,Console,是否有可能(如果有,我如何)使用Delphi2007使单个程序同时作为控制台应用程序和GUI版本工作 我想说的是,如果程序使用适当的命令行选项运行,它应该作为控制台程序运行,使用WRITELN将输出打印到控制台,但是如果没有给出命令行参数,它应该作为正常的Delphi GUI应用程序运行 问题在于,当作为控制台应用程序运行时,命令行解释器会等待应用程序终止,然后才允许您输入新命令,而从命令行启动的GUI应用程序会立即将您返回到命令行,GUI应用程序会在分离的进程中启动。我想保留这种行为 我不介意

是否有可能(如果有,我如何)使用Delphi2007使单个程序同时作为控制台应用程序和GUI版本工作

我想说的是,如果程序使用适当的命令行选项运行,它应该作为控制台程序运行,使用WRITELN将输出打印到控制台,但是如果没有给出命令行参数,它应该作为正常的Delphi GUI应用程序运行

问题在于,当作为控制台应用程序运行时,命令行解释器会等待应用程序终止,然后才允许您输入新命令,而从命令行启动的GUI应用程序会立即将您返回到命令行,GUI应用程序会在分离的进程中启动。我想保留这种行为

我不介意这样的事情:

如果是GUI,则启动应用程序GUI(ParamStr(0))

如果需要,我不介意使用某种形式的执行调用重新启动应用程序,以GUI模式启动应用程序,只要启动GUI版本时命令行界面返回到命令行输入

我更喜欢一个大致如下的解决方案/建议:


如果是控制台模式,则
运行控制台(参数)
否则开始
应用程序初始化
Application.CreateForm(…)
应用程序。运行
结束

(反之亦然,即在GUI模式下以特殊方式做事)


因此,在制作GUI界面时,我仍然可以使用Delphi的IDE和VCL…

Windows在控制台和UI应用程序的可执行文件头中有不同的值(请参阅更多详细信息)。因此,似乎不可能使相同的可执行文件在两种模式下都工作


或者,您可以在UI应用程序中打开一个控制台,但它将是新的控制台,而不是您启动应用程序的控制台。

在Windows上,这有点棘手。实际上,控制台应用程序和GUI应用程序之间的区别是PE头中的一个标志。您可以很容易地编写控制台应用程序来创建窗口,但这样您就可以始终拥有控制台窗口(虽然您可以将其隐藏,但当人们从
cmd
运行您的程序时,这就不好了)

但是,如果需要,您可以编写GUI应用程序,使用以下函数创建控制台:

一个进程只能与一个控制台关联,因此如果调用进程已经有控制台,alloconsole函数将失败。进程可以使用该函数将自身从当前控制台分离,然后调用alloconsole创建新控制台或附加到另一个控制台

如果调用进程创建子进程,则子进程将继承新控制台

AllocConsole初始化新控制台的标准输入、标准输出和标准错误句柄。标准输入句柄是控制台输入缓冲区的句柄,标准输出和标准错误句柄是控制台屏幕缓冲区的句柄。要检索这些句柄,请使用函数

此功能主要由图形用户界面(GUI)应用程序用于创建控制台窗口。GUI应用程序在没有控制台的情况下初始化。控制台应用程序是用控制台初始化的,除非它们是作为分离进程创建的(通过调用带有分离进程标志的函数)


但是,当从
cmd
运行时,这可能会导致出现另一个控制台窗口,而不是重新使用现有窗口。我不知道那里是否存在一个好的解决方案。

在我看来,最好的方法是使用非可视化类来实际执行程序的工作。然后您可以从GUI程序调用它,也可以从单独的命令行程序调用它。这两个程序只是类功能的包装

这也迫使设计保持干净-您的类必须与应用程序的GUI层分离。

AttachConsole()可用于获取父控制台。 例如,如果应用程序是从cmdline shell启动的,则可以避免AllocSole()

if not AttachConsole(ATTACH_PARENT_PROCESS)
then AllocConsole;
更多信息请点击此处:

简短的回答(从这个链接)是:“你不能,但你可以试着假装。”这种方法的问题是,如果操作得当,它需要分发三个文件:1)命令行可执行文件,2)GUI可执行文件,3)包含程序相关核心的库文件。我更喜欢单一的可执行文件,最好的选择似乎是在头中有一个带有控制台位的GUI程序,如果需要作为GUI运行,它可以使用分离的控制台重新启动程序本身。就像提供的各种链接中的ildasm一样,我认为只有两个可执行文件是可行的。如果构建包含BPL的EXE,则无需分发任何“核心”文件-每个应用程序只需一个EXE。但是很明显,你是知道你的部署需求的人;我很高兴ildasm的回答很有帮助。你是对的,它可以用两个文件来完成,但是核心功能代码必须编译成两个版本,这对IMO来说是一种浪费。根据核心功能的大小,这也会显著增加部署的大小。Chee Wee的代码示例如下: