Tuesday, 5 October 2010

Using Multiple Wine Prefixes

This post is a cross-post from Ubuntu Gamer

Wine rocks. It is probably one of the most underestimated pieces of software in the open source ecosystem. If the idea of running pre-compiled programs from Windows on a totally different operating system with a different kernel, and different programming libraries doesn't make you cross-eyed with the complexity, then you aren't thinking about it hard enough.

Just to give some idea of the Herculean achievement that Wine is; the current number of lines of code that make up Wine stands at well over 2.5 million and the project was started in 1993.

The Wine developers don't just have a mountain to climb. To extend the metaphor, they have to climb the mountain, blindfolded, in a straight jacket while tied to a goat... drunk. Their work really is that hard.

Yet despite all that effort, Wine still isn't 100% perfect. Sometimes a Wine DLL will be missing some code, other times the code may not match what Windows does and occasionally a program assumes the existence of files that may not even necessarily exist on a native Windows installation (e.g. .NET).

In these situations it's possible to use native original Windows DLLs in place of the Wine manufactured ones, or to install non-default runtime files like .NET or Java using their Windows installers.

To make this process easy there is a script called “winetricks” included in the Wine package from the Wine PPA or is available for download from here. Running winetricks from the terminal will give you a bunch of possible options to change and runtimes to install. Things like configuring font-smoothing, or installing .NET 1.1, 2.0 or 3.0.

The interesting thing is that these changes usually only affect the default Wine “prefix”.

What is a Prefix?

You all probably know that Windows installations have a certain folder structure. Specifically you'll normally have a C:\Windows directory, and a C:\Program Files directory. When you run Wine for the first time it creates these folders in a hidden directory in your home folder called “.wine”

This is a Wine prefix, it is essentially a fake Windows installation. It contains the folder tree, system files, a registry and Wine specific options (e.g. the Windows version). When you install an application, the files will be installed in the correct places within this tree and may add and remove registry entries. The default prefix is ~/.wine but you can create new ones anywhere you like.

So, Multiple Prefixes?

As I previously mentioned, sometimes you need to install some extra stuff into a Wine prefix to get an application working. If you are installing many applications and games your prefix can bloat up. Perhaps you may install something to get your second application working that breaks the first one. Perhaps you have an application that requires Wine to simulate Windows 98 and another application that only runs on XP and above.

To avoid this situation you can create a fake Windows installation for each individual application you install. You can tailor this installation for the application you are installing without the risk of breaking any other installed Windows programs.

The WINEPREFIX variable

Wine keeps track of the prefix to use with the WINEPREFIX environment variable. When the WINEPREFIX variable is set, all Wine commands such as winetricks or winecfg and any Windows application will use the specified prefix. Wine will also create the prefix if it doesn't exist.

As an example I'll demonstrate installing Interstate 76 bought from GOG.com into its own prefix. What's interesting about this specific game (and specifically the GOG version) is it requires a native Visual C++ runtime, .NET and the Windows version to be set to Windows 98, otherwise it crashes.

It's worth noting that you are required to have a Windows license to install Microsoft redistributables. Eventually Wine and Mono will progress enough to make this unnecessary though, just not yet :)

Example: Interstate 76

So, we want to create a new Wine prefix, which we do by setting the WINEPREFIX variable. So in a terminal we run:
export WINEPREFIX=~/.wine-interstate76
From this point forward all Wine commands run within the terminal session will work on our new prefix in a hidden .wine-interstate76 folder.

So now we can run the installer:
wine ~/Downloads/setup_interstate76_arsenal.exe
Running this command will do two things. Firstly it will create the prefix (you'll see a nice Wine message box telling you that it is updating the prefix). Secondly, it will run the installation program. Once we've been through the installer it will ask if you want to launch the game. This errors out with the Windows error message:
“An application has made an attempt to load the C runtime library incorrectly”.
If you ever see this specific error while trying to start a program under Wine, the workaround is usually to install the native VC++ runtime using winetricks. You'll notice the terminal printed the following:
err:module:attach_process_dlls "MSVCR90.dll" failed to initialize, aborting
So, we fire up winetricks and scroll down the list and lo and behold right next to “vcrun2008” is “msvcr90” listed as one of the components that it installs. Enable the checkbox next to vcrun2008, also next to dotnet20 and win98 which are required for this game.

Clicking OK will start off the VC++ runtime and .NET 2.0 installations and you'll need to do the traditional Next, Next, Next, Finish dance. But once done, you can run Interstate 76 from the Applications menu and it will work fine, from its own independent prefix.

A Note on Double Clicking

Double clicking a Windows application will always use the default ~/.wine prefix. So choosing another prefix requires using the terminal. Fortunately though, you only need to run the initial setup program (and wine tools) from the terminal because Wine creates entries in the Applications menu with the WINEPREFIX set. Basically, once your game is running fine you won't need to go to the terminal to run it, it'll just work.

1 comment:

  1. thanks for this tip, but there is another way to fix this problem, i fixed it by replacing this file http://fix4dll.com/xinput1_3_dll and thats it!