SaveState Files and "Error: The current VMID is in use. Wait for the other application to exit."

If you launch the emulator by hand with savestates enabled (ie. "DeviceEmulator.exe nk.bin /s MySaveState.dess"), then your savestate file may fail to launch later, with an error "Error: The current VMID is in use. Wait for the other application to exit.".  This can happen if you launch another emulator instance from the command line then try to launch the savestate file.

Behind the scenes, every launch of the DeviceEmulator has an associated Virtual Machine ID (a VMID).  These are GUIDs that help Visual Studio and the Device Emulator Manager uniquely identify an instance of a virtual machine.  If you don't specify a VMID explicitly on the emulator's command line, then the emulator chooses a VMID automatically.  If VMIDs are GUIDs, which are unique by definition, why do two instances of the emulator have the same VMID GUID?

The answer to that is related to how the emulator supports networking.  Ideally, each launch of the emulator would create new, unique, MAC addresses for the two emulated network cards.  Unfortunately, creating new MAC addresses for each launch of the emulator can add a large load to your network's DHCP server:  each emulator instance would appear like a new PC on your network and would negotiate a DHCP-assigned IP address with a lease.  The problem is with the lease:  if your DHCP server is configured to lease out IP addresses with a lifetime of 24 hours, then each emulator instance would keep an IP address reserved for 24 hours after it exited.  Launch a few hundred emulators and a few hundred IP addresses are removed from the address pool until tomorrow.

To address this, the DeviceEmulator caches MAC address values it has used in the past.  The cache associates a MAC address with a VMID GUID, meaning that if you launch the same VMID multiple times, it will use the same MAC address each time, which will cause the DHCP server to hand back the same IP address used in the last launch of that VMID.  The cache sits in "HKEY_CURRENT_USER\Software\Microsoft\Device Emulator\MAC Addresses" in the registry.

So back to VMIDs... each launch of an emulator from Visual Studio uses the same VMID, as it is a property of each entry in the "Devices" list, and the VMID is passed on the emulator's command line via the "/vmid" option.  Emulators launched by hand without /vmid have a different strategy:  they pick a VMID GUID from a short list of VMID GUIDs hard-coded into the emulator itself.  So if you launch two DeviceEmulators by hand, one picks the first VMID from the table and the second picks the second VMID.

And back to savestate files...  each savestate file contains the emulator's VMID.   So if you launch one emulator on a machine and exit, creating a savestate file, then launch a new emulator then try to launch the savestate file, you'll get the error dialog.  The "new emulator" will be using the first VMID in the emulator's list, and the savestate file has the same VMID.

 

To make sure this doesn't happen, it is a good idea to create a new VMID GUID each time you wish to create a savestate file by launching the emulator by hand.  It's easy to do:  from the Visual Studio Command prompt, run uuidgen.exe.  Then add "/vmid {...guid from uuidgen }" to the emulator's command line.  Something like this:

   c:\>uuidgen

   c7cbfcc5-36c8-42be-852a-6ec017a4f2f8

   c:\>DeviceEmulator.exe nk.bin /s MySaveState.dess /vmid {c7cbfcc5-36c8-42be-852a-6ec017a4f2f8}

Barry