portable vhd
This page is mainly about portable vhd
#Persistent
;------------- MAIN PROGRAM -------------
If !A_IsAdmin
{
MsgBox, 0, Administrator Rights Required, Sorry, I require LOCAL MACHINE Adminstrator access to mount drives.`n`nClick 'OK' to exit the application.
Gosub exit
}
; Load initial options from .ini file
IniRead, PlaySounds, settings/settings.ini, Program Options, PlaySounds
IniRead, ShowSplash, settings/settings.ini, Program Options, ShowSplash
; Add tray menu
Menu, Tray, Tip, PortableVHD
Menu, Tray, Icon, icons\loading.ico
Menu, Tray, NoStandard
; Welcome screen
If ShowSplash
{
SplashImage, images\splash.png, b fs18
If PlaySounds
{
SoundPlay, sounds\startup.wav
}
Sleep, 3000
SplashImage, off
}
Menu, Tray, Tip, PortableVHD - No drives are mounted
Menu, Tray, Icon, icons\unmounted.ico
; Check VHD directory is valid
IfNotExist, vhd
{
If PlaySounds
{
SoundPlay, sounds\notify.wav
}
FileCreateDir, vhd
MsgBox, 0, No VHD folder!, There was no 'vhd' directory so I've made one.`nHowever, there are obviously no VHDs in there!`nYou'll have to create some ...`n`nClick 'OK' to exit the application.
gosub exit
}
IfNotExist, vhd\*.vhd
{
If PlaySounds
{
SoundPlay, sounds\notify.wav
}
MsgBox, 0, No VHDs!, I can't find any VHD's in the VHD folder.`n`nClick 'OK' to exit the application.
gosub exit
}
; Loop through all files in vhd directory
VHDArray := [] ; Initialise empty array
Loop, Files, vhd\*.vhd
{
VHDFileName := A_LoopFileName ; Retrieve file name from folder
VHDFriendlyName := RTrim(VHDFileName, ".vhd") ; Construct friendly name from filename
StringUpper, VHDFriendlyName, VHDFriendlyName , T ; Uppercase first letter
VHDFileSize := A_LoopFileSizeMB ; Retreive file size in MB
VHDFileArray := [VHDFileName,VHDFriendlyName,VHDFileSize,0] ; Create array to hold file information
VHDArray.insert(VHDFileArray) ; Add item to array from information above
}
; Populate mount / unmount menu from VHDArray
For index, vhd in VHDArray
{
VHDFriendlyName := vhd[2] ; Need to do this here because can't use arrays in Menu command
Menu, MountMenu, Add, %VHDFriendlyName%, mountMenuHandler
Menu, UnmountMenu, Add, %VHDFriendlyName%, unmountMenuHandler
Menu, UnmountMenu, Disable, %VHDFriendlyName%
}
; Add parent menus
Menu, Tray, Add, Mount, :MountMenu
Menu, Tray, Add, Unmount, :UnmountMenu
; Refresh menu
Menu, Tray, Add, Refresh, refresh ; NOT YET IMPLEMENTED
; Options menu
Menu, Tray, Add, Options, options
; Exit menu
Menu, Tray, Add, Exit, exit
; Is PortableVHD running from a removable drive?
StringLeft, scriptDrive, A_ScriptFullPath, 1
DriveGet, DrivesMounted, List, Removable
If InStr(DrivesMounted, ScriptDrive)
{
removableDrive := 1
TrayTip, PortableVHD Warning!, Virtual Hard Disks can't be run from removable drives. VHD(s) will be copied to local disk during operation., 12, 1
If PlaySounds
{
SoundPlay, sounds\notify.wav
}
}
; How many drives are mounted? Initially zero.
mounted := 0
return
;--------- END OF MAIN PROGRAM ----------
; Menu handlers
; Need menu handlers because you can't pass parameters
mountMenuHandler:
{
mount(A_ThisMenuItemPos)
return
}
unmountMenuHandler:
{
Unmount(A_ThisMenuItemPos)
return
}
refresh:
{
refresh := 1
return
}
options:
{
Gui, Options:New
Gui, Options:+AlwaysOnTop -MinimizeBox -SysMenu
Gui, Add, Button, x12 y90 w130 h30 gOptionsSaveAndClose,Save and Exit
Gui, Add, Button, x162 y90 w130 h30 gOptionsClose,Exit
Gui, Add, GroupBox, x12 y10 w280 h70 ,Program options
Gui, Add, CheckBox, x22 y30 w260 h20 vPlaySounds Checked%PlaySounds%, Play application sounds
Gui, Add, CheckBox, x22 y50 w260 h20 vShowSplash Checked%ShowSplash%, Show splash screen
Gui, Show, W305 Center, Options
return
}
; Functions
; Functions perform the mounting, unmounting and exiting
mount(VHDIndex)
{
; Make variables available inside the function
Global VHDArray
Global mounted
Global removableDrive
; Get drive details
VHDFilename := VHDArray[VHDIndex][1]
VHDFriendlyName := VHDArray[VHDIndex][2]
VHDFileSize := VHDArray[VHDIndex][3]
VHDMounted := VHDArray[VHDIndex][4]
;Get list of current drives so we can open new drive later
DriveGet, driveList, list
if removableDrive = 1 ; I'm running from a removable drive and VHD must be copied before mounting
{
if VHDFilesize > 256 ; VHD is greater than 256MB
{
MsgBox, 4, It's a big file!,The VHD is over 256MB in size and as I am running from a removable drive, it could take a long time to mount and unmount. Do you want to continue?
IfMsgBox, No
{
Return
}
}
;Remove vhd if it's already in temp folder presumably because of a problem with the script?
IfExist, %temp%\vhd\%VHDFileName%
{
FileDelete, %temp%\vhd\%VHDFileName%
}
;Copy VHD to local disk - can't mount otherwise
IfNotExist, %temp%\vhd
{
FileCreateDir, %temp%\vhd
}
FileCopy, %A_ScriptDir%\vhd\%VHDFilename%, %temp%\vhd\%VHDFilename%
VHDLocation = %temp%\vhd\%VHDFilename%
}
else
{
VHDLocation = %A_ScriptDir%\vhd\%VHDFilename%
}
; Set environment variable for Diskpart
EnvSet, mountscript, "%A_ScriptDir%\scripts\mountscript.txt"
RunWait, %comspec% /c ECHO SELECT VDISK FILE=%VHDLocation% > %mountscript%, ,hide
RunWait, %comspec% /c ECHO ATTACH VDISK >> %mountscript%, ,hide
; Actually mount the disk and increase number of mounted drives
RunWait, %comspec% /c Diskpart /s %mountscript%, ,hide
mounted := mounted + 1
; Display traytip confirming mounting
TrayTip, Mounted, %VHDFriendlyName% is successfully mounted. The drive will required unmounting before you can exit PortableVHD., 10, 1
; Disable Mount and Enable Unmount for this VHD
Menu, MountMenu, Disable, %VHDFriendlyName%
Menu, UnmountMenu, Enable, %VHDFriendlyName%
Menu, Tray, Disable, Exit ; You are not allowed to exit whilst a disk is mounted
; Change tray icon and tip
Menu, Tray, Icon, icons\mounted.ico
Menu, Tray, Tip, PortableVHD - Drives are mounted
; Set global flag and VHD mounted flag
drivesMounted := 1
VHDArray[VHDIndex][4] := 1
; Wait for new drive to mount and then open it
;Sleep, 1000
DriveGet, newDriveList, list
Loop, Parse, newDriveList
{
IfNotInString, driveList, %A_LoopField%
{
newDrive = %A_LoopField%
run, %newDrive%:\
}
}
return
}
unmount(VHDIndex)
{
; Make variables available inside the function
Global VHDArray
Global mounted
Global PlaySounds
Global removableDrive
; Get drive details
VHDFilename := VHDArray[VHDIndex][1]
VHDFriendlyName := VHDArray[VHDIndex][2]
VHDMounted := VHDArray[VHDIndex][4]
If removableDrive = 1
{
; Confirm that the user wishes to write back the disk image
overwrite := 0 ;By Default, do not overwrite
If PlaySounds
{
soundplay, sounds\notify.wav
}
MsgBox, 3, Overwrite?, The working VHD will be copied back to the PortableVHD directory, overwriting the original disk image. Are you sure you want this to happen?`n`nChoosing 'Yes' will save your changes.`n`nBy choosing 'No', the VHD will be unmounted and you will LOSE ALL YOUR CHANGES.`n`nIf you choose 'Cancel', no harm will be done and this dialogue will vanish.
IfMsgBox, Cancel ;I made a mistake!
Return
IfMsgBox, No ;I'm happy to lose my changes
overWrite := 0 ;Do not overwrite
IfMsgBox, Yes ;I want to save my changes
overWrite := 1 ;Happy to overwrite
VHDLocation = %temp%\vhd\%VHDFilename%
}
Else
{
VHDLocation = %A_ScriptDir%\vhd\%VHDFilename%
}
; Disable application menus during unmount
Menu, UnmountMenu, Disable, %VHDFriendlyName%
Menu, Tray, Disable, Exit
Menu, Tray, Icon, icons\unmounting.ico
Menu, Tray, Tip, PortableVHD - Unmounting ...
; Set environment variable for Diskpart
EnvSet, mountscript, "%A_ScriptDir%\scripts\mountscript.txt"
RunWait, %comspec% /c ECHO SELECT VDISK FILE=%VHDLocation% > %mountscript%, ,hide
RunWait, %comspec% /c ECHO DETACH VDISK >> %mountscript%, ,hide
; Actually unmount the disk and decrease number of mounted drives
RunWait, %comspec% /c Diskpart /s %mountscript%, ,hide
mounted := mounted - 1
If removableDrive
{
; If user wants to save changes, do so
If overWrite = 1
{
SplashTextOn, 375, 75, Please wait ...,`nPortableVHD is copying VHD back to application folder.`nThis dialogue will close once complete.
FileCopy, %temp%\vhd\%VHDFilename%, %A_ScriptDir%\vhd\%VHDFilename%, 1
SplashTextOff
}
; Remove the VHD from temporary storage
FileDelete, %temp%\vhd\%VHDFilename%
}
; Tooltip and Reenable menus
TrayTip, Unmounted, %VHDFriendlyName% is successfully unmounted., 10, 1
Menu, UnmountMenu, Disable, %VHDFriendlyName%
Menu, MountMenu, Enable, %VHDFriendlyName%
; If there are still drives mounted, put icon and tip back to mounted state
; or else, change application state to unmounted and allow exit
If mounted > 0
{
Menu, Tray, Icon, icons\mounted.ico
Menu, Tray, Tip, PortableVHD - Drives are mounted
}
Else
{
FileRemoveDir, %temp%\vhd
Menu, Tray, Enable, Exit
Menu, Tray, Icon, icons\unmounted.ico
Menu, Tray, Tip, PortableVHD - No Drives are mounted
Return
}
return
}
exit:
{
; Make variables available inside the function
Global PlaySounds
TrayTip, Goodbye, Shutting down ..., 10, 1
If PlaySounds
{
SoundPlay, sounds\shutdown.wav
}
Sleep, 3000
ExitApp
}
OptionsSaveAndClose:
{
Gui, Options:Submit
IniWrite, %PlaySounds%, settings/settings.ini, Program Options, PlaySounds
IniWrite, %ShowSplash%, settings/settings.ini, Program Options, ShowSplash
Return
}
OptionsClose:
{
Gui, Options:Cancel
Return
}
Last modified: October 5th, 2021