传统 API 的虚拟化并与更现代的 API 共存?
我并不是说这个问题是一个火焰诱饵,但我将使用 Microsoft 及其 win32 API 作为遗留 API 的示例。
现在我想知道的是,微软花费了大量的金钱和精力来维护他们的遗留 API,包括保持 API 功能不变所需的所有“故障/错误/解决方法”。现在我知道,在 Windows 7 中,他们为客户提供了一种在“Windows XP”VM 中运行应用程序的方法,这将是他们开始清理 win32 API 的一种方法,因为他们可以推送所有将应用程序加载到“Windows XP”VM 中。
所以现在我想知道的是,是否可以虚拟化旧版 API,以便客户/程序仍然可以访问和使用它,同时能够利用新版本/API?因为据我了解,如果应用程序在“Windows XP”VM 中运行,它将无法访问 Windows 7 的任何较新的 API/功能。
I don't mean for this question to be a flame bait but I'll be using Microsoft and their win32 API as a example of a legacy API.
Now what I am wondering here is Microsoft is spending a lots of their money and energy in maintaining their legacy API, including all of the "glitches/bugs/workaround" that are needed to keep the API functioning the same. Now I'm aware that in Windows 7 they are providing a way for the customer to run their application in a "Windows XP" VM which would be one such way for them to start cleaning up their win32 API because they could then push all of the application into the "Windows XP" VM.
So now what I am wondering is, is it possible to virtualization a legacy API in such way that an customer/program can still access and use it, yet at the same time be able to take advantage of the newer version/API? Because as far as I understand it, if the application is ran in the "Windows XP" VM, it won't be able to access any of the newer API/feature of Windows 7.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当这个问题出现时,让我感到困惑的是,自从 NT 在 90 年代中期问世以来,Windows 就一直在这样做。这就是 NT 运行 DOS 和 Win16 程序的方式,并且一直如此。 NTVDM 虚拟化层在 Win32 下运行 16 位应用程序,几乎不需要核心操作系统的特殊支持。这只是一个例子 - 另一个是 WINE,据我了解,它在 API 集之上运行 Windows 应用程序非常合理,这与 Windows 非常不同。所以这绝对是可能的。
更相关的问题是微软为什么会考虑它。为了让你认为这是必要的,你必须考虑两件事。 1) 有更好的东西可以替代 win32 API,2) 维护 Win32 API 是一种负担。
这两点都是值得怀疑的。在内核职责方面,例如访问硬件、同步以及执行线程、进程和内存,Win32 API 做得非常好,并且最终非常接近内核真正所做的事情。如果您认为有更好的 API,那么那一定意味着也有更好的内核。我个人认为NT现在不需要更换。对于图形和窗口,诚然,gdi32 有点过时了。但微软通过同时构建 WPF 解决了这个问题。这就带来了负担问题。好吧,当然有两个 API 需要维护,但如果您在 WPF 之上虚拟化 GDI,您仍然必须维护这两个 API,因此没有任何好处。并行运行两者的优点是 GDI 已经存在并且已经经过测试。您所要做的就是修复偶尔出现的错误,而新的虚拟化层则必须重新编写和测试,这需要时间来使 WPF 变得更好。
就保持向后兼容性而言,这并不像听起来那么麻烦。这主要是一个测试问题 - 你必须测试 API 行为不会改变,但同样 - 这些测试已经被编写,所以它实际上并不是任何额外的工作。
那么,用问题来回答问题,他们为什么要费心呢?
The thing that puzzles me about this question when it comes up is that Windows has been doing this since NT came out in the mid nineties. This is how NT runs DOS and Win16 programs, and how it always has. The NTVDM virtualization layer runs 16-bit apps under Win32 with very little special support from the core OS. This is just one example - another is WINE, which as I understand it does a pretty reasonabl job of running windows apps on top of an API set which is very different from that of windows. So it is definitely possible.
The more pertinent question would be why Microsoft would consider it. In order for you to think it is necessary you have to think two things. 1) There is something better to replace the win32 API with and 2) Maintaining the Win32 API is a burden.
Both of these are questionable. In the case of kernel duties, such as accessing hardware and synchronizing and doing threads and processes and memory the Win32 API does a pretty good job, and is ultimately quite close to what the kernel really does. If you think there is a better API then that must mean there is also a better kernel. I personally don't think that NT needs replacing right now. For graphics and windowing, admitedly gdi32 is a bit long in the tooth. But Microsoft solved that problem by building WPF right alongside it. This then brings in the burden question. Well, sure there are two APIs to maintain, but if you virtualized GDI on top of WPF you'd still have to maintain both anyway so there is no benefit there. The advantage of running both in parallel is that GDI already exists and is already tested. All you have to do is to fix the occasional bug, whereas a new virtualization layer would have to be written and tested all over again, which takes time away from making WPF better.
In terms of maintaining back compat, that isn't as much of a burden as it sounds. It is mainly a test question - you have to test that the API behaviour doesn't change, but again - those tests have already been written, so it isn't really any extra work.
So, to answer a question with a question, why would they bother?
这是一个有趣的问题,至少对我来说是这样,以下是我的一些想法。
您的理解是正确的,在 XP VM 中运行的应用程序只能访问 VM 中 XP 提供的 Win32 API。我看到 Microsoft 增强特定 API 的方法有多种,其中之一是创建具有增强/固定功能的新函数,并通过在原始名称后附加 Ex 甚至 ExEx 来命名新函数,例如
对于接受指向的函数结构,通过使用结构的大小来确定所需的功能,对结构进行“版本控制”,因此较旧的代码将传递结构的先前大小,而较新的代码将传递较新的较大结构和相应的 API 函数。
我猜想,问题已经不再只是 API 工作方式的差异,而是操作系统功能和内部结构的一个组成部分,这些变化已经足够明显,以至于可以说写得很糟糕代码已被有效破解。
至于你的实际问题,我想这会很困难。即使有人想让操作系统根据可执行文件的 PE 头中的目标操作系统版本调整其执行代码的方式,如果将较新的 DLL 加载到针对最新操作系统的进程中会发生什么,现在操作系统应该如何当代码执行时处理这个?恕我直言,我认为这将非常具有挑战性,充满陷阱,最终会失败。
当然,这只是我对这个主题的原始想法,所以我可能 100% 错了,而且有一些简单的方法只是没有想到。
This is an interesting question, at least to me, here are some of my thoughts.
Your understanding is correct, an application running in the XP VM only has access to the Win32 APIs provided by XP in the VM. One of the many ways that I have seen Microsoft's approach to enhancing specific APIs is to create new functions with the enhanced/fixed functionality and name the new function by append Ex and even ExEx to the original name, for example
For functions that accept pointers to structures, the structures are 'versioned' by using the size of the structure to determine the functionality required, so older code would be passing a previous size of the structure while newer code would be passing in the newer larger strucure and the API functions accordingly.
I guess, the problem has become that it is no longer just differences in how an API works, but more integral to the functioning of the operating system and the internal structures which have changes significantly enough that arguably badly written code is effectively broken.
As to your actual question, I guess it would be quite tough. Even if one thought to let the OS adjust how it executes code based on a target OS version in the PE header of the executable, what would happen if a newer DLL was loaded into the process that targeted the latest OS, now how should the OS handle this when the code is executing? IMHO, I think this would be very challenging, one frought with pitfalls that would ultimately fail.
Of course that is just my raw thoughts on the topic so I might be 100% wrong and there is some simple approach that just did not come to mind.