Double click to mount a virtual hard disk (Windows 7 Style)

I have been wanting to come up with a workable solution for mounting virtual hard disks by double clicking on them in Windows 7 for a while now.  The problem is that:

  • There is no easily scriptable API for VHD mounting
  • You need to be elevated (running “As Administrator”) in order to mount a virtual hard disk

The best idea I could think of for a simple solution was to try scripting the DISKPART tool.  Unfortunately – once I got going I got a bit carried away.  The result is this batch file:

 @ECHO OFF
  
 REM - This will be the file that I use for scripting
 SET temporaryFileName=%temp%\VHDBatchTempFile_%random%.txt
  
 REM - Parse the first parameter and go to the right lication
 IF %1==mount GOTO:mount
 IF %1==readOnlyMount GOTO:readOnlyMount
 IF %1==dismount GOTO:dismount
 IF %1==compact GOTO:compact
 IF %1==install GOTO:install
 IF %1==uninstall GOTO:uninstall
  
 REM - Give a helpful error message if no parameter is recognized
 GOTO:error
  
 REM - Mounting a virtual hard disk
 :mount
 ECHO select vdisk file=%2 > %temporaryFileName%
 ECHO attach vdisk >> %temporaryFileName%
 diskpart /s %temporaryFileName%
 del %temporaryFileName%
 GOTO:EOF
  
 REM - Mounting a virtual hard disk (read only)
 :readOnlyMount
 ECHO select vdisk file=%2 > %temporaryFileName%
 ECHO attach vdisk readonly >> %temporaryFileName%
 diskpart /s %temporaryFileName%
 del %temporaryFileName%
 GOTO:EOF
  
 REM - Dismounting a virtual hard disk
 :dismount
 ECHO select vdisk file=%2 > %temporaryFileName%
 ECHO detach vdisk >> %temporaryFileName%
 diskpart /s %temporaryFileName%
 del %temporaryFileName%
 GOTO:EOF
  
 REM - Compacting a virtual hard disk
 :compact
 ECHO select vdisk file=%2 > %temporaryFileName%
 ECHO compact vdisk >> %temporaryFileName%
 diskpart /s %temporaryFileName%
 del %temporaryFileName%
 GOTO:EOF
  
 REM - Put registry keys in place 
 :install
  
 SET temporaryFileName=%temporaryFileName:txt=reg%
  
 SET batchFileName=%~f0
 SET batchFileName=%batchFileName:\=\\%
  
 ECHO Windows Registry Editor Version 5.00 > %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\.vhd] >> %temporaryFileName%
 ECHO @="Windows.VirtualPC.HD" >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\.vhd\ShellEx] >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\.vhd\ShellEx\ContextMenuHandlers] >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD] >> %temporaryFileName%
 ECHO @="Virtual Machine Hard Drive Image" >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\ShellEx] >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\ShellEx\ContextMenuHandlers] >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell] >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open2] >> %temporaryFileName%
 ECHO @="M&ount VHD" >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open2\Command] >> %temporaryFileName%
 ECHO @="CMD /S /C  \"\"%batchFileName%\" mount \"%%1\"\"" >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open3] >> %temporaryFileName%
 ECHO @="D&ismount VHD" >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open3\Command] >> %temporaryFileName%
 ECHO @="CMD /S /C  \"\"%batchFileName%\" dismount \"%%1\"\"" >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open] >> %temporaryFileName%
 ECHO @="Mount &VHD (Read Only)" >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open\Command] >> %temporaryFileName%
 ECHO @="CMD /S /C  \"\"%batchFileName%\" readOnlyMount \"%%1\"\"" >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open4] >> %temporaryFileName%
 ECHO @="Com&pact VHD" >> %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open4\Command] >> %temporaryFileName%
 ECHO @="CMD /S /C  \"\"%batchFileName%\" compact \"%%1\"\"" >> %temporaryFileName%
  
 regedit /s %temporaryFileName%
  
 del %temporaryFileName%
  
 ECHO.
 ECHO Windows VHD integration installed.  
 ECHO Run "%~f0 uninstall" to uninstall windows VHD integration if desired.
 ECHO.
  
 GOTO:EOF
  
 REM - Remove registry keys
 :uninstall
  
 SET temporaryFileName=%temporaryFileName:txt=reg%
  
 SET batchFileName=%~f0
 SET batchFileName=%batchFileName:\=\\%
  
 ECHO Windows Registry Editor Version 5.00 > %temporaryFileName%
 ECHO. >> %temporaryFileName%
 ECHO [-HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell] >> %temporaryFileName%
 ECHO [-HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open] >> %temporaryFileName%
 ECHO [-HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open\Command] >> %temporaryFileName%
 ECHO [-HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open2] >> %temporaryFileName%
 ECHO [-HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open2\Command] >> %temporaryFileName%
 ECHO [-HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open3] >> %temporaryFileName%
 ECHO [-HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open3\Command] >> %temporaryFileName%
 ECHO [-HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open4] >> %temporaryFileName%
 ECHO [-HKEY_CLASSES_ROOT\Windows.VirtualPC.HD\Shell\Open4\Command] >> %temporaryFileName%
  
 regedit /s %temporaryFileName%
  
 del %temporaryFileName%
  
 ECHO.
 ECHO Windows VHD integration uninstalled.  
 ECHO Run "%~f0 install" to install windows VHD integration if desired.
 ECHO.
  
 GOTO:EOF
  
 REM - Helpful error message
 :error
 ECHO.
 ECHO VHD Batch file.
 ECHO.
 ECHO Usage:
 ECHO.
 ECHO %~n0 install
 ECHO.
 ECHO This command will allow you to right click on a virtual hard disk
 ECHO and select and action to perform without manually running this
 ECHO batch file.  Make sure you do not move or delete the batch file
 ECHO after running this command without first running "uninstall".
 ECHO.
 ECHO %~n0 uninstall
 ECHO.
 ECHO Removes all information from the system about this batch file.
 ECHO.
 ECHO %~n0 mount "full path and name for a virtual hard disk"
 ECHO.
 ECHO will use DISKPART to mount the virtual hard disk specified. Note
 ECHO that you need to provide the full path and name for the virtual
 ECHO hard disk, and that you should not mount a virtual hard disk that
 ECHO has differencing disks, undo disks or snapshot files associated
 ECHO with it.
 ECHO.
 ECHO %~n0 readOnlyMount "full path and name for a virtual hard disk"
 ECHO.
 ECHO will use DISKPART to mount the virtual hard disk specified. In
 ECHO read only mode.  This is always safe to do. Note that you need to 
 ECHO provide the full path and name for the virtual hard disk.
 ECHO.
 ECHO %~n0 dismount "full path and name for a virtual hard disk"
 ECHO.
 ECHO will use DISKPART to mount the virtual hard disk specified. Note
 ECHO that you need to provide the full path and name for the virtual
 ECHO hard disk.
 ECHO.
 ECHO %~n0 compact "full path and name for a virtual hard disk"
 ECHO.
 ECHO will use DISKPART to compact the virtual hard disk specified. Note
 ECHO that you need to provide the full path and name for the virtual
 ECHO hard disk, and that you should not compact a virtual hard disk that
 ECHO has differencing disks, undo disks or snapshot files associated
 ECHO with it.  You should also not compact a virtual hard disk that is
 ECHO currently mounted.

If you put this text into a .CMD file (or download the attached file on this blog) and place it where ever you want to keep it – you can do one of two things:

  • Use it as a convenient command line tool for mounting and dismounting virtual hard disks
  • Run it with the “install” parameter – in which case it will add registry entries to your system that allow you to double click on a virtual hard disk to have it mount (in read only mode) or right click on a virtual hard disk to get options to mount, dismount or compact a virtual hard disk

So what is it doing under the covers?  For the disk related operations this batch file builds a DISKPART script file on the fly and feeds it into DISKPART.  For installing and uninstalling it adds and removes appropriate registry keys.

After a bit of testing I can confirm that this works on Windows 7 and Windows 2008 R2, 32-bit and 64-bit, with and without Windows Virtual PC and Hyper-V and is fully compatibility with UAC.

Have fun!

Cheers,
Ben

VHDBatch.zip