10

我必须首先说我是一个编程菜鸟。我不了解 IDE 的所有编译器选项或细微差别,不是很远。但我正在努力自学更多关于本机编程语言的知识。(我对 C# 很满意,但我发现这比 C 容易得多。

今天,我用C写了这个小程序。它是一个控制台/命令行程序。我使用了 Visual Studio 2012,我的开发机器在 Windows 7 和 8、64 位之间切换。首先,我所做的是创建一个新的 VC++ 项目,然后我选择了一个空白项目。然后我创建了一个新的 app.c 文件。当您在 Windows 资源管理器中浏览文件属性时,我还创建了一个 *.rc 文件来为可执行文件提供一些额外的属性,例如“文件版本”和“公司名称”。然后我转到项目的属性,选择配置属性 -> C/C++ -> 代码生成并将运行时库更改为“多线程 (/MT),这样我就不必分发 msvcr100.dll 文件连同我的可执行文件。

在 app.c 文件中,我放置了以下代码:

#include <stdio.h>
#include <string.h>
#include <Windows.h>
#include <WtsApi32.h>
#pragma comment(lib, "WtsApi32.lib")

void main(int argc, char *argv[])
{
    char *helpMsg = "blah";
    char *hostName, *connState = "";
    char *addrFamily = "";
    HANDLE hHost = NULL;

    ...stuff and so forth and so on...
}

然后我构建/编译了程序,可执行文件在 Windows 7、8、Server 2008R2、Server 2012 上运行良好,所有 64 位。但是当我尝试在 Server 2003 上运行程序时(我猜也是 WinXP 等),我看到了 Windows 对话框:

“Foo.exe 不是有效的 Win32 应用程序。”

所以我的问题是,我是否缺少一些明显/简单的东西可以让这个可执行文件也可以在我缺少的早期 XP/2003/32bit 平台上工作?我不相信我在我的程序中使用了任何 64 位专有功能。但我认为,因为我确实选择了“空白项目”而不是“Win32 控制台应用程序”,所以我可能会遗漏一些设置。

编辑:这是针对我的 exe 运行时的 dumpbin.exe /headers 输出:

Microsoft (R) COFF/PE Dumper Version 11.00.50727.1
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\users\me\Release\foo.exe

PE signature found

File Type: EXECUTABLE IMAGE

FILE HEADER VALUES
         14C machine (x86)
           5 number of sections
    50F604BC time date stamp Tue Jan 15 19:39:08 2013
           0 file pointer to symbol table
           0 number of symbols
          E0 size of optional header
         102 characteristics
               Executable
               32 bit word machine

OPTIONAL HEADER VALUES
         10B magic # (PE32)
       11.00 linker version
        7800 size of code
        A200 size of initialized data
           0 size of uninitialized data
        16A7 entry point (004016A7) _mainCRTStartup
        1000 base of code
        9000 base of data
      400000 image base (00400000 to 00414FFF)
        1000 section alignment
         200 file alignment
        6.00 operating system version
        0.00 image version
        6.00 subsystem version
           0 Win32 version
       15000 size of image
         400 size of headers
           0 checksum
           3 subsystem (Windows CUI)
        8140 DLL characteristics
               Dynamic base
               NX compatible
               Terminal Server Aware
      100000 size of stack reserve
        1000 size of stack commit
      100000 size of heap reserve
        1000 size of heap commit
           0 loader flags
          10 number of directories
           0 [       0] RVA [size] of Export Directory
        D374 [      3C] RVA [size] of Import Directory
       11000 [     538] RVA [size] of Resource Directory
           0 [       0] RVA [size] of Exception Directory
           0 [       0] RVA [size] of Certificates Directory
       12000 [     C04] RVA [size] of Base Relocation Directory
        9160 [      38] RVA [size] of Debug Directory
           0 [       0] RVA [size] of Architecture Directory
           0 [       0] RVA [size] of Global Pointer Directory
           0 [       0] RVA [size] of Thread Storage Directory
        CF98 [      40] RVA [size] of Load Configuration Directory
           0 [       0] RVA [size] of Bound Import Directory
        9000 [     118] RVA [size] of Import Address Table Directory
           0 [       0] RVA [size] of Delay Import Directory
           0 [       0] RVA [size] of COM Descriptor Directory
           0 [       0] RVA [size] of Reserved Directory


SECTION HEADER #1
.text name
7670 virtual size
1000 virtual address (00401000 to 0040866F)
7800 size of raw data
 400 file pointer to raw data (00000400 to 00007BFF)
   0 file pointer to relocation table
   0 file pointer to line numbers
   0 number of relocations
   0 number of line numbers
60000020 flags
     Code
     Execute Read

SECTION HEADER #2
.rdata name
49E2 virtual size
9000 virtual address (00409000 to 0040D9E1)
4A00 size of raw data
7C00 file pointer to raw data (00007C00 to 0000C5FF)
   0 file pointer to relocation table
   0 file pointer to line numbers
   0 number of relocations
   0 number of line numbers
40000040 flags
     Initialized Data
     Read Only

Debug Directories

    Time Type       Size      RVA  Pointer
-------- ------ -------- -------- --------
50F604BC cv           61 0000CFE0     BBE0    Format: RSDS, {582D0FF2-59C1-4633-AF2A-E4A4AD6BFA2C}, 1, C:\Users\me\Release\users.pdb
50F604BC feat         10 0000D044     BC44    Counts: Pre-VC++ 11.00=0, C/C++=116, /GS=116, /sdl=0

SECTION HEADER #3
.data name
2C04 virtual size
E000 virtual address (0040E000 to 00410C03)
 E00 size of raw data
C600 file pointer to raw data (0000C600 to 0000D3FF)
   0 file pointer to relocation table
   0 file pointer to line numbers
   0 number of relocations
   0 number of line numbers
C0000040 flags
     Initialized Data
     Read Write

SECTION HEADER #4
.rsrc name
 538 virtual size
11000 virtual address (00411000 to 00411537)
 600 size of raw data
D400 file pointer to raw data (0000D400 to 0000D9FF)
   0 file pointer to relocation table
   0 file pointer to line numbers
   0 number of relocations
   0 number of line numbers
 40000040 flags
     Initialized Data
     Read Only

 SECTION HEADER #5
.reloc name
235C virtual size
12000 virtual address (00412000 to 0041435B)
2400 size of raw data
DA00 file pointer to raw data (0000DA00 to 0000FDFF)
   0 file pointer to relocation table
   0 file pointer to line numbers
   0 number of relocations
   0 number of line numbers
 42000040 flags
     Initialized Data
     Discardable
     Read Only

Summary

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

我也试过去项目属性 - >链接器 - >系统:最低要求版本并将其更改为 5.00 和 1.00 或其他任何内容,但它没有效果。dumpbin.exe 仍将操作系统版本报告为 6.00。我什至在 exe 上使用了 editbin.exe /version 5.00 并且没有报告任何错误……但 dumpbin.exe 仍然报告操作系统版本为 6.00。

4

3 回答 3

7

VS2012 最初发布时不支持 XP/2003。更新后的 CRT 和运行时支持库使用了太多在这些操作系统上不可用的 Windows api 函数。委婉地说,这在其客户中引起了不小的轰动,他们重新设计了库以动态绑定到这些功能,并沿着它们缺少的功能蹒跚而行。这在Update 1中可用,您需要使用 Project + Properties, General, Platform Toolset = v110_xp来构建使用这些库的程序。

请注意它如何更改链接器设置,重要的是,链接器 > 系统 > 最低要求版本 =“5.01”。这确保了可执行文件被标记为与 XP 子系统版本兼容。您还将针对 SDK 版本 7.1 进行构建,这是最后一个仍与 XP 兼容的版本。

当您使用默认工具集 (v110) 时,您的目标是子系统 6.00 和 SDK 版本 8。版本 6.00 是最后一个主要内核版本,从 Vista 开始。

简要概述了用于让您(非常粗略地)了解 XP 版本中缺少的新 api 函数:

  • FlsAlloc, FlsFree, FlsGetValue, FlsSetValue : 安全的线程本地存储
  • InitializeCriticalSectionEx、CreateSemaphoreEx:安全
  • SetThreadStackGuarantee:稳定性
  • CreateThreadPoolTimer, SetThreadPoolTimer, WaitForThreadPoolTimerCallbacks, CloseThreadPoolTimer : 更便宜的计时器
  • CreateThreadPoolWait, SetThreadPoolWait, CloseThreadPoolWait : 更便宜的等待?
  • FlushProcessWriteBuffers、GetCurrentProcessorNumber、GetLogicalProcessorInformation:线程
  • FreeLibraryWhenCallbackReturns:稳定性?
  • CreateSymbolicLink : 功能
  • InitOnceExecuteOnce :未知
  • SetDefaultDllDirectories:未知
  • EnumLocalesEx、CompareStringEx、GetDateFormatEx、GetLocalInfoEx、GetTimeFormatEx、GetUserDefaultLocaleName、IsValidLocaleName、LCMapStringEx:更好的语言环境支持
于 2013-01-16T01:34:28.357 回答
4

我自己想通了。(但感谢 Hans 引导我朝着正确的方向前进。)出于某种原因,即使使用 Update 1,甚至在将我的工具集设置为 v110_xp在链接器选项中将所需的最低版本设置为 5.01 之后,结果dumpbin app.exe /headers仍然报告最低操作系统版本为 6.0。

所以我只是跑了

editbin.exe app.exe /SUBSYSTEM:CONSOLE,5.01 /OSVERSION:5.1

现在可执行文件在旧操作系统上运行良好。我认为 Visual Studio 中的某个地方可能仍然存在一些错误。

于 2013-01-16T15:38:05.137 回答
2

MSVC 团队博客说,当通过 v110_xp 平台工具集从命令行使用 MSBuild 或 DEVENV 时,无需进行其他更改。此信息不正确/不完整。/SUBSYSTEM 链接器参数和关联的“最低要求版本”也必须适当设置。

/ENTRY的 MSDN 文档指出,如果未指定 /SUBSYSTEM 参数,则自动确定 SUBSYSTEM 和 ENTRY POINT。我的预感是,当这种情况发生时,SUBSYSTEM 的“最低要求版本”参数也会被自动覆盖。

v110_xp 工具集自动指定 SUBSYSTEM 的 MRV(“5.1”(WindowsXP)),但不指定 SUBSYSTEM。因此,MRV 将被覆盖,例如,被“6.0”的链接器覆盖。运行该应用程序将导致 WindowsXP 显示错误消息,指出该应用程序“不是有效的 Win32 应用程序”。

于 2013-04-18T16:42:59.200 回答