Windows 3.1 in a Windows 95 Virtual Machine

Windows 95 can run the GUI portion of Windows 3.1 as a DOS program in a virtual machine. So too can Windows 3.1. The story has more to it than you would ever know from Microsoft.

What’s here now is only the first of two parts or the first half of a longer article.

Occasional thoughts in late 2021 about my earliest work with DOS and Windows have sometimes got me looking on the Internet. A page by Raymond Chen from 2018 titled For a brief period, Windows 95 could run Windows 3.1 in a virtual machine caught my attention for revealing a pre-release feature that I would otherwise never have known about. Then it held my attention because Raymond stopped short of telling what survived in the released product and didn’t even hint that the feature had all along been much more a natural expectation than modern readers might think.

Or so it seemed to me from memory. Somewhere, I kept thinking, I have a picture. I recalled with certainty that discussions with Andrew Schulman in 1995—early enough that Windows 95 had not yet been released—had led me to a quick demonstration that an MS-DOS Prompt in Windows 3.1 could run a copy of the Windows 3.1 GUI. I also remembered what small trickery was required, not exactly but well enough to be confident of refreshing the details from notes that I knew I must still have. Also a strong memory was that the same trickery was mysteriously not needed for Windows 95. Less well remembered was a sense that Windows 95 presented other complications, but this may have been for some quixotic notion of running some of the Windows 95 GUI in an MS-DOS Prompt under Windows 95—or, less unrealistically, of exiting and re-running the Windows 95 GUI without leaving the Windows 95 operating system. Such were the architectural probings that I thought about back then! For the simpler matter of having Windows 95 run the Windows 3.1 GUI in an MS-DOS Prompt, I was sure I had got past the thought experiments and got something up and running, and been pleased enough with myself to have kept a screen-shot. That “Windows 95 could run Windows 3.1 in a virtual machine” was certainly not just “For a brief period”, and somewhere I must have this screen-shot to make the point.

Add that Raymond wrote in terms that suggested some revision of history, and I couldn’t help but be intrigued. Raymond, naturally, tends to write from Microsoft’s perspective about Microsoft’s experience and intentions, including for how Microsoft would like its products to be perceived. As Microsoft would have it, MS-DOS persisted in Windows 95 only as some sort of compatibility layer, but Raymond’s phrase “emulated MS-DOS virtual machine” stood out as going too far: when and how did the 80386’s hardware support for virtual-8086 execution get reduced to an emulation? Raymond anyway left unsaid that what was being run in the Windows 95 virtual machine could not be the whole of Windows 3.1, started from scratch by running WIN.COM, but was just its GUI, started by running KRNL386.EXE as a DOS program. This brought back to mind that Microsoft had stretched the definition of Windows 95 to take in not just its GUI and the Virtual Machine Manager (VMM) as its operating system but also the DOS that Windows 95 started from and could exit to—yet now for Windows 3.1 in Raymond’s telling, Windows was conveniently narrowed to just its GUI. Terminology for the relationship between DOS and Windows, and where exactly between them was the operating system, always was too vague for my taste and now it looked more fluid than ever: for Raymond in 2018 it’s just a matter of fact that Windows 3.1 is “the operating system” that Windows 95 “was designed to replace” but my memory of the early 1990s is that Microsoft talked then of Windows 3.1 more as a GUI program and an operating environment than as any sort of operating system.

Of course, memory after nearly thirty years is not nearly as reliable as might be hoped. This is true not just of biological memory but of what I have kept with me on disk or paper—not just after many changes of computers and of software but also because moving from one side of the world to the other and back has the inevitable consequence that things have got lost. I’ve been aware for many years that although I still have some records from the early 1990s, I’m missing much—including the original text of DOS Internals (ISBN 0-201-60835-9)—and that I have hardly anything from the mid-1990s, not even email. Where they’ve got to, I just don’t know—except that I can’t find them here with me now in New York—but Raymond had me intrigued enough that whenever these last few months of diversions into retro-computing have got me rummaging through what archives I have, I’ve kept half an eye open for anything relevant to this execution of the Windows 3.1 GUI in an MS-DOS Prompt in Windows 95.

The Old Screen Capture

Eventually, the neglected screen-shot did turn up. It’s no small frustration that I have no record of how exactly I ever produced this picture (other than pressing Print Screen), but frustration turns out to be an excellent motivator, even more than is curiosity, and so I should not be surprised if I do eventually get Windows 95 installed on some old computer to get a fresh and more instructive picture. I start to think that the reason I have no notes is because there wasn’t any difficulty worth noting, that the hardest part to getting a new picture will be the acquisition of suitable hardware or a willingness to install some third-party emulator from who knows where on the Internet. Meanwhile, the old picture more than suffices, because against the background of Raymond’s story about a science-project feature that was removed before release, it’s no small wonder that anything like the following could ever have existed. (Click on it for expansion to its original 800x600.)

Suspended Windows 3.1 in Windows 95

See especially that this isn’t some pre-release build of Windows 95. From the several Internet icons—which have no shortcut overlays, by the way, to encourage the perception that the Internet is a system feature—this Windows 95 can’t be from any earlier than mid-1996. It is anyway not a Windows 95 that was set up for curiosity. It’s a working installation of the real Windows 95 for my real-world use. Among other things it has Microsoft Office installed.

Floating over this very ordinary Windows 95 desktop is a windowed MS-DOS Prompt. Its title shows that the DOS program running within is KRNL386. The contents of the window are consistent with KRNL386 starting a separate installation of the Windows 3.1 GUI which got as far as running the Program Manager with at least enough interactivity for bringing up the About dialog. This in turn confirms that what’s running inside the MS-DOS Prompt is Version 3.1 in 386 Enhanced Mode. So far, so good, but evidently the interactivity had limits. Showing over the MS-DOS Prompt is a message box from Windows 95 to explain that what’s in the MS-DOS Prompt is a “graphics application” that can only be run full-screen. Calling up the About dialog must have been done while the MS-DOS Prompt had the screen to itself. While it was instead in a window for the screen-shot, it had to be suspended.

I suspect this suspension could have been overcome, if not by setting up the Windows 3.1 GUI to use only VGA drivers, then by setting up Windows 95 to. I also suspect I won’t have seen much point to proceeding. Had I imagined then that I might want the picture decades later for commenting about a Microsoft blog, I might have given it more attention. Instead I likely won’t have wanted to disturb my working Windows 95 installation just to rehash practicalities that were already known and expected from running the Windows 3.1 GUI in an MS-DOS Prompt on Windows 3.1.

As Raymond notes, those practicalities are not insubstantial. Even without the suspension while windowed, running the Windows 3.1 GUI in an MS-DOS Prompt—whether full-screen or windowed, on Windows 95 or Windows 3.1—is nothing that anyone should want to do except for the curiosity of seeing that it can be done. As far as the host Windows is concerned, a windowed MS-DOS Prompt is one Windows application that gives a view into one virtual machine (this representation being, I hope, what Raymond means when describing the virtual machine as emulated). What happens to be running in this particular virtual machine is an unusually complex MS-DOS program named Windows. That this in turn runs 16-bit Windows programs and subdivides its time for co-operatively multi-tasking them is all its own business. The host Windows knows nothing about the Windows programs in the MS-DOS Prompt, and they know nothing about being hosted. Either way, their usability is greatly hampered.

If you configure the MS-DOS Prompt so that Alt-Tab is not treated as a Windows shortcut key, then pressing Alt-Tab while the MS-DOS Prompt has the keyboard focus leaves it to be interpreted by whatever runs in the MS-DOS Prompt. Since this happens to be also a Windows GUI, the effect is that you can easily switch among the Windows programs that are inside the MS-DOS Prompt. Outside, Alt-Tab switches between the programs in the host Windows, among which the MS-DOS Prompt counts just as one. Keep at least one other Windows shortcut key for Windows, e.g., Alt-Enter for switching the MS-DOS Prompt between full-screen and windowed, or Ctrl-Esc for bringing up the Windows 95 Start button even while the MS-DOS Prompt has the keyboard focus, and you can move almost usably among all the Windows programs, both in the host Windows and in the MS-DOS Prompt. But make no mistake that they are two separate sets of Windows programs with no (built-in) communication or even awareness—and no real usefulness.

Still, whatever this toy’s deficiencies, whatever may have been the problems with setting it up, let alone with getting it to approach real-world usefulness, the picture plainly is of the released Windows 95 running Windows 3.1 in a virtual machine. What can it be that Raymond means by his talk of “a science project” that lasted only for “a brief period”?

Explicit Feature

A short answer may be that Raymond had something very particular in mind, not about what Windows was capable of doing but about what Microsoft had set it up to do for beta testers to see. Perhaps the title of Raymond’s article might better be read as

For a brief period, Microsoft made it an explicit feature that Windows 95 could run Windows 3.1 in a virtual machine.

What persisted of this feature in the released Windows 95, what was involved in its development (at least as early as July 1993) and why it was ever requested (however much earlier) isn’t credibly unknown to Raymond, but it may all be simply out of scope. In one sense, this is only natural. It persists for Raymond as a Windows feature to write about in 2018 only as much as it ever was alive for Microsoft in some sort of corporate mind. Get it up and running as a science project and it’s remembered as a science project. Cancel the science project and it’s remembered only as a cancelled science project.

But perspective is everything. Every writer so naturally has one that it’s rarely stated overtly and readers can’t expect it to be (and might reasonably be suspicious if it were). Here, Raymond’s talk of compatibility and eventually of failure is deeply tinged with a view that Windows 95 was a new operating system. There’s certainly a case to be made for this view, but an ever so slightly different perspective is that Microsoft in mid-1993 wanted very much for the world to see this forthcoming Windows as a new operating system but recognised that the world might instead take it to be just the next version of the Windows and DOS that Microsoft had so thoroughly established through the preceding decade. Seen this way, running Windows 3.1 in a Windows 95 virtual machine is less about demonstrating compatibility than about suggesting such novelty that compatibility needs demonstrating.

Left to themselves in mid-1993, the early beta testers—or were they still alpha testers—of what Microsoft was then calling Chicago would have understood that having the new version of Windows run old Windows programs was for Microsoft’s programmers a vital question of backwards compatibility but was for everyone else just their usual expectation of continuity. That backwards compatibility through a succession of versions was widely expected just as basic continuity is something that Microsoft had been notably good at encouraging on the way to building a mass market around DOS and Windows. I’ve long argued that it was the secret sauce in Microsoft’s spectacular success and that Microsoft never has been given enough credit for it (not that Microsoft needs that anyone cry for it). Still, by the early 1990s Microsoft will have understandably been itching to move on. What Microsoft will have wanted for Chicago was that its early reviewers should perceive it not as an evolutionary development but as a revolutionary departure.

The problematic background to this for Microsoft will have been that the mass market had already resisted one revolutionary departure (OS/2) and looked unlikely to embrace another that was newly ready for release (Windows NT). If the journey from Windows 3.1 to what became Windows 95 was to be presented as another of these revolutionary departures, but as the one that finally would sweep the mass market along, then the travellers who expected continuity would need the assurance of a convincing demonstration that Microsoft had compatibility well in hand. For bonus, it might work beneficially in reverse: give them the right demonstration and they might accept that they’re seeing a revolution.

That is the context I propose for reading Raymond’s perspective on compatibility and failure. Among the reasons that running Windows 3.1 in a Windows 95 virtual machine was only ever a science project is that even if Raymond’s skill and ingenuity could get it developed into real-world usefulness it plausibly never was intended for the final release. There was no failure to anticipate. Continuity was never in serious doubt. What really counted about this feature as a demonstration of compatibility was its usefulness to Microsoft for helping to establish from the start a perception—outside Microsoft and especially by those whom we nowadays call influencers—that Chicago was leaving the old DOS and Windows behind. For this, the feature may in its “brief period” have been quite the understated success.


For a visual sense of the distance that Microsoft wanted its beta testers to perceive between Windows 3.1 and Chicago, look at the screen-shots at Switch to Chicago and Switch to Windows 95. These are a quarter-century late, from 2017 and 2018, but it may be unrealistic to expect anything much earlier, let alone contemporary, given the nature of non-disclosure agreements and the decades that apparently must pass before old pre-release software is picked up for a fresh look as retro-computing. The second of these pages is notable for being linked to from Raymond’s article. Its publication may even be what brought the feature back to Raymond’s attention.

See that unlike my picture above, with the Windows 3.1 GUI in a window, albeit suspended, these pages each have pictures in pairs, one for the Chicago desktop, the other for Windows 3.1 running full-screen. Whatever their author may mean in the headlines with talk of running Windows 3.1 “in a window”, the feature’s design apparently did not make running in a window, in contrast to full-screen, obvious enough for a single-picture depiction that readers would obviously most want to see. For the page Would this work on Windows 95? from 2009—the earliest public discussion I have yet found—a commenter disappointedly describes the feature’s presentation just as “Windows 3.1 on Chicago in fullscreen mode” and the original poster produces a screen-shot with the regret that “I can’t figure out how to run it in a window, if it’s even possible.”

That a smattering of hobbyists on the Internet don’t show Windows 3.1 running in a window is in no way definitive but is some measure of an intended non-obviousness. The directions in Microsoft’s release notes, helpfully reproduced near the top of the last-cited page, suggest the involvement of just enough magic that readers conceivably followed carefully without daring to vary, and although execution in a window is not actually said to be impossible, neither is the possibility volunteered: “Chicago can run Windows 3.1 on a separate screen”.


How Microsoft packaged the feature was that users see a DOS program, named WIN31.EXE, and a Program Information File (PIF), named WIN31.PIF. Users are to “run” the PIF. This tells Chicago to execute WIN31.EXE as a DOS program in a new virtual machine that has a particular configuration. When WIN31.EXE starts in this virtual machine, it executes KRNL386.EXE as a DOS program to start the Windows 3.1 GUI, but the PIF settings apply to the whole of this execution: show the virtual machine full-screen and let all the usual Windows shortcut keys act in the virtual machine instead of in Chicago. Though PIF settings are sometimes vital, the DOS application being sufficiently demanding (or misbehaved) that it won’t run in Windows if the PIF settings are varied, I expect that the settings for WIN31 are just preferences. As Raymond says, “you could in theory run Windows 3.1 in a window”, but there are reasons not to—both general and specific—and the PIF is how Microsoft gets to say please don’t.

Generally, windowed DOS applications perform poorly. Because a full-screen application is interfered with less, it is faster, and because it owns the display for all practical effect (during foreground execution), its colours, fonts and proportions are exactly what it intends, not some translation to a smaller space and possibly a different palette. That DOS programs can be run in windows is too useful to be without—flipping full-screen DOS applications into windows gives a natural point-and-click user-interface for switching between them, with an easy view of multiple programs concurrently and the means to do such things as copy-and-paste—but sustained use of any one DOS application is far, far easier if done full-screen. This is true even for simple, well-behaved text-mode programs, let alone sophisticated graphics-mode applications such as Windows. Microsoft will have wanted that any assessment of Windows 3.1 in a virtual machine should be for appearance and performance full-screen, not windowed, because that’s simply what anyone would want of any graphical DOS application in the Windows of the day.

The specific reason for the preferences in WIN31.PIF is that the Windows 3.1 GUI was only being run as a DOS application for presentation as Windows 3.1 in a Chicago virtual machine, which brings in turn that the experience should match as closely as possible that of Windows 3.1 on a physical machine, ideally as if the user chose to run Windows 3.1 instead of Chicago. This needs not just effective ownership of the display, for being run full-screen, but of the keyboard too, specifically of the Windows shortcut keys such as Alt-Tab. Leaving one or even a few of these to Chicago as the host makes the combination of Chicago and Windows 3.1 more usable but makes Windows 3.1 less real. For instance, if Alt-Enter is interpreted by the host, it can switch the Windows 3.1 virtual machine between full-screen and windowed, but however useful this may be overall, the price is that Alt-Enter is not available within Windows 3.1 as a shortcut for Properties on the File menu of many Windows 3.1 programs. The reality of the Windows 3.1 experience therefore demands that Windows 3.1 claims all the Windows shortcut keys for itself whenever it has the keyboard focus.

Thus are the WIN31.PIF settings entirely natural as preferences, but see that they present a practical difficulty. Apply these settings to any DOS application, even to COMMAND.COM for an MS-DOS Prompt, and your only means to switch back to Windows is to exit the DOS program.


The WIN31.PIF settings therefore lead naturally to needing that something be created in the Windows 3.1 GUI for switching back to Chicago. But the aim, at least initially, will have been that this Windows 3.1 can be anyone’s pre-existing installation, perhaps limited to some basic configuration, but ideally unchanged.

The design that Microsoft settled on has WIN31.EXE also be a Windows program. Before its DOS part executes KRNL386.EXE as a DOS program to start the Windows 3.1 GUI, WIN31.EXE hooks int 2Fh function 160Bh to arrange that USER.EXE in the newly started Windows 3.1 GUI will know to execute WIN31.EXE as a Windows program. What WIN31.EXE does as a Windows program is to create a minimized window captioned “Switch to Chicago”. The essence of the window procedure is that attempting to restore the window from its iconic state gives the focus to the System VM.

For the earliest leaked but extant beta, build 58s (with relevant files dated July and August 1993), this switching of focus to the System VM is done by calling the system in ring 0, specifically the Virtual Device Driver (VxD) that has ID 0017h and logical name SHELL. This VxD has always exposed a protected-mode (PM) API through int 2Fh function 1684h. SHELL’s particular API takes a function number in dx. Originally, these were in one series starting at zero. Chicago extended to a second series starting at 0100h. The switching of focus to the System VM is done by calling function 0107h, which I cannot discount was invented for WIN31.EXE specifically. Documentation in the Device Driver Kit (DDK) for Windows 95 names eight SHELL functions that it then does not document. Some of the names matched my interpretation of the new series of SHELL API functions. For instance, 0100h is obviously SHSV_Get_Version and less obviously 0104h, 0105h and 0106h must be SHSV_Enumerate_Properties, SHSV_Update_Properties and SHSV_Set_ScreenSaver_Info. For function 0107h, however, what’s done by the relevant code in the released Windows 95 is nothing that any of the names suggest. Now from looking at pre-release builds, I know that this is because 0107h was SHSV_GiveSYSVMfocus in early Chicago builds but was soon reassigned to new code that does something else entirely. This reassignment of the function number happened at least as early as build 73f from November 1993, which changed the focus switching to number 0026h in the SHELL API’s old series. This does survive to the retail release (but, as far as I know, was never even named in public).

This design with a WIN31 program and PIF, and some specialised support from the operating system, arguably delivers the best possible look of reality to the execution of the Windows 3.1 GUI in a Chicago virtual machine. But let’s not miss that this design has some convenient distraction. Allow Windows 3.1 to show in the same sort of window as an MS-DOS Prompt, with familiar user-interface support for getting back to the Chicago desktop, and you make it plain that what’s running is just the Windows 3.1 GUI as a DOS application. That would still have been “a convincing technology demonstration”, but closing it off, or just making it non-obvious, might see non-expert users take at face value that what’s being demonstrated is the greater technology of Windows 3.1 as one operating system in another’s virtual machine. Present Windows 3.1 as separate enough from the Chicago experience that it doesn’t show concurrently and needs the clicking of a special Windows 3.1 desktop icon to “Return to Chicago”, and you inevitably suggest that new Chicago’s execution of old Windows 3.1 in a virtual machine is something special.

Nothing Really New

In reality, the management of virtual machines even in the released Windows 95 is essentially unchanged from Windows 3.1. True, in Windows 95, each virtual machine (VM) competes for its pre-emptive multi-tasking not just with other virtual machines but with pre-emptive multi-threading in the first virtual machine (named the System VM). What runs in this System VM under Windows 95 in contrast to Windows 3.1 is a significant elaboration that has a rich mixture of 16-bit and 32-bit code use the significant new system support of threads and multiple address spaces. Importantly, the system underneath restricts this support to the System VM. For the other virtual machines, Windows 95 brings nothing really new. Windows 95 can run the Windows 3.1 GUI in a virtual machine for a very simple reason: because Windows 3.1 can.

None of this was ever news to Raymond, of course—except perhaps before 1992 or so—but it likely is to you even now in 2022. As far as I recall or can now find either on the Internet or in my box of relevant books from the 1990s, having Windows 3.1 run a separate installation of its own GUI in a second virtual machine (whether full-screen or windowed) never has been discussed in public until now. Even if now did not mean a delay of nearly thirty years, you might want some convincing. After all, Raymond would have it that to “Run Windows 3.1 in an MS-DOS virtual machine inside Windows 95” was the “ultimate in backward compatibility, along multiple axes” and “served as a convincing technology demonstration”, and I’m a relative nobody telling you that it’s not compatibility at all, just continuity, because it really isn’t any different from running Windows 3.1 in an MS-DOS virtual machine inside Windows 3.1—which you, in turn, never knew was possible.

Windows 3.1 in Windows 3.1

As it happens, Windows 3.1 can run not just one copy of itself in a virtual machine but multiple copies of itself concurrently, each in its own virtual machine, each showing in its own window on the Windows 3.1 desktop. You can drag them round like any other windows. You can switch between them just by clicking on the one you want to bring to the foreground. You can switch to the host’s other windows just by clicking on them. Nowhere do you need some special icon for returning to the host.

Since I have by now found an old computer and installed Windows 3.1 on it—not Windows 95 yet, whose Setup hangs after the license dialog—I can illustrate this point with a fresh picture. Here is Windows 3.1 Enhanced Mode as host to two separate installations of Windows 3.1, each in their own DOS window, each left alone to execute in the background for long enough to have triggered their different screen savers. (Click on the picture if you want it expanded to its original 640x480.)

Multiple Windows 3.1 Screen Savers

There are, of course, a few caveats and a contrivance. Stick with me for Part Two and I will explain, including to give directions so that you can play too (with suitable hardware or emulators).

Part One, I hope has demonstrated that Raymond’s story has more to it, but although this is easy enough to see from outside Microsoft, we can’t know what more with certainty, especially for questions of motive and strategy. Part Two will shift attention from what Raymond’s science project is to what was needed for getting it up and running. For how Raymond’s science project got up and running, we can hypothesise with confidence because the programming and debugging left a trail, memorialised in surviving copies of Windows 3.1 and Windows 95, open to inspection and experiment.