Freigeben über


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

Comments

  • Anonymous
    November 10, 2009
    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.

  • Anonymous
    November 10, 2009
    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.

  • Anonymous
    November 10, 2009
    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.

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

  • Anonymous
    November 16, 2009
    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.

  • Anonymous
    December 13, 2009
    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?

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

  • Anonymous
    July 01, 2011
    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 :-)

  • Anonymous
    July 13, 2011
    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 !