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

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

  • Comments 9

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

Attachment: VHDBatch.zip
Leave a Comment
  • Please add 2 and 2 and type the answer here:
  • Post
  • Did you check this? http://code.msdn.com/vhdshellext

    This uses Hyper-V WMI interfaces and can work using the Hyper-V WMI APIs on a remote system.

    And also this: http://www.ravichaganti.com/blog/?p=349

    This one is very similar to what you provided here.

  • There is tool that adds mounting to context menu of VHD file. It is called VHD attach and it can be downloaded at http://www.jmedved.com/?page=vhdattach.

  • That's not getting carried away, you should see some of my dad's batch files from the MS-DOS days.  He kept all the PC games we had in individual ZIPs and separate ZIPs for the diffs between the games' install files and settings/saved games.  He had a BAT to automatically extract 'em, run the game, find the diff files, and compress them into the settings ZIP and remove the temporary folder.  He even added a bunch of different switches to do things I don't remember anymore.

  • This is exactly what I have been looking for! Any chance you could do something on using the APIs?

  • More scripts and batch files please. Oh wait, while these are nice, I can't run Windows Virtual PC at all due to stupid hardware requirements.

  • Well, this doesn't work for me. I tried installing this on my mac with Bootcamp (Windows 7) but get an error: Failed to initialize. Weird?

  • I love it when PMs can still get their hands dirty.  ;-)  Thanks for sharing, Ben.

  • Nice, "compact" is something VHDattach 2.01 does not offer, I'll test this part of your script when I need it. If you ever want to get rid of the "full VHD path" limitation check out "%~f2" instead of %2 :-)

  • Surely Scripting Guy blogs.technet.com/.../heyscriptingguy and community gallery.technet.microsoft.com/ScriptCenter could help with the powershell script. Just look at their last 2011 Scripting Games blogs.technet.com/.../2011-scripting-games-all-links-on-one-page.aspx !

Page 1 of 1 (9 items)