Parallels Desktop VS VMWare Fusion – deleting multiple snapshots

I have used both Parallels Desktop and VMWare Fusion to run Windows, largely for Windows software development, on a Mac, over the past several years.  There have been a number of reviews comparing them, which I won’t repeat.  Parallels Desktop allowed much better hardware configuration and much better keyboard mapping a couple of years ago, which is why I have been using it over the past couple of years (newer versions of VMWare Fusion may have improved that — I don’t know).

One of the biggest advantage of using Virtual Machines for software development (with either Parallels Desktop or VMWare Fusion) is the ability to easily create snapshots.  When you are doing development, you often need to install or update software components, and never know when you may destabilize your system.  The ability to easily create system backups is similar to commits in source code control, in that you can easily save multiple states that you can go back to if you need to.  As a result, I tend to create a LOT of snapshots.

My biggest complaint about Parallels Desktop in comparison to VMWare Fusion is that it does not allow you to delete multiple snapshots at once.  Deletion of one snapshot (with either Parallels or VMWare) can easily take five to ten minutes or longer.  If you have to delete thirty or forty snapshots, clicking on one, waiting ten minutes, clicking on the next, waiting ten minutes, it can get very time consuming.

VMWare Fusion has had a much better solution for this problem, and is much better than Parallels Desktop in this regard.  In Fusion, you merely select all of the snapshots you want to delete, and then select “Delete”.  It may take a while, but you don’t have to manually select each snapshot, one at a time, delete it, and wait.  It can run overnight, and when you come back, the work is all done!  Alas, Parallels Desktop does not allow you to select more than one snapshot to delete at a time.

Recently, I submitted a request to Parallels about my problem, and to my delight (and surprise), their technician called me on the phone the next day to help me.  Ultimately, they led me to what seems to be a solution, but not without a couple of mis-steps, so I wanted to document my experience for anyone else having this problem.

One thing about snapshots: they are NOT backups.  The virtual disks with either VMWare or Parallels are MUCH more fragile than a regular hard drive controlled with a journaled format by a modern operating system (Windows, Linux, or OS X).  I have had both VMWare and Parallels disk images become corrupted fairly often, which results in ALL of your snapshots (and everything else) being lost.  If you use VM’s, you MUST backup the ENTIRE VM FILE, just as with source code control.  That also has the advantage of backing up all of your snapshot history.  Before doing anything I describe here, be sure you have at least one backup (and preferably more, on different disks) of your VM.  As I mention, my VM DID become corrupted, and I had to use a backup.  You have been warned.

I had backed up my entire VM with all of my old snapshots, and I just wanted to remove all of the old snapshots from my current, working copy.  I had a virtual hard disk with about 100 GB of files, but the VM had swollen to about 450 GB with all of the snapshots.  Parallels has a “Delete snapshots with children” option, which I had used to delete any “branches” I had (usually when I had to go back to a working configuration).  Thus, I just had one long line of snapshots in my Parallels VM.

The technician directed me to use  the prl_disk_tool merge option.  He directed me to the http://kb.parallels.com/9165 page.  He had me open a terminal session, and copy

prl_disk_tool merge --hdd

onto the command line.  Then, he had me open Parallels, and in the Virtual Machines List, right click on the offending VM and select “Show in Finder”.  Then, right click on the VM file in Finder and select “Show Package Contents”.  Then (and I didn’t know you could do this), click on the large .hdd file and drag it into the Terminal window — that copied the full path of the .hdd file, properly escaped, onto the end of the command line I was building, which left me with a command line like

prl_disk_tool merge --hdd /Users/nachbar/Documents/Parallels/Win 7.pvm/Win 7-0.hdd

Then, press Enter.  I was immediately presented with an operation progress starting at 1%, and slowly increasing to 100% over about 90 minutes.  At the same time, the size of my VM dropped, and the free space on my physical hard drive increased, by about 300 GB.  But that only partially fixed the problem.

I was then able to run my smaller VM with the merged snapshots, but Snapshot Manager showed all of the snapshots still there.  I emailed them back, and they directed me to the page about snapshot manager and deleting snapshots there.  I was able to delete them one at a time, and it was a lot faster (five to ten seconds each).  That page also described “Delete with children”, and so I thought I would use that, figuring that I would be warned if it was going to delete my current VM state.  Big mistake.  I was almost immediately met with the “Unable to Connect to Parallels Service” error described at http://kb.parallels.com/8089 .  The “Deleting Snapshot” animation continued, however, and I allowed it to run, figuring that if I killed it I would certainly corrupt my VM.  However, after 14 hours, I really had no choice but to kill the Parallels application.  I rebooted, and to my surprise, the VM booted (with a message from Parallels that it had recovered from a serious error).  However, all of the snapshots were still there, and now I could not delete any of them, being met with the “The configuration file you specified is invalid” error.  Thus, still a kind of VM file corruption.

So, I went back to my VM file backup, and started over.  I again ran prl_disk_tool merge, and this time I just deleted the snapshot zombies one at a time, each taking only about 5 seconds (since the underlying snapshots had already been merged).  About half way through, I still had some trouble — I got the “Unable to Connect to Parallels Service” message, and Parallels hung and had to be Force Quit.  Restarting Parallels produced the “Unable to Connect to Parallels Service” error, so I followed the instructions in http://kb.parallels.com/8089 to restart the Parallels Service.  I also got the “Parallels has recovered from a serious error” message.  I was then able to proceed with deleting more snapshot zombies until I had removed all of them.  Now, my VM is down from 450 GB to about 117 GB, and the VM seems faster (at least on startup, which used to be quite slow).

So, clearly a kludge, and still involving a Force Quit and Serious Error recovery, but ultimately I got to a much smaller VM.  I would note that I usually shut down my VM before doing these procedures.  I’m not sure if it is needed, but it seemed reasonable.

Hopefully, Parallels will catch up to where VMWare has been for many years and allow us to select multiple snapshots to delete at one time.  In the meantime, you may want to try this ON A BACKUP OF YOUR VM if you have a lot of snapshots and a bloated VM.

Compiling THtmlViewer to use in C++ Builder XE

The THtmlViewer component is a component that displays HTML in a Delphi/C++ Builder form.  It is also used by the outstanding TRichView component for importing HTML.  It is available under the MIT license, so it can be used in commercial projects.  It is hosted on Google Code : http://code.google.com/p/thtmlviewer/.  It can be downloaded using subversion as described here: http://code.google.com/p/thtmlviewer/source/checkout, and as noted on that page,

# Non-members may check out a read-only working copy anonymously over HTTP.
svn checkout http://thtmlviewer.googlecode.com/svn/trunk/ thtmlviewer-read-only

The author of TRichView recommends that you NOT use the trunk version, but rather branch 11:

svn checkout http://thtmlviewer.googlecode.com/svn/branches/11/ thtmlviewer-read-only

The 2010 Delphi project imports into Delphi XE and compiles, and you can install the resulting package, but the components only show up when running Delphi!

To create the components for C++ projects, you need to create a C++ package, but NOT using File/New/Package — C++ Builder

Instead, Component/Install Component, Install into new package, select the same .pas files used in the Delphi package (basically, all of them in the source folder)
You then need to name the package and choose its save location (for the package folder).  You can give it a description, which will later show up in the Component/Install Packages… dialog

Make sure to specify that you want a C++ Package, not a Delphi package.  Select Finish, and your package will be created, although linking will fail with an error.

You have more work to do before it will work properly.  You need to specify the -LUDesignIDE option to the Delphi compiler — in the Project Options/Delphi Compiler/Compiling/Other options/Additional options to pass to the compiler, include “-LUDesignIDE” (without the quotes).  Be sure to use the correct build configuration at the top of the dialog — you will want a Release build, so select Base or Release.

Also, Delphi needs to know to make the .hpp files, etc.  In the — in the Project Options/Delphi Compiler/Compiling/Output – C/C++ / C/C++ Output file generation, pick “Generate all C++ Builder files (including package libs)” so you get the header files as well as the package lib to install.

Finally, when you try to install the package, you will get an error that it conflicts with a file included in the vclimg150 package.  The solution is to include vclimg150.bpl in the Requires list for the package.  Right-click on Requires, and add vclimg150.bpl (just type the name — you don’t need to browse to the file, and when it shows up in the requires list, it will be vclimg.bpi, even though you typed vclimg150.bpl)

Now, pick the Release build, and build it (In the Project Manager, open up Build Configurations, right click on Release, and select Build)

Then, you need to install it, using Component/Install Packages .

First, save and close your THTMLViewer C++ Project.  Then, WITH NO PROJECTS OPEN, Select Component/Install Packages…  THTMLViewer should not be listed in the design packages check list box.

Click Add… , and go to the directory where your library was placed (this is set under Project/Options for the project that made the THTMLViewer component — by default under Windows 7 and RADStudio XE it is C:UsersPublicDocumentsRAD Studio8.0Bpl .  Select the .bpl package library that you just made, and click OK.

Then, you can create a new C++ Project, and you should be able to select the THtmlViewer component and drop it on the form.  Make a FormCreate handler, containing the line HtmlViewer1->LoadFromString(WideString(“Hello”)); .  Compile the project, and it may complain about missing .h files.  Just browse to the source directory, where the .hpp files should be.  You can select the .hpp file even though RAD Studio is looking for the .h file.  If it compiles and you see “Hello” in the window, you know you are done!

Incidentally, creating the component project under Delphi is easier than under C++ Builder — Delphi automatically recognizes and fixes the vclimg150 problem, presenting it in a dialog box, with “OK” to add the reference and rebuild the component.  Also, Delphi automatically installs the component.  However, the component does not install under both C++ Builder and Delphi at the same time (I could not figure out how to do that), and since I don’t really need it under Delphi, I did not pursue it.