Video Screencast Help
Symantec Appoints Michael A. Brown CEO. Learn more.

How to modify a virtual registry value for every user?

Created: 03 Dec 2012 • Updated: 04 Dec 2012 | 3 comments
This issue has been solved. See solution.

Hello,

I've created a layer of Evernote and it works well but I need to change an option in the program that needs to be different for every user of the layer.

This option is the path where the Evernote database is located. If you don't modify the default installation it goes to a directory below the user profile like this one:

C:\Users\manel\AppData\Local\Evernote\Evernote

I know that I can exclude this directory so the data inside it goes to the base instead of the layer but is better for us to move this data to another partition or a network drive so is not lost when redeploying the OS.

If I change this path through the program GUI this info appear in the registry:

[HKEY_CURRENT_USER\Software\Evernote\Evernote]
"EvernotePath"="D:\\USUARIS\\manel\\Evernote"

So, how do I need to write this information in the layer registry so it will different for every user? I've test using D:\USUARIS\%USERNAME%\Evernote both as REG_SZ and REG_EXPAND_SZ without success because the program expects to be a real path not to use variables.

Is there any trick to have this registry key a variable? Or to populate it with the real and good value uppon the first start of the layer by the user?

Thanks.

 

Comments 3 CommentsJump to latest comment

EdT's picture

In a non-virtualised application, the creation of specific user entries in the registry is normally handled with Active Setup.  I don't know enough about the inner workings of SWV to advise whether you can use parameters in a user registry key, but if there is no other answer forthcoming for this, implementing active setup would be my solution. If you need more info, let me know.

If your issue has been solved, please use the "Mark as Solution" link on the most relevant thread.

AngelD's picture

I would create a vbscript shortcut-wrapper to first write the registry value and then launch evernote.

The vbscript could look something like the below to fix the registry, you have to add the launch of evernote yourself.

 

Dim REG

Set REG = New RegistryClass
Call REG.SetEntry("HKCU\Software\Evernote\Evernote", "EvernotePath", ExpandEnvironmentStrings("D:\USUARIS\%USERNAME%\Evernote"), REG.TYPE_SZ)
Set REG = Nothing


Function ExpandEnvironmentStrings(ByVal value)
	Dim oWshShell
	Set oWshShell = CreateObject("WScript.Shell")
	
	ExpandEnvironmentStrings = oWshShell.ExpandEnvironmentStrings(value)
	Set oWshShell = Nothing
End Function

Class RegistryClass
	Private m_Registry

	Private Sub Class_Initialize
		Set m_Registry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
	End Sub

	Public Property Get HIVE_CLASSES_ROOT
		HIVE_CLASSES_ROOT = &H80000000
	End Property
	Public Property Get HIVE_CURRENT_USER
		HIVE_CURRENT_USER = &H80000001
	End Property
	Public Property Get HIVE_LOCAL_MACHINE
		HIVE_LOCAL_MACHINE = &H80000002
	End Property
	Public Property Get HIVE_USERS
		HIVE_USERS = &H80000003
	End Property
	
	Public Property Get TYPE_SZ
		TYPE_SZ = 1
	End Property
	Public Property Get TYPE_EXPAND_SZ
		TYPE_EXPAND_SZ = 2
	End Property
	Public Property Get TYPE_BINARY
		TYPE_BINARY = 3
	End Property
	Public Property Get TYPE_DWORD
		TYPE_DWORD = 4
	End Property
	Public Property Get TYPE_MULTI_SZ
		TYPE_MULTI_SZ = 7
	End Property

	Public Function KeyExists(sRegPath)
		Dim hive, sKeyPath
		KeyExists = false
		
		If (GetHiveFromPath(sRegPath, hive)) Then
			sKeyPath = UCase(Mid(sRegPath, InStr(sRegPath, "\")+1))
			KeyExists = Reg_KeyExists(hive, sKeyPath)
		End If
	End Function

	Public Function SetEntry(sRegPath, sEntryName, value, iType)
		On Error Resume Next
		Dim hive, sKeyPath, rc
		SetEntry = false
		
		If (NOT CreateKey(sRegPath)) Then Exit Function
		
		If (NOT GetHiveFromPath(sRegPath, hive)) Then Exit Function
		sKeyPath = UCase(Mid(sRegPath, InStr(sRegPath, "\")+1))
		
		Err.Clear
		Select Case iType
		Case TYPE_SZ
			rc = m_Registry.SetStringValue(hive, sKeyPath, sEntryName, value)
		Case TYPE_EXPAND_SZ
			rc = m_Registry.SetExpandedStringValue(hive, sKeyPath, sEntryName, value)
		Case TYPE_BINARY
			rc = m_Registry.SetBinaryValue(hive, sKeyPath, sEntryName, value)
		Case TYPE_DWORD
			rc = m_Registry.SetDWORDValue(hive, sKeyPath, sEntryName, value)
		Case TYPE_MULTI_SZ
			rc = m_Registry.SetMultiStringValue(hive, sKeyPath, sEntryName, value)
		Case Else
			Exit Function
		End Select
		
		If ((rc = 0) And (Err = 0)) Then SetEntry = true
	End Function

	Public Function CreateKey(sRegPath)
		On Error Resume Next
		Dim hive, sKeyPath, rc
		CreateKey = false
		
		If (KeyExists(sRegPath)) Then
			CreateKey = true
			Exit Function
		End If
		
		If (NOT GetHiveFromPath(sRegPath, hive)) Then Exit Function
		sKeyPath = UCase(Mid(sRegPath, InStr(sRegPath, "\")+1))
		
		Err.Clear
		rc = m_Registry.CreateKey(hive, sKeyPath)
		If (rc = 0) And (Err = 0) Then CreateKey = true
	End Function

	Private Function GetHiveFromPath(sRegPath, hive)
		Dim hiveString
		GetHiveFromPath = true
		
		hiveString = UCase(Mid(sRegPath, 1, InStr(sRegPath, "\")-1))
		
		Select Case(hiveString)
			Case "HKEY_CLASSES_ROOT", "HKCR"
				hive = HIVE_CLASSES_ROOT
			Case "HKEY_CURRENT_USER", "HKCU"
				hive = HIVE_CURRENT_USER
			Case "HKEY_LOCAL_MACHINE", "HKLM"
				hive = HIVE_LOCAL_MACHINE
			Case "HKEY_USERS", "HKU"
				hive = HIVE_USERS
			Case Else
				GetHiveFromPath = false
		End Select
	End Function

	Private Sub Class_Terminate
		Set m_Registry = Nothing
	End Sub
End Class

SOLUTION
ManelR's picture

:-(

Wow ... I've done this kind of wrapper a lot of times in a non-virtual apps and I've not thinked on this solution with SWV ...

Thanks for the tip.

 

IT Systems Manager
LCFIB - Computing Lab
Barcelona School of Informatics
Universitat Politècnica de Catalunya - Barcelona Tech