微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 不要在发行版中显示控制台窗口,而是在调试中显示

我想创建一个程序,将作为最终产品在后台运行.出于调试目的,我希望它显示一个控制台.

我了解到有一个ShowWindow(hWnd,SW_HIDE);功能,但如果我在“标准”主功能中使用它,控制台窗口仍会弹出片刻.我试图这样做(是的,我知道这很糟糕):

#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <tchar.h>


#define DEBUG
//#undef DEBUG

#ifndef DEBUG
#pragma comment(linker, "/SUBSYstem:WINDOWS")

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdshow)
{
    HWND hWnd = GetConsoleWindow();
    ShowWindow( hWnd, SW_HIDE );    

    while(1);

    return 0;
}
#else
#pragma comment(linker, "/SUBSYstem:CONSOLE")
    int main(int argc, int **argv)
    {
        HWND hWnd = GetConsoleWindow();

        while(1);

        return 0;
    }
#endif

在这里,我设法阻止窗体弹出,但我无法将参数传递给程序.

我相信有一个更好的解决方案.你能分享吗?

PS

我不想使用.NET.

解决方法:

这是问题第一部分的答案,“我设法防止窗口弹出窗口”,即如何在Visual C中为应用程序设置Windows子系统.

我将分别回答关于命令行参数的问题的第二部分.

// How to create a Windows GUI or console subsystem app with a standard `main`.

#ifndef _MSC_VER
#   error hey, this is Visual C++ specific source code!
#endif

// Better set this in the project settings, so that it's more easily configured.
#ifdef  NDEBUG
#   pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )
#else
#   pragma comment( linker, "/subsystem:console" )
#endif

#undef  UNICODE
#define UNICODE
#undef  NOMINMAX
#define NOMINAX
#undef  STRICT
#define STRICT
#include <windows.h>

int main()
{
    MessageBox( 0, L"Hi!", L"This is the app!", MB_SETFOREGROUND );
}

NDEBUG标准C宏旨在抑制标准断言的影响,因此不需要具有全局意义.但是,在实践中它具有全球意义.然而,与使用诸如DEBUG之类的Visual C宏相比,它提供了一些可移植性.

无论如何,为了更容易配置子系统,除非你想强制执行调试版本应该是控制台和发布版本应该是GUI,那么我建议在项目设置中而不是通过#pragma执行此操作(另请注意例如,g编译器不支持链接器编译指示,因此使用项目设置更具可移植性).

如果您愿意,可以通过编程方式检查子系统,而不仅仅是通过检查(即,而不是注意上述程序是否产生控制台):

// How to create a Windows GUI or console subsystem app with a standard `main`.

#ifndef _MSC_VER
#   error hey, this is Visual C++ specific source code!
#endif

// Better set this in the project settings, so that it's more easily configured.
#ifdef  NDEBUG
#   pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )
#else
#   pragma comment( linker, "/subsystem:console" )
#endif

#undef  UNICODE
#define UNICODE
#undef  NOMINMAX
#define NOMINAX
#undef  STRICT
#define STRICT
#include <windows.h>

#include <assert.h>         // assert
#include <string>           // std::wstring
#include <sstream>          // std::wostringstream
using namespace std;

template< class Type >
wstring stringFrom( Type const& v )
{
    wostringstream  stream;

    stream << v;
    return stream.str();
}

class S
{
private:
    wstring     s_;

public:
    template< class Type >
    S& operator<<( Type const& v )
    {
        s_ += stringFrom( v );
        return *this;
    }

    operator wstring const& () const { return s_; }
    operator wchar_t const* () const { return s_.c_str(); }
};

IMAGE_NT_HEADERS const& imageHeaderRef()
{
    HMODULE const                   hInstance   =
        GetModuleHandle( nullptr );

    IMAGE_DOS_HEADER const* const   pImageHeader    =
        reinterpret_cast< IMAGE_DOS_HEADER const* >( hInstance );
    assert( pImageHeader->e_magic == IMAGE_DOS_SIGNATURE );     // "MZ"

    IMAGE_NT_HEADERS const* const   pNTHeaders      = reinterpret_cast<IMAGE_NT_HEADERS const*>(
            reinterpret_cast< char const* >( pImageHeader ) + pImageHeader->e_lfanew
            );
    assert( pNTHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC );    // "PE"

    return *pNTHeaders;
}

int main()
{
    IMAGE_NT_HEADERS const& imageHeader = imageHeaderRef();
    WORD const              subsystem   = imageHeader.OptionalHeader.Subsystem;

    MessageBox(
        0,
        S() << L"Subsystem " << subsystem << L" "
            << (0?0
                : subsystem == IMAGE_SUBSYstem_WINDOWS_GUI?     L"GUI"
                : subsystem == IMAGE_SUBSYstem_WINDOWS_CUI?     L"Console"
                : L"Other"),
        L"Subsystem info:",
        MB_SETFOREGROUND );
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐