【问题标题】:Do Windows Applications usually have a console for StdIn, StdOut and StdErrWindows 应用程序是否通常有一个用于 StdIn、StdOut 和 StdErr 的控制台
【发布时间】:2021-07-05 10:37:54
【问题描述】:

我在使用 Pascal/FPC/Lazarus 时遇到了以下问题,但我认为它对所有 Windows .exe 文件都是通用的,无论它们是使用什么 IDE/编译器创建的:

我创建了一个 Windows GUI 应用程序,并希望在一个简单的文本控制台中显示一些调试信息。通常在 Pascal 控制台应用程序中,Write 和 WriteLn 用于写入控制台/StdOut,但在项目配置中没有其他措施,这会崩溃,因为在 GUI exe(至少如果使用 Lazarus 创建)中不存在控制台窗口,我获得“文件未打开”异常。

在 Lazarus 中有多种方法(主要是在构建过程中控制 -WG 开关)来获得附加的控制台“write /writeln”可以写入文本,这不是问题。我的问题是,对控制台设备(StdIn、StdOut、StdErr)的支持是否是 Windows 功能,它是 Windows 运行时的一部分,可能由嵌入在 exe 中的一些元数据控制,而这些元数据又由这个 -WG 开关控制,或者它是否是由特定开发环境添加的运行时环境的功能,在这种情况下是由 Lazarus IDE 或底层 FPC 编译器附带的运行时。

谢谢!

【问题讨论】:

  • 这取决于可执行目标的子系统,控制台子系统或 gui 子系统。通常显示窗口 UI 的可执行文件以后者为目标,并且没有标准输入、标准输出、标准错误。
  • FPC 中有一个-WG 编译器开关,它在创建GUI 应用程序时控制是否创建附加的带有stdOut 的附加控制台,这是一种显示调试/跟踪信息的便捷方式。我想知道这是适用于所有 WIndows GUI 应用程序的 Windows 功能,还是仅适用于使用 Lazarus/FPC 创建的 Windows 应用程序的 FPC 好东西。
  • 这不是我阅读文档时 -WG 所做的。这指定可执行文件将针对 GUI 子系统。 Windows 在这方面与 *nix 有很大不同。如果你想产生调试信息,那么你最好使用日志库。
  • 令人困惑!这是否意味着我的目标是“不同的子系统”?情况似乎并非如此,因为我的 GUI 在有和没有 -WG 的情况下都能正常运行。如果我删除 -WG,我只会得到一个额外的文本控制台。
  • 正如@Marco 所说,Lazarus 正在为您调用AllocConsole,这是控制台的来源。通常,GUI 应用程序不应该这样做。使用日志库。

标签: windows windows-runtime freepascal lazarus


【解决方案1】:

是的,控制台通常不用于 Windows GUI 应用程序,但您可以使用 allocconsole 手动实例化一些控制台。 Lazarus 的早期版本就是这样做的。

正如大卫所说,通常在 Windows 上使用 Outputdebugstring() 或日志库。


技术细节:afaik 所有 Windows 进程(控制台也是如此)必须主动激活控制台,该任务通常由运行时完成。 -WG 开关通过将特殊的 IsConsole 布尔变量设置为 false 来抑制这种情况。

控制台 io 初始化在 rtl/win/syswin.inc 过程 SysInitStdIO 中的第 515 行附近。

在那里您可以看到,如果不是 IsConsole,则会生成一个虚拟文件描述 (assignerror),并且错误会被重定向到消息框(并且可能会被 GUI 用户忽略)。

【讨论】:

  • 感谢您的贡献,但它与我的问题不太相符。我曾一度认为 GUI 应用程序和控制台应用程序是专有选项,您可以在创建应用程序时将应用程序定位到其中一个。当我最近了解到这个 -WG 开关时,我感到很困惑,如果我选择创建 GUI 应用程序,默认情况下会设置该开关。如果我删除它,我会得到 GUI 控制台。如果我将 {$Apptype Console} 添加到 GUI 应用程序,也会发生同样的情况。我预计会丢失 GUI,但没有,相反,除了 GUI,我还得到了一个完美运行的附加控制台。
  • 我在帖子中添加了一些细节。您描述的是旧情况,但后来更改为更好地符合一般 Windows GUI 程序,并在发生某些情况时弹出窗口。一些程序还分配带有参数的虚拟描述符以将其全部记录到文件中。
  • @MarcovandeVoort 在 Windows 上,我不需要运行时“激活”控制台。如果 PE 文件表明可执行文件以控制台子系统为目标,则加载程序确保存在控制台。通过附加到父进程的控制台,或制作一个新的控制台。
  • 那么也许我们的方法是使用一个 RTL 的解决方法。现在我们有一个自己的链接器,也许应该重新考虑一下。
  • 所以,为了确保我把你所有有用的答案放在一起——我原来的问题的正确答案是,这种双窗口行为(1 个 GUI,1 个控制台)是Lazarus/FPC 运行时,而不是在 Windows 下运行的所有程序共有的东西?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 1970-01-01
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多