MSVC2008 c / c ++控制台应用程序生成新的控制台

时间:2013-01-17 12:40:10

标签: windows visual-studio-2008 console-application msvcrt

应用程序在哪里决定/导致生成新的控制台窗口(动态链接时)? 是否有一些我可能忽略的定义或编译指示或默认运行时dll中标准行为的某些变化?我不确定这些是正确的问题,请阅读下面的背景并耐心等待。我很高兴每个人都朝着正确的方向努力。

背景: 控制台应用程序(/ SUBSYSTEM:CONSOLE)在启动时会生成一个新的子控制台。使用相同来源和配置设置的其他应用程序不适用。唯一的区别(看似)是提供的第三方dll。由于新的子控制台,我无法再重定向输出(app.exe> dump.txt)。重定向对于此应用程序至关重要。

我在MS Visual Studio 2008上构建了那个c / c ++控制台应用程序。该应用程序动态链接到一个非常混乱的dll。整个Library-pack由一个第三方提供,作为发布版本,没有调试信息。 dll-pack包括msvcr90.dll(9.0.30729.1)msvcp90.dll(9.0.30729.1)和msvcr80.dll(8.0.50727.42)。

无论是什么原因,这看起来都非常全局,因为main()中的stdout或stderr的第一个fprintf转到新的控制台窗口,而不是启动应用程序的shell。

在我的第一次尝试中,我在Visual Studio 2005(我们使用直到最新版本的库包)和2010(由dll-provider推荐)上构建了应用程序。这些构建版本并没有产生控制台,但是当释放内存时可能会崩溃,这可能是在运行时的不同版本中分配的。使用Dependency Walker我可以找到" main"运行时dll与之链接。

PS:Afaik链接2个不同的运行时是危险的。但它比之前版本的dll-pack有所改进,其中包括71,80,90个运行时dll的r,c和m变体。

PPS:我之前主要是在linux上开发的,所以我本可以犯一些非常基本的错误。请提前为我的无知道歉。

更新1:

根据Anton Kovalenko的建议,我将越来越多的图书馆用掉。然后我删除了更多代码。最后我结束了:

#include <stdio.h>
#include <Windows.h>

int main(int _argc, char **_argv)
{
printf("application running ...\n");
fflush(stdout);
Sleep(2000);
exit(0);
}

配置属性&gt; c / c ++&gt;命令行:

/Od /Ob2 /D "_MBCS" /FD /EHsc /MD /Fo"a4input_interface_6.12_1.dir\Release\\" /Fd"a4input_interface_6.12_1.dir\Release\vc90.pdb" /W3 /nologo /c /TC /errorReport:prompt

配置属性&gt;链接器&gt;命令行:

/OUT:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe" /VERSION:0.0 /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

配置属性&gt; Manifest工具&gt;命令行

/nologo /outputresource:"..\..\..\build\win32_release\inputinterfaces\.inter_612_1_32.exe;#1"

我仍然遇到问题,即生成了一个shell,并且无法使用(即app.exe&gt; test.txt)重定向stdout。所以文本&#34;应用程序运行...&#34;没有打印在exe启动的同一个shell上。

我仍然无能为力,仍然感激每一个提示。

更新2:

我为命令行创建了一个批处理文件。如果我用它编译它,exe按预期工作。

cl.exe /Od /Ob2 /D "_MBCS" /FD /EHsc /MD /Fo"a4input_interface_6.12_1.dir\Release\\" /Fd"a4input_interface_6.12_1.dir\Release\vc90.pdb" /W3 /nologo /c /TC /errorReport:prompt main.c

link.exe /OUT:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe" /VERSION:0.0 /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib a4input_interface_6.12_1.dir\Release\main.obj

mt.exe /manifest a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest /nologo /outputresource:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe";#1"

因此,视觉工作室所做的事情并没有反映在它给出的命令行中。什么和为什么? 我仍然无能为力,仍然感激每一个提示。

解决方案: 为此可执行文件名配置了调试器。这就是我有这种行为的原因:

  • inter_612_2_32.exe没有子shell
  • intes_612_2_32.exe没有子shell
  • inter_612_1_32.exe产生子shell
  • intes_612_1_32.exe没有子shell

使用ProcessExplorer我发现,inter_612_1_32.exe是DbgHost.exe的子进程。不幸的是,我并没有遵循这条线索而忘记了它。

装载的Dlls实际上并不重要。问题是登记处的条目是: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Image File Execution Options \ inter_612_1_32.exe

我猜这个条目是由DebugDiag,Application Verifier或其他工具创建的,但在工具GUI中删除后却没有删除。

感谢所有想到它的人。

1 个答案:

答案 0 :(得分:1)

某些第三方dll可能正在调用FreeConsoleAllocConsole,这会产生您描述的效果。如果它在DllMain DLL_PROCESS_ATTACH内完成,则会在为您的项目依赖项的库输入main()之前完成。

似乎没有与您的构建环境相关的替代解释。

如果您创建的项目将使用LoadLibrary用于可疑dll而不是链接到其导入库,您可以了解更多信息:如果其中一些(或他们的依赖项)确实{{ {}}中的{}}和FreeConsole,会在AllocConsole来电期间发生。