3

今天是个好日子,

我最近升级到 Visual Studio 2012,我喜欢改进的 C++11 支持和深色主题。但是,我正在尝试编写一个在 Windows XP 及更高版本上运行的程序,但遇到了一些奇怪的问题。

第一次尝试在 XP 虚拟机上运行我的程序时,我收到“这不是有效的 Win32 程序”错误消息。一些谷歌搜索显示我需要将更新 1 应用到 VS 才能以 Windows XP 为目标。我搜索了它,但找到了更新 2。我应用了它并将平台工具集设置为 v110_xp,然后重新编译了我的程序并尝试再次运行它。这次我没有收到错误消息,但是在尝试启动程序时,我听到了 XP 的错误声音(与您在使用 MB_ICONERROR 调用 MessageBox 时听到的声音相同),然后没有其他任何反应。在 Windows XP 的事件查看器中也没有提及任何内容。

我想也许更新 2 搞砸了其他东西,所以我完全卸载了 VS2012,包括它留下的所有 MS SQL 废话,重新安装它,只应用更新 1。再次用 XP 工具集编译我的代码,但同样的事情发生了。尝试启动我的程序时发出错误声音但没有消息。

更多谷歌搜索显示我必须将 PSAPI_VERSION 定义为 1 以针对 Windows 7 之前的 Process API 版本,所以我这样做了,但问题仍然存在。

我开始认为我的代码有问题,所以我制作了最基本的 Hello World 程序,但它仍然有同样的问题。所以我现在没有主意了。

这是我用来编译 Hello World 程序的代码:

主.cpp:

#include "winapi.h"

int WINAPI wWinMain(HINSTANCE inst, HINSTANCE prev, wchar_t *cmdline, int show)
{
    MessageBox(HWND_DESKTOP, L"Let's hope this works in Windows XP...", L"Testing 1... 2... 3...", MB_ICONERROR);

    return 0;
}

winapi.h:

#ifndef WINAPI_H_INCLUDED
#define WINAPI_H_INCLUDED

#ifdef _WIN32

// WINDOWS DEFINES /////////////////////////////////////////////////////////////

// If this is not a console program, let the linker include a manifest to
// enable visual styles.
#ifndef _CONSOLE
# pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif // _CONSOLE

// Shorten compile time by only including the most basic Windows definitions.
#define WIN32_LEAN_AND_MEAN

#define NOGDICAPMASKS       // CC_*, LC_*, PC_*, CP_*, TC_*, RC_
#define NOSYSMETRICS        // SM_*
#define NOICONS             // IDI_*
#define NOKEYSTATES         // MK_*
#define NOSYSCOMMANDS       // SC_*
#define NORASTEROPS         // Binary and Tertiary raster ops
#define OEMRESOURCE         // OEM Resource values (OCR_NORMAL and related constants)
#define NOATOM              // Atom Manager routines
#define NOCLIPBOARD         // Clipboard routines
#define NODRAWTEXT          // DrawText() and DT_*
#define NOKERNEL            // All KERNEL defines and routines
#define NONLS               // All NLS defines and routines
#define NOMEMMGR            // GMEM_*, LMEM_*, GHND, LHND, associated routines
#define NOMETAFILE          // typedef METAFILEPICT
#define NOMINMAX            // Macros min(a,b) and max(a,b)
#define NOOPENFILE          // OpenFile(), OemToAnsi, AnsiToOem, and OF_*
#define NOSERVICE           // All Service Controller routines, SERVICE_ equates, etc.
#define NOSOUND             // Sound driver routines
#define NOTEXTMETRIC        // typedef TEXTMETRIC and associated routines
#define NOWH                // SetWindowsHook and WH_*
#define NOCOMM              // COMM driver routines
#define NOKANJI             // Kanji support stuff.
#define NOHELP              // Help engine interface.
#define NOPROFILER          // Profiler interface.
#define NODEFERWINDOWPOS    // DeferWindowPos routines
#define NOMCX               // Modem Configuration Extensions

// Enable strict typechecking on Windows types like HANDLE, HWND and HDC.
#define STRICT

// Enable targetting of pre-Win7 Process API functions when compiling on
// VS2012 or higher.
#if _MSC_VER >= 1700
# define PSAPI_VERSION 1
#endif // _MSC_VER

// Specify the minimum versions of Windows and Internet Explorer supported
// by this code.
#define NTDDI_VERSION       NTDDI_WIN2K
#define _WIN32_WINNT        _WIN32_WINNT_WIN2K
#define WINVER              _WIN32_WINNT_WIN2K
#define _WIN32_IE           _WIN32_IE_IE50

// WINDOWS INCLUDES ////////////////////////////////////////////////////////////

#include <Windows.h>

#else // _WIN32
// OTHER OS ////////////////////////////////////////////////////////////////////
#error This software has been written with Visual C++ in mind.
////////////////////////////////////////////////////////////////////////////////

#endif // _WIN32

#endif // WINAPI_H_INCLUDED

正如我所说,我通过以 v110_xp 工具集为目标来编译此代码,并使用项目设置窗口将 CRT 与 /MD 静态链接。我将它编译为 x86 代码,它在我的 Windows 7 x64 机器上运行良好。在生成的可执行文件上运行 dumpbin 确认它已编译为 32 位代码,适用于操作系统版本 5.01 和 Windows GUI 子系统。

为了使这尽可能完整,这里是可执行文件的导入:

D:\Projects\xptest\Release>dumpbin /imports xptest.exe
Microsoft (R) COFF/PE Dumper Version 11.00.51106.1
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file xptest.exe

File Type: EXECUTABLE IMAGE

  Section contains the following imports:

    USER32.dll
                4070FC Import Address Table
                40B19C Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                  215 MessageBoxW

    KERNEL32.dll
                407000 Import Address Table
                40B0A0 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                  218 GetModuleHandleW
                   8F CreateFileW
                  187 GetCommandLineW
                  300 IsDebuggerPresent
                  304 IsProcessorFeaturePresent
                  202 GetLastError
                  473 SetLastError
                  2EF InterlockedIncrement
                  2EB InterlockedDecrement
                  1C5 GetCurrentThreadId
                   EA EncodePointer
                   CA DecodePointer
                  119 ExitProcess
                  217 GetModuleHandleExW
                  245 GetProcAddress
                  367 MultiByteToWideChar
                  264 GetStdHandle
                  525 WriteFile
                  214 GetModuleFileNameW
                  24A GetProcessHeap
                  1F3 GetFileType
                  2E3 InitializeCriticalSectionAndSpinCount
                   D1 DeleteCriticalSection
                  263 GetStartupInfoW
                  3A7 QueryPerformanceCounter
                  1C1 GetCurrentProcessId
                  279 GetSystemTimeAsFileTime
                  1DA GetEnvironmentStringsW
                  161 FreeEnvironmentStringsW
                  4D3 UnhandledExceptionFilter
                  4A5 SetUnhandledExceptionFilter
                  1C0 GetCurrentProcess
                  4C0 TerminateProcess
                  4C5 TlsAlloc
                  4C7 TlsGetValue
                  4C8 TlsSetValue
                  4C6 TlsFree
                   EE EnterCriticalSection
                  339 LeaveCriticalSection
                  2CF HeapFree
                  4B2 Sleep
                  30A IsValidCodePage
                  168 GetACP
                  237 GetOEMCP
                  172 GetCPInfo
                  33E LoadLibraryExW
                  38A OutputDebugStringW
                  33F LoadLibraryW
                  418 RtlUnwind
                  2CB HeapAlloc
                  2D2 HeapReAlloc
                  511 WideCharToMultiByte
                  269 GetStringTypeW
                  2D4 HeapSize
                  32D LCMapStringW
                  157 FlushFileBuffers
                  19A GetConsoleCP
                  1AC GetConsoleMode
                  487 SetStdHandle
                  467 SetFilePointerEx
                  524 WriteConsoleW
                   52 CloseHandle

  Summary

        3000 .data
        5000 .rdata
        3000 .reloc
        1000 .rsrc
        6000 .text

正如我所说,我在这里完全没有想法......我已经尝试了我能想到的一切。任何有用的评论将不胜感激!

问候,

杰拉德

4

1 回答 1

3

在您使用#include任何 Windows 标头之前,请确保您具有以下内容#define

#ifndef WINVER
#define WINVER 0x0501
#endif

#ifndef _WIN32_WINNT   // Specifies that the minimum required platform is Windows XP.
#define _WIN32_WINNT 0x0501
#endif

如果您想查看其他替代方案,这一切都在 MSDN 上进行了解释。

于 2013-05-11T14:48:14.447 回答