GetVersionEx()已过时:我应该使用Environment.OSVersion吗?

5
我打算编写代码来确定操作系统是否为Windows XP,以便设置LOCALAPPDATA环境变量,解决一堆大量使用ExpandEnvironmentVariables()的代码问题。更有趣的是,一些代码是用VB6编写的,另一些代码则是用C# 4.0编写的。查看GetVersionEx()的文档,强烈建议从Windows 8.1开始将停用此API调用。但是没问题,我可以使用不同的API调用(VerifyVersionInfo / VerSetConditionMask)。对于VB6,没有选择-我必须使用API调用。然而,对于我的C#代码,似乎没有明显的等效物。有Environment.OSVersion,但这似乎是从不同来源组合而成的数据集,没有像VerifyVersionInfo() API那样微妙的内容。是否有这个API调用的包装器?如果没有,是否值得自己实现?[添加]或者,也许有人可能拥有关于Environment.OSVersion如何实现的内部信息?

1
你担心使用一个可能很快就会被弃用的函数,来确定一个操作系统,而这个操作系统也将很快不再受到支持? - Damien_The_Unbeliever
2
当人们为在过时的操作系统上运行的代码付出大量金钱时,它就是值得的。另一方面,我们不想编写明显在后来的操作系统上立即过时的代码。 "VerifyVersionInfo"可能比"GetVersionEx"更持久! - Mark Bertenshaw
1
在C#代码中,如果您正在寻找的是这样做,您可以使用P/Invoke调用与VB6代码调用相同的API。 - Jason Evans
1
如何实现Environment.OSVersion - Jim Mischel
1
通过下载 .NET Framework 源代码 - Jim Mischel
显示剩余3条评论
4个回答

3
首先,重要的是要理解"Deprecated"的含义。它意味着该函数要么存在严重问题(例如一些早期线程),要么已经被新功能所取代。在这种情况下,属于后者。
GetVersionEx函数的文档中有一个链接建议使用版本助手APIs
其中特别重要的是这个页面的一部分:
引用:

注意:这些API由versionhelper.h定义,该文件包含在Windows 8.1 Preview软件开发工具包(SDK)中。此文件可与其他Microsoft Visual Studio版本一起使用,以实现对Windows 8.1 Preview之前版本的相同功能。


2

使用GetVersionEx是完全可以的。如果有必要,它在很长一段时间内也不会从Windows中移除。微软一直以来都保持着与旧程序的兼容性。例如,即使是20年前被弃用的Win16 API,你仍然可以调用。


1
Api不会被删除,但它可能无法给出预期结果。在8.1版本中,它似乎决定欺骗我们。http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074%28v=vs.85%29.aspx - ColdCat
@ColdCat 这符合提问者的期望结果。我是在XP系统上吗?8.1的细微差别并不是问题。 - David Heffernan
@DavidHeffernan - 确实,看起来它只会在以后的版本中停用,但我担心的是文本说它可能在Win 8.1之后“不可用”。到目前为止,除了VB之外,我同意你对MS在向后兼容方面一直做得非常好的看法。但这是一个我认真对待的警告。 - Mark Bertenshaw
当他们拿出来时,95% 的程序将无法启动。这永远不会发生。 - David Heffernan
微软并不总是保持对“旧程序的兼容性”。Windows帮助文件在32位版本的Windows中得到支持,但在Windows 10中不再支持。 - Sam Hobbs

0

我在原来的问题中添加了一个额外的部分,询问是否有人了解Environment.OSVersion对象的内部。在这个网站上搜索了几分钟后,我找到了这个问题:

如何使用.NET检测Windows 64位平台?

现在,“官方”答案本身对我来说并不是很有趣,但是Phil Devaney的第二个答案提到了一个名为“Reflector”的应用程序,似乎可以做一些魔术。所以我下载了它,然后惊讶地发现,我能够反编译Environment.OSVersion对象构造函数的P-Code:

Win32Native.OSVERSIONINFO osVer = new Win32Native.OSVERSIONINFO();
            if (!GetVersion(osVer))
            {
                throw new InvalidOperationException(GetResourceString("InvalidOperation_GetVersion"));
            }

所以,这就是全部:Environment.OSVersion 内部使用 GetVersion 函数,该函数在未来可能无法正常工作。看起来 VerifyVersionInfo 和 P/Invoke 是解决此问题的方法。

现在我必须在另一台机器上下载 .NET 4.5 并查看该实现是否有任何不同。


如果你想检测XP,GetVersion和GetVersionEx都可以。 - David Heffernan
嗯,我希望如此。但我不喜欢微软在Win 8.1+的实际功能方面相当模糊的评论。 - Mark Bertenshaw
MSDN充斥着像那样毫无意义的样板文件。显然他们不能取消这些函数。破坏每一个.NET应用程序?不可能发生。 - David Heffernan
@DavidHeffernan - 在 VB6 的惨败之后,你能确定吗? :-) 好吧,我认为这里的答案不是太在意这个问题。但是未来,我不会再使用这些 API。 - Mark Bertenshaw
VB6仍然有效。 VB6应用程序仍可在Windows 8.1上运行。我想知道IsWindows8Point1OrGreater在Win 2k上是如何实现的。我敢打赌里面有一个对GetVersionEx的调用!请注意,所有这些最近的API在Win2k上都有最小支持版本。但许多其他API被列为最小级别XP,而实际上它们存在于NT4上。微软迫切希望您不要直接调用GetVersionEx,因此它试图吓唬您。但是从C#中,您无法包含版本助手标头。 - David Heffernan
显示剩余6条评论

0

马克) 也许这对你有趣 GetVersionExEx 但请注意,VerifyVersionInfo 在 Windows 操作系统的后续版本中也可能被弃用(正如 msdn 社交论坛中的 ms 技术人员所述)。

此代码依赖于 VerifyVersionInfo 并提供相同的使用体验。 代码中还使用了二分算法。

版本助手 API 用于请求 API,而此代码用于精确值。

谢谢)


请注意,“VersionHelpers.h”只是使用“VerifyVersionInfo”。 - Chuck Walbourn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接