用VS2012编写的C程序可以使用Win7/8/2008R2/2012工作,但不能使用2003/XP/32bit?

用VS2012编写的C程序可以使用Win7/8/2008R2/2012工作,但不能使用2003/XP/32bit?,c,visual-c++,C,Visual C++,首先,我得说我是个编程高手。我不理解IDE的所有编译器选项或细微差别,一点也不理解。但我正在努力教自己更多关于本地编程语言的知识。(我对C#很在行,但我发现这比C要容易得多。) 今天,我用C编写了这个小程序。它是一个控制台/命令行程序。我使用Visual Studio 2012,我的开发机器在Windows 7和8之间交替运行,64位。首先,我创建了一个新的VC++项目,然后选择了一个空白项目。然后我创建了一个新的app.c文件。我还创建了一个*.rc文件,以便在Windows资源管理器中浏览文

首先,我得说我是个编程高手。我不理解IDE的所有编译器选项或细微差别,一点也不理解。但我正在努力教自己更多关于本地编程语言的知识。(我对C#很在行,但我发现这比C要容易得多。)

今天,我用C编写了这个小程序。它是一个控制台/命令行程序。我使用Visual Studio 2012,我的开发机器在Windows 7和8之间交替运行,64位。首先,我创建了一个新的VC++项目,然后选择了一个空白项目。然后我创建了一个新的app.c文件。我还创建了一个*.rc文件,以便在Windows资源管理器中浏览文件属性时为可执行文件提供一些额外属性,如“文件版本”和“公司名称”。然后我转到项目的属性,选择Configuration properties->C/C++->Code Generation,并将运行时库更改为“多线程(/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...
}

我也尝试过进入Project Properties->Linker->System:Minimum Required Version并将其更改为5.00和1.00或其他版本,但没有任何效果。dumpbin.exe仍然报告操作系统版本为6.00。我甚至在exe上使用了editbin.exe/Version 5.00,并且没有报告任何错误……但dumpbin.exe仍然报告操作系统版本为6.00版本。

VS2012最初不支持XP/2003。更新的CRT和运行时支持库使用了太多在这些操作系统上不可用的Windows api函数。这在其客户中引起了相当大的轰动,说得委婉一点,他们重新设计了库以动态绑定到这些函数这是在中提供的,您需要使用Project+Properties,General来构建使用这些库的程序

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

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

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

  • FlsAlloc、FlsFree、FlsGetValue、FlsSetValue:安全线程本地存储
  • 初始化CriticalSectionEx,CreateSamphoreEx:safety
  • 第二,保证:稳定性
  • CreateThreadPoolTimer、SetThreadPoolTimer、WaitForThreadPoolTimerCallbacks、CloseThreadPoolTimer:更便宜的计时器
  • CreateThreadPoolWait、SetThreadPoolWait、CloseThreadPoolWait:更便宜的等待
  • FlushProcessWriteBuffers、GetCurrentProcessorNumber、GetLogicalProcessor信息:线程
  • FreeLibraryWhenCallbackReturns:稳定性
  • createsymbolicink:功能
  • initonceExecutionce:未知
  • SetDefaultDllDirectory:未知
  • EnumLocalesEx、CompareStringEx、GetDateFormatEx、GetLocalInfo、GetTimeFormatEx、GetUserDefaultLocaleName、IsValidLocaleName、LCMapStringEx:更好的语言环境支持
    • 我自己想出来了。(但谢谢汉斯给我指引了正确的方向。)出于某种原因,即使使用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中的某些地方可能仍然有一点错误。

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

      的MSDN文档说明,如果未指定/SUBSYSTEM参数,则子系统和入口点将自动确定。我的直觉是,发生这种情况时,子系统的“最低要求版本”参数也会自动覆盖


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

      如果将应用程序构建为32位,它将在任何地方运行。64位应用程序无法在32位计算机上运行。我正在构建32位应用程序。例如,当我在任务管理器中查看正在运行的应用程序时,我看到“app.exe*32”,我还尝试将我的平台工具集更改为“Windows XP(v100_XP)”,但没有成功。感谢您的及时回复。但是,我有VS2012更新1补丁,我已经将平台工具集更改为v110_xp。。。但这没用。嗯,这是很难诊断的。您正在尝试在32位操作系统上运行64位程序吗?使用dumpbin.exe/headers进行双重检查。像“特征+机器”和“操作系统版本”该死的,我讨厌当我有无法解决的问题时。我已将dumpbin/headers的完整输出添加到我的原始帖子中。操作系统版本错误,6.0是Vista。链接器+系统+最小值=“5.01”最小版本已设置为5.01。我只是将它设置为1.00,然后重新构建。这没用。谢谢,你刚刚救了我一命:)我在VS2013和th中也遇到过这个问题
      editbin.exe app.exe /SUBSYSTEM:CONSOLE,5.01 /OSVERSION:5.1