Question Trusted Locations (Access specifically 2016)

ryetee

Registered User.
Local time
Today, 21:47
Joined
Jul 30, 2013
Messages
952
So how does trusted locations work.

I thought, maybe naively, that if I added trusted locations in the development phase they would be available in production.

That doesn't seem to be the case.
The latest production front end is held on a server. This happens to be the C: drive. Let's call the location C:\PRODVERSION

Users log onto the server and can actually see this folder.
They run a script file which copies the program from C:\PRODVERSION into their own unique folder C:\USERCOPY.

The trusted locations don't seem to be copied over.
Where are the trusted locations actually stored?

Actually if I'm in USER1 for example and I fill in the trusted locations in C:\PRODVERSION it will copy the trusted locations over to C:\USER1COPY
If I then log on as USER2 and look at the PRODVERSION I can't see the trusted locations input when signed on as USER2
 
Last edited:
The trusted locations are not a part of the Access database and so don't copy with it. Trusted locations are added to the registry of the computer where you set them. Therefore, they would need to be set on EVERY computer where you install the app.

So, depending on how many users you have and how you distribute this, there are several options.
1. This is a product for sale or for distribution in a company where you have no control over anything - purchase a product called SageKey - it's a little pricey and it requires a new purchase each time you change Access versions which I dislike. But, it will provide a smooth, professional installation.
2. If you are distributing internally and the Network staff is willing, have them distribute the registry keys to all your users as part of their start up script.
3. Manually set the trusted locations for each user. This works only if everyone has the full version. You can't get there from here using the runtime.
4. Manually edit the registry for each person.
5. Send out a script to update the registry to each person.
6. Add some code to your Access app to modify the registry. I don't have a sample handy but they aren't hard to find.
 
If you have savvy users I believe they could add the location as trusted in Word or Excel if they only have Runtime Access , and it propogates for all office apps?

/caveat/ I may be talking complete bobbins /caveat/
 
The trusted locations are not a part of the Access database and so don't copy with it. Trusted locations are added to the registry of the computer where you set them. Therefore, they would need to be set on EVERY computer where you install the app.

So, depending on how many users you have and how you distribute this, there are several options.
1. This is a product for sale or for distribution in a company where you have no control over anything - purchase a product called SageKey - it's a little pricey and it requires a new purchase each time you change Access versions which I dislike. But, it will provide a smooth, professional installation.
2. If you are distributing internally and the Network staff is willing, have them distribute the registry keys to all your users as part of their start up script.
3. Manually set the trusted locations for each user. This works only if everyone has the full version. You can't get there from here using the runtime.
4. Manually edit the registry for each person.
5. Send out a script to update the registry to each person.
6. Add some code to your Access app to modify the registry. I don't have a sample handy but they aren't hard to find.
OK so once it's set up for USER for specific version of access I never have ti set it up again? I like the idea of 5. I've never edited the registry from a script. I presume there are many examples out there I can crib.
I have a script already that copies the prodversion to the users desktop. This script deletes and replaces files. If this script edits the registry as well would I have to delete the entry first and replace or can I just add (many times).
 
If you have savvy users I believe they could add the location as trusted in Word or Excel if they only have Runtime Access , and it propogates for all office apps?

/caveat/ I may be talking complete bobbins /caveat/

It's a pretty simple set up. They don't have word/excel!!
 
I don't believe the trusted locations are shared with Word and Excel. You would have to specify separate registry entries for each product.

I've attached three documents that will help. BE CAREFUL with the .reg document. DO NOT DOUBLE CLICK ON IT.Right click and choose edit or open Notepad and then open it. This file contains actual registry updates but you would need to customize them to your own path names. I had to zip it because the site would not accept it as a .reg file type.
 

Attachments

1. To confirm Pat's comment, trusted locations are NOT shared by different Office programs.
For Access the values are stored using a registry key ...Access\Security\Trusted Locations

2. I find the easiest way to set trusted locations is to include a script to do this as part of the install file routine. For example all my applications are installed to subfolders of "C:\Programs\MendipDataSystems", so I use the script below which assigns this folder & all subfolders for each version of Access from 2007 onwards

Code:
/trusted locations
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\14.0\Access\Security\Trusted Locations\Location10 :: Path="C:\Programs\MendipDataSystems\"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\14.0\Access\Security\Trusted Locations\Location10 :: AllowSubFolders=1
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\14.0\Access\Security\Trusted Locations\Location10 :: Description="Mendip Data Systems"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\14.0\Access\Security\Trusted Locations\Location10 :: Date="08/12/2015 19:51"

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\12.0\Access\Security\Trusted Locations\Location10 :: Path="C:\Programs\MendipDataSystems\"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\12.0\Access\Security\Trusted Locations\Location10 :: AllowSubFolders=1
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\12.0\Access\Security\Trusted Locations\Location10 :: Description="Mendip Data Systems"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\12.0\Access\Security\Trusted Locations\Location10 :: Date="27/04/2014 19:51"

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\15.0\Access\Security\Trusted Locations\Location10 :: Path="C:\Programs\MendipDataSystems\"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\15.0\Access\Security\Trusted Locations\Location10 :: AllowSubFolders=1
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\15.0\Access\Security\Trusted Locations\Location10 :: Description="Mendip Data Systems"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\15.0\Access\Security\Trusted Locations\Location10 :: Date="27/04/2014 19:51"

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Access\Security\Trusted Locations\Location11 :: Path="C:\Programs\MendipDataSystems\"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Access\Security\Trusted Locations\Location11 :: AllowSubFolders=1
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Access\Security\Trusted Locations\Location11 :: Description="Mendip Data Systems"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Access\Security\Trusted Locations\Location11 :: Date="08/12/2015 19:51"

3. During installation, information about the application such as version info, registered user info, licence key & support expiry date is saved to the registry.

When the applications runs for the first time this info is read back from the registry to the application & saved in a settings table.

This means that for subsequent logins (admin users only), the app can check whether:
a) the support period is about to expire
b) a newer version is available to download .... etc
If any of these checks are true, the user is automatically alerted
 
Last edited:
While we're at it, here's a quick module I came up with a while back for some basic reg tasks via VBA. It worked surprisingly well (I've re-used it numerous times since then). Name the module 'Registry' per my usual two-part naming convention

Could probably convert to VBScript easily enough if you wanted to.

Ideally something like this would be tossed into a launcher app of some sort (you can't exactly update the trusted location from within the app you need the trusted location set from...).

Reg file might be easier: installers typically handle this stuff well also. Thought I'd throw it out here anyway though.

(side note: anyone else feel like trusted locations are pretty much pointless being they can be so easily set from code? oh well...)

Code:
Option Compare Database
Option Explicit

' jleach@dymeng, Feb 2015
' handles some registry stuff via WMI
' v1.0
' all breaking changes must increment the major version number
'
' https://msdn.microsoft.com/en-us/library/aa394600(v=vs.85).aspx
'
' should probably set it up to run silent... maybe v1.1

Public Enum RegistryHives
  HKCR = &H80000000   'HKEY_CLASSES_ROOT
  HKCU = &H80000001   'HKEY_CURRENT_USER
  HKLM = &H80000002   'HKEY_LOCAL_MACHINE
  HKU = &H80000003    'HKEY_USERS
  HKCC = &H80000005   'HKEY_CURRENT_CONFIG
  HKDD = &H80000006   'HKEY_DYN_DATA
End Enum

Public Enum RegValueTypes
  REG_ANY = 0
  REG_SZ = 1
  REG_EXPAND_SZ = 2
  REG_BINARY = 3
  REG_DWORD = 4
  REG_MULTI_SZ = 7
  REG_QWORD = 11
End Enum



Public Function GetDWORDValue(Hive As RegistryHives, ByVal KeyPath As String, ValueName As String) As Long
On Error GoTo Err_Proc
'=========================
  Dim ret As Long
  Dim reg As Object
'=========================

  If Left(KeyPath, 1) = "\" Then KeyPath = Mid(KeyPath, 2)
  If Right(KeyPath, 1) = "\" Then KeyPath = Left(KeyPath, Len(KeyPath) - 1)

  If Not Registry.ValueExists(Hive, KeyPath, ValueName) Then Err.Raise vbObjectError + 1, , "Value doesn't exists."
  If Not Registry.KeyExists(Hive, KeyPath) Then Err.Raise vbObjectError + 2, , "Key doesn't exist."

  Set reg = GetReg()
  
  reg.GetDWORDValue Hive, KeyPath, ValueName, ret

'=========================
Exit_Proc:
  Set reg = Nothing
  GetDWORDValue = ret
  Exit Function
Err_Proc:
  Err.Source = "Registry.GetDWORDValue"
  Select Case Err.Number
    Case Else
      MsgBox Err.Number & ": " & Err.Description
  End Select
  Resume Exit_Proc
  Resume
End Function


Public Function CreateDWORDValue(Hive As RegistryHives, ByVal KeyPath As String, ValueName As String, Value As Long) As Boolean
On Error GoTo Err_Proc
'=========================
  Dim ret As Boolean
  Dim reg As Object
'=========================

  'remove leading and trailing \ if they exist
  If Left(KeyPath, 1) = "\" Then KeyPath = Mid(KeyPath, 2)
  If Right(KeyPath, 1) = "\" Then KeyPath = Left(KeyPath, Len(KeyPath) - 1)

  If Registry.ValueExists(Hive, KeyPath, ValueName) Then Err.Raise vbObjectError + 1, , "Value already exists."
  If Not Registry.KeyExists(Hive, KeyPath) Then Err.Raise vbObjectError + 2, , "Key doesn't exist."
  
  Set reg = GetReg()
  
  ret = Not CBool(reg.SetDWORDValue(Hive, KeyPath, ValueName, Value))
  
'=========================
Exit_Proc:
  Set reg = Nothing
  CreateDWORDValue = ret
  Exit Function
Err_Proc:
  Err.Source = "Registry.CreateValue"
  Select Case Err.Number
    Case vbObjectError + 1
      MsgBox "Specified value already exists"
    Case vbObjectError + 2
      MsgBox "Key does not exist.  Please create it first."
    Case Else
      MsgBox Err.Number & ": " & Err.Description
  End Select
  Resume Exit_Proc
  Resume
End Function


Public Function ValueExists( _
      Hive As RegistryHives, _
      ByVal KeyPath As String, _
      ValueName As String, _
      Optional ValueType As RegValueTypes = RegValueTypes.REG_ANY _
) As Boolean
On Error GoTo Err_Proc
'=========================
  Dim ret As Boolean
  Dim reg As Object
  Dim Values() As Variant
  Dim ValueTypes() As Variant
  Dim v As Variant
  Dim vt As Variant
  Dim i As Integer
'=========================

  'remove leading and trailing \ if they exist
  If Left(KeyPath, 1) = "\" Then KeyPath = Mid(KeyPath, 2)
  If Right(KeyPath, 1) = "\" Then KeyPath = Left(KeyPath, Len(KeyPath) - 1)

  If Not Registry.KeyExists(Hive, KeyPath) Then GoTo Exit_Proc

  Set reg = GetReg()
  
  reg.EnumValues Hive, KeyPath, Values, ValueTypes
  
  For i = 0 To UBound(ValueTypes)
    If CStr(Values(i)) = ValueName Then
      If ValueType = REG_ANY Then
        ret = True
        GoTo Exit_Proc
      Else
        If CLng(ValueTypes(i)) = CLng(ValueType) Then
          ret = True
          GoTo Exit_Proc
        End If
      End If
    End If
  Next
  
'=========================
Exit_Proc:
  Set reg = Nothing
  ValueExists = ret
  Exit Function
Err_Proc:
  Err.Source = "Registry.ValueExists"
  Select Case Err.Number
    Case Else
      MsgBox Err.Number & ": " & Err.Description
  End Select
  Resume Exit_Proc
  Resume
End Function


Public Function CreateKey(Hive As RegistryHives, ByVal KeyPath As String) As Boolean
On Error GoTo Err_Proc
'=========================
  Dim ret As Boolean
  Dim reg As Object
'=========================

  'remove leading and trailing \ if they exist
  If Left(KeyPath, 1) = "\" Then KeyPath = Mid(KeyPath, 2)
  If Right(KeyPath, 1) = "\" Then KeyPath = Left(KeyPath, Len(KeyPath) - 1)
  
  Set reg = GetReg()
  
  ret = Not CBool(reg.CreateKey(Hive, KeyPath))

'=========================
Exit_Proc:
  Set reg = Nothing
  CreateKey = ret
  Exit Function
Err_Proc:
  Err.Source = "Registry.CreateKey"
  Select Case Err.Number
    Case Else
      MsgBox Err.Number & ": " & Err.Description
  End Select
  Resume Exit_Proc
  Resume
End Function


Public Function KeyExists(Hive As RegistryHives, ByVal KeyPath As String) As Boolean
On Error GoTo Err_Proc
'=========================
  Dim ret As Boolean
  Dim reg As Object
  Dim ParentPath As String
  Dim Subkey As String
  Dim x As Long
  Dim Subkeys() As Variant
  Dim v As Variant
'=========================


  If Right(KeyPath, 1) = "\" Then KeyPath = Left(KeyPath, Len(KeyPath) - 1) 'remove trailing \ if present
  
  ParentPath = Mid(KeyPath, 1, InStrRev(KeyPath, "\"))
  Subkey = Mid(KeyPath, InStrRev(KeyPath, "\") + 1)
  
  'remove leading \ if present
  If Left(ParentPath, 1) = "\" Then ParentPath = Mid(ParentPath, 2)
  
  Set reg = GetReg()
  
  If reg.EnumKey(Hive, ParentPath, Subkeys) <> 0 Then GoTo Exit_Proc
  
  For Each v In Subkeys
    If CStr(v) = Subkey Then
      ret = True
      GoTo Exit_Proc
    End If
  Next

'=========================
Exit_Proc:
  Set reg = Nothing
  KeyExists = ret
  Exit Function
Err_Proc:
  Err.Source = "Registry.KeyExists"
  Select Case Err.Number
    Case Else
      MsgBox Err.Number & ": " & Err.Description
  End Select
  Resume Exit_Proc
  Resume
End Function


Private Function GetReg() As Object
  Set GetReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
End Function
 
Last edited:
Jack

Your code sample is very similar to mine (inevitably as they are doing much the same...)

I normally store program & user settings in HKCU rather than HKLM
The reason is that I've had issues getting elevated permissions needed for HKLM to work reliably for all computers using installer script files.

Have you a solution for that?
 
Have you a solution for that?

Nope. HKCU it is, where we can (exactly for that reason). My module allows you to specify any of the hives, but generally with in-app reg settings we're working in CU anyway (otherwise LM hive work has a natural tenancy to be better fitted for installer packages, where it's more expected to require admin privs)

Cheers
 
Nope. HKCU it is, where we can (exactly for that reason). My module allows you to specify any of the hives, but generally with in-app reg settings we're working in CU anyway (otherwise LM hive work has a natural tenancy to be better fitted for installer packages, where it's more expected to require admin privs)

Cheers

I was referring to scripts run during installer routines as well as to SQL Server scripts. Sometimes HKLM works but I could never guarantee it would do so...
 
Oh, sorry I thought you meant whether we should prefer HKCU or HKLM.

I'm not an expert on this and going off the top of my head, but I believe you're correct that you can't guarantee HKLM will be generally manageable without elevated privileges.

As to how to achieve that, usually the installer should take care of making sure it runs elevated (you can run a batch file that requests elevated privileges, but the installer itself should be able to dictate that), and typically you would wrap up the scripts within the installer and call them with the installer, in which case those scripts should inherit the installer's elevated privileges.

Still not sure if I understood what you're after. Maybe a separate thread so we don't bring this any further off topic?
 
Still not sure if I understood what you're after. Maybe a separate thread so we don't bring this any further off topic?

Thanks but no need. Your answers confirmed what I thought to be true
 
I don't believe the trusted locations are shared with Word and Excel. You would have to specify separate registry entries for each product.

I've attached three documents that will help. BE CAREFUL with the .reg document. DO NOT DOUBLE CLICK ON IT.Right click and choose edit or open Notepad and then open it. This file contains actual registry updates but you would need to customize them to your own path names. I had to zip it because the site would not accept it as a .reg file type.

Billiant - thanks. Not sure I have the spheroids to do this but this is a great help!
 
1. To confirm Pat's comment, trusted locations are NOT shared by different Office programs.
For Access the values are stored using a registry key ...Access\Security\Trusted Locations

2. I find the easiest way to set trusted locations is to include a script to do this as part of the install file routine. For example all my applications are installed to subfolders of "C:\Programs\MendipDataSystems", so I use the script below which assigns this folder & all subfolders for each version of Access from 2007 onwards

Code:
/trusted locations
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\14.0\Access\Security\Trusted Locations\Location10 :: Path="C:\Programs\MendipDataSystems\"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\14.0\Access\Security\Trusted Locations\Location10 :: AllowSubFolders=1
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\14.0\Access\Security\Trusted Locations\Location10 :: Description="Mendip Data Systems"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\14.0\Access\Security\Trusted Locations\Location10 :: Date="08/12/2015 19:51"

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\12.0\Access\Security\Trusted Locations\Location10 :: Path="C:\Programs\MendipDataSystems\"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\12.0\Access\Security\Trusted Locations\Location10 :: AllowSubFolders=1
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\12.0\Access\Security\Trusted Locations\Location10 :: Description="Mendip Data Systems"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\12.0\Access\Security\Trusted Locations\Location10 :: Date="27/04/2014 19:51"

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\15.0\Access\Security\Trusted Locations\Location10 :: Path="C:\Programs\MendipDataSystems\"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\15.0\Access\Security\Trusted Locations\Location10 :: AllowSubFolders=1
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\15.0\Access\Security\Trusted Locations\Location10 :: Description="Mendip Data Systems"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\15.0\Access\Security\Trusted Locations\Location10 :: Date="27/04/2014 19:51"

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Access\Security\Trusted Locations\Location11 :: Path="C:\Programs\MendipDataSystems\"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Access\Security\Trusted Locations\Location11 :: AllowSubFolders=1
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Access\Security\Trusted Locations\Location11 :: Description="Mendip Data Systems"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Access\Security\Trusted Locations\Location11 :: Date="08/12/2015 19:51"

3. During installation, information about the application such as version info, registered user info, licence key & support expiry date is saved to the registry.

When the applications runs for the first time this info is read back from the registry to the application & saved in a settings table.

This means that for subsequent logins (admin users only), the app can check whether:
a) the support period is about to expire
b) a newer version is available to download .... etc
If any of these checks are true, the user is automatically alerted
Thanks Ridders - so ca I stick this in a VBS file then and can I leave it in - i.e. does it matter it's 'run' more than once?
 
While we're at it, here's a quick module I came up with a while back for some basic reg tasks via VBA. It worked surprisingly well (I've re-used it numerous times since then). Name the module 'Registry' per my usual two-part naming convention

Could probably convert to VBScript easily enough if you wanted to.

Ideally something like this would be tossed into a launcher app of some sort (you can't exactly update the trusted location from within the app you need the trusted location set from...).

Reg file might be easier: installers typically handle this stuff well also. Thought I'd throw it out here anyway though.

(side note: anyone else feel like trusted locations are pretty much pointless being they can be so easily set from code? oh well...)

Code:
Option Compare Database
Option Explicit

' jleach@dymeng, Feb 2015
' handles some registry stuff via WMI
' v1.0
' all breaking changes must increment the major version number
'
' https://msdn.microsoft.com/en-us/library/aa394600(v=vs.85).aspx
'
' should probably set it up to run silent... maybe v1.1

Public Enum RegistryHives
  HKCR = &H80000000   'HKEY_CLASSES_ROOT
  HKCU = &H80000001   'HKEY_CURRENT_USER
  HKLM = &H80000002   'HKEY_LOCAL_MACHINE
  HKU = &H80000003    'HKEY_USERS
  HKCC = &H80000005   'HKEY_CURRENT_CONFIG
  HKDD = &H80000006   'HKEY_DYN_DATA
End Enum

Public Enum RegValueTypes
  REG_ANY = 0
  REG_SZ = 1
  REG_EXPAND_SZ = 2
  REG_BINARY = 3
  REG_DWORD = 4
  REG_MULTI_SZ = 7
  REG_QWORD = 11
End Enum



Public Function GetDWORDValue(Hive As RegistryHives, ByVal KeyPath As String, ValueName As String) As Long
On Error GoTo Err_Proc
'=========================
  Dim ret As Long
  Dim reg As Object
'=========================

  If Left(KeyPath, 1) = "\" Then KeyPath = Mid(KeyPath, 2)
  If Right(KeyPath, 1) = "\" Then KeyPath = Left(KeyPath, Len(KeyPath) - 1)

  If Not Registry.ValueExists(Hive, KeyPath, ValueName) Then Err.Raise vbObjectError + 1, , "Value doesn't exists."
  If Not Registry.KeyExists(Hive, KeyPath) Then Err.Raise vbObjectError + 2, , "Key doesn't exist."

  Set reg = GetReg()
  
  reg.GetDWORDValue Hive, KeyPath, ValueName, ret

'=========================
Exit_Proc:
  Set reg = Nothing
  GetDWORDValue = ret
  Exit Function
Err_Proc:
  Err.Source = "Registry.GetDWORDValue"
  Select Case Err.Number
    Case Else
      MsgBox Err.Number & ": " & Err.Description
  End Select
  Resume Exit_Proc
  Resume
End Function


Public Function CreateDWORDValue(Hive As RegistryHives, ByVal KeyPath As String, ValueName As String, Value As Long) As Boolean
On Error GoTo Err_Proc
'=========================
  Dim ret As Boolean
  Dim reg As Object
'=========================

  'remove leading and trailing \ if they exist
  If Left(KeyPath, 1) = "\" Then KeyPath = Mid(KeyPath, 2)
  If Right(KeyPath, 1) = "\" Then KeyPath = Left(KeyPath, Len(KeyPath) - 1)

  If Registry.ValueExists(Hive, KeyPath, ValueName) Then Err.Raise vbObjectError + 1, , "Value already exists."
  If Not Registry.KeyExists(Hive, KeyPath) Then Err.Raise vbObjectError + 2, , "Key doesn't exist."
  
  Set reg = GetReg()
  
  ret = Not CBool(reg.SetDWORDValue(Hive, KeyPath, ValueName, Value))
  
'=========================
Exit_Proc:
  Set reg = Nothing
  CreateDWORDValue = ret
  Exit Function
Err_Proc:
  Err.Source = "Registry.CreateValue"
  Select Case Err.Number
    Case vbObjectError + 1
      MsgBox "Specified value already exists"
    Case vbObjectError + 2
      MsgBox "Key does not exist.  Please create it first."
    Case Else
      MsgBox Err.Number & ": " & Err.Description
  End Select
  Resume Exit_Proc
  Resume
End Function


Public Function ValueExists( _
      Hive As RegistryHives, _
      ByVal KeyPath As String, _
      ValueName As String, _
      Optional ValueType As RegValueTypes = RegValueTypes.REG_ANY _
) As Boolean
On Error GoTo Err_Proc
'=========================
  Dim ret As Boolean
  Dim reg As Object
  Dim Values() As Variant
  Dim ValueTypes() As Variant
  Dim v As Variant
  Dim vt As Variant
  Dim i As Integer
'=========================

  'remove leading and trailing \ if they exist
  If Left(KeyPath, 1) = "\" Then KeyPath = Mid(KeyPath, 2)
  If Right(KeyPath, 1) = "\" Then KeyPath = Left(KeyPath, Len(KeyPath) - 1)

  If Not Registry.KeyExists(Hive, KeyPath) Then GoTo Exit_Proc

  Set reg = GetReg()
  
  reg.EnumValues Hive, KeyPath, Values, ValueTypes
  
  For i = 0 To UBound(ValueTypes)
    If CStr(Values(i)) = ValueName Then
      If ValueType = REG_ANY Then
        ret = True
        GoTo Exit_Proc
      Else
        If CLng(ValueTypes(i)) = CLng(ValueType) Then
          ret = True
          GoTo Exit_Proc
        End If
      End If
    End If
  Next
  
'=========================
Exit_Proc:
  Set reg = Nothing
  ValueExists = ret
  Exit Function
Err_Proc:
  Err.Source = "Registry.ValueExists"
  Select Case Err.Number
    Case Else
      MsgBox Err.Number & ": " & Err.Description
  End Select
  Resume Exit_Proc
  Resume
End Function


Public Function CreateKey(Hive As RegistryHives, ByVal KeyPath As String) As Boolean
On Error GoTo Err_Proc
'=========================
  Dim ret As Boolean
  Dim reg As Object
'=========================

  'remove leading and trailing \ if they exist
  If Left(KeyPath, 1) = "\" Then KeyPath = Mid(KeyPath, 2)
  If Right(KeyPath, 1) = "\" Then KeyPath = Left(KeyPath, Len(KeyPath) - 1)
  
  Set reg = GetReg()
  
  ret = Not CBool(reg.CreateKey(Hive, KeyPath))

'=========================
Exit_Proc:
  Set reg = Nothing
  CreateKey = ret
  Exit Function
Err_Proc:
  Err.Source = "Registry.CreateKey"
  Select Case Err.Number
    Case Else
      MsgBox Err.Number & ": " & Err.Description
  End Select
  Resume Exit_Proc
  Resume
End Function


Public Function KeyExists(Hive As RegistryHives, ByVal KeyPath As String) As Boolean
On Error GoTo Err_Proc
'=========================
  Dim ret As Boolean
  Dim reg As Object
  Dim ParentPath As String
  Dim Subkey As String
  Dim x As Long
  Dim Subkeys() As Variant
  Dim v As Variant
'=========================


  If Right(KeyPath, 1) = "\" Then KeyPath = Left(KeyPath, Len(KeyPath) - 1) 'remove trailing \ if present
  
  ParentPath = Mid(KeyPath, 1, InStrRev(KeyPath, "\"))
  Subkey = Mid(KeyPath, InStrRev(KeyPath, "\") + 1)
  
  'remove leading \ if present
  If Left(ParentPath, 1) = "\" Then ParentPath = Mid(ParentPath, 2)
  
  Set reg = GetReg()
  
  If reg.EnumKey(Hive, ParentPath, Subkeys) <> 0 Then GoTo Exit_Proc
  
  For Each v In Subkeys
    If CStr(v) = Subkey Then
      ret = True
      GoTo Exit_Proc
    End If
  Next

'=========================
Exit_Proc:
  Set reg = Nothing
  KeyExists = ret
  Exit Function
Err_Proc:
  Err.Source = "Registry.KeyExists"
  Select Case Err.Number
    Case Else
      MsgBox Err.Number & ": " & Err.Description
  End Select
  Resume Exit_Proc
  Resume
End Function


Private Function GetReg() As Object
  Set GetReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
End Function


Thanks for this! I'll take a closer look in the morning.
 
Thanks Ridders - so ca I stick this in a VBS file then and can I leave it in - i.e. does it matter it's 'run' more than once?

Yes, yes and no in that order.

Obviously you need to change the folder and description lines.
If you don't want subfolders to be trusted, that line should be 0
 
Running the registry updates more than once won't hurt but you don't want to run the samples we gave you. You need to modify them first. Hence the warning.
 

Users who are viewing this thread

Back
Top Bottom