Access to the registry key '[KEY_NAME]' is denied - vb.net

I'm writing a small program in Visual Basic 2008 that flips the values of specific DWORDs in a registry key
The registry key in question is:
'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties'
The dword I'm manipulating is "{e0a941a0-88a2-4df5-8d6b-dd20bb06e8fb},4"
This is the line of code I wrote to set the DWORD's value is this:
Dim keyString = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties"
My.Computer.Registry.SetValue(keyString, "{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2", "00000000")
But I get a UnauthorizedAccessException at runtime stating that "Access to the registry key [KEY_NAME] is denied."
I ran the program with Administrator privileges, changed the app's manifest to include:
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
But that didn't work either. So I searched a few forums and tried this:
Dim rkLM As RegistryKey = Registry.LocalMachine
Dim pRegKey As RegistryKey = rkLM.OpenSubKey("\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties", True)
pRegKey.SetValue("{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2", "00000000")
But that threw a NullReferenceException at me stating "Object reference not set to an instance of an object."
Is there any way I can modify that that key without having to run my program with SYSTEM privileges?

You should probably try with requireAdministrator in your manifest because highestAvailable may not actually be an administrator.
I would also try specifying the data type (in your case I think it is binary):
My.Computer.Registry.SetValue(keyString, _
"{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2", _
"00000000", _
RegistryValueKind.Binary)
However the value you are setting may need to be a byte array (something else you could try)

Thanks Matt, I tried running it with requireAdministrator as well but that didn't help either. Anyway, I found the solution to this and it seems the problem lied with the permissions on the registry key that I was trying to modify.
Full Control access was only given to the TrustedInstaller group, so I granted Full Control to the users in the Administrators group as well.
I started 'regedit' with SYSTEM privileges using Sysinternals' PsExec tool
[psexec -si regedit] and navigated to the key I wished to manipulate using my program and used [Edit -> Permissions] to grant write access to myself.
After doing that, my code worked and this:
Dim keyString = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\" _
+ "MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties"
Dim regKey = "{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2"
My.Computer.Registry.SetValue( _
keyString, regKey, "00000000", RegistryValueKind.DWord)
could successfully flip the value of the DWORD. Although this worked, I would like to know if there's a way to do this without having to manually change permissions on the registry subkey.
I found a similar problem and solution for this in C# given here but I couldn't successfully convert the C# code mentioned there to VB.NET code. Could you help with that?

Here is the vb.net code for the c# link referenced below. You will need to set a reference to System.Security.
Imports System.Security
Imports System.Security.Principal
Imports System.Security.AccessControl
Imports Microsoft.Win32
Private Sub TestMethod(ByVal subkey As String)
' Create access rule giving full control to the Administrator user.
Dim rs As New RegistrySecurity()
rs.AddAccessRule( New RegistryAccessRule( _
"Administrator", _
RegistryRights.FullControl, _
InheritanceFlags.ContainerInherit Or InheritanceFlags.ObjectInherit, _
PropagationFlags.InheritOnly, _
AccessControlType.Allow))
' Get the registry key desired with ChangePermissions Rights.
Dim rk As RegistryKey = Registry.LocalMachine.OpenSubKey( _
subkey, _
RegistryKeyPermissionCheck.ReadWriteSubTree, _
RegistryRights.ChangePermissions Or RegistryRights.ReadKey)
' Apply the new access rule to this Registry Key.
rk.SetAccessControl(rs)
' Get the registry key desired with ChangePermissions Rights.
rk = Registry.LocalMachine.OpenSubKey( _
subkey, _
RegistryKeyPermissionCheck.ReadWriteSubTree, _
RegistryRights.ChangePermissions Or RegistryRights.ReadKey)
' Apply the new access rule to this Registry Key.
rk.SetAccessControl(rs)
' Open the key again with full control.
rk = Registry.LocalMachine.OpenSubKey( _
subkey, _
RegistryKeyPermissionCheck.ReadWriteSubTree, _
RegistryRights.FullControl)
' Set the security's owner to be Administrator.
rs.SetOwner(New NTAccount("Administrator"))
' Set the key with the changed permission so Administrator is now owner.
rk.SetAccessControl(rs)
End Sub

I had this same problem, and setting requireAdministrator didn't help. Then I realized VS2010 never asked me to restart with Administrative rights. I closed and reopened VS2010, ran the program, and then it asked me to start with Administrative privileges. I'm used to changing to requireAdministrator and it asking me to restart at the next time I debug.
So, to clarify, requireAdministrator does help, but may require a manual restart of VS2010 (or just run VS2010 as Administrator).

Related

Setting MS Access password at runtime in vb.net designer generated system

I am developing a VB.NET update system for a volunteer organisation’s MS Access database. The database is protected by a password as it contains personal information. I have created the application using the VB designer. I need to be able to code the application so that, if the owner decides to change the MS Access password, they will have no need to come back to me to change the code and rebuild the solution. In other words, I do not want the password to be hard coded in the app.config file or the settings.designer.vb file. My code should not need to know the password as a simple call to one of the Fill functions can test any password entered by the user. My problem is that I have found no way to alter the connection string that is tested in the setttings.designer.vb code whenever the database is accessed. I am using Visual Studio 2017.
I have spent a long time searching the web for answers and have tried various solutions involving the configurationmanager without success. I am new to this area so I would be most grateful if anyone here can help.
Here is my latest attempt which still produces an invalid password error even though the third debug statement suggests that the connection string, including the password, has been correctly set.
Public Sub UpdateConnString(connString As String)
Dim configFileMap As New ExeConfigurationFileMap()
Dim config As Configuration = ConfigurationManager.OpenExeConfiguration(configFileMap.ExeConfigFilename)
Dim connStringName As String = "TestConnectionString"
Debug.Print("0 " + config.ConnectionStrings.ConnectionStrings(connStringName).ConnectionString)
config.ConnectionStrings.ConnectionStrings(connStringName).ConnectionString = connString
Debug.Print("1 " + config.ConnectionStrings.ConnectionStrings(connStringName).ConnectionString)
config.Save(ConfigurationSaveMode.Modified, True)
Debug.Print("2 " + config.ConnectionStrings.ConnectionStrings(connStringName).ConnectionString)
End Sub
Just because a connection string is stored in the config file, you aren't required to use it as it is. You can read in that default value and then edit it before using it, e.g.
Dim builder As New OleDbConnectionStringBuilder(My.Settings.DefaultConnectionString)
builder.DataSource = dataSource
Dim connectionString = builder.ConnectionString
You can add or modify any part of a connection string you want that way at run time.
Thank you for your response. Unfortunately, the code throws a compilation error - "DefaultConnectionString is not a member of My.Settings".
Fortunatley I have now managed to find a working solution:
'My.Settings.Item("TestConnectionString") = connectionString

Change system registry values on vb.net

I want to change my computer's system registry value via vb.net
Dim regKey As RegistryKey
regKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Ole", True)
regKey.SetValue("EnableDCOM", "Y")
regKey.Close()
I've tried the above, however it gives no error but it simply doesn't change the value...
I hardly use VB, but I believe the below is the correct approach.
Dim autoshell = My.Computer.Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows NT\CurrentVersion\Winlogon", True)
'' Set the value to 0
autoshell.SetValue("autorestartshell", 0)
autoshell.Close()
If you experience errors, you need to check that:
You have permissions to read/write to the registry.
The subkey you are trying to change actually exists.
You should also consult the MSDN VB Documentation.

UnauthorizedAccessException with File.AppendAllText in VB.NET

I have recently started getting System.UnauthorizedAccessException errors when using File.AppendAllText to write to a shared drive on the network. I think there were some changes to the network when this happened. The code in my application hasn't changed.
I have asked our IT dept to grant me full permission to the folder. I can see I have permissions for Modify, Read & Execute, Read, Write under my username if I navigate to the file and look at the Security tab under properties. I am also part of a group with read, write and modify permissions to the folder.
This works without error in the same folder:
File.WriteAllText(myFile, myText)
This generates a System.UnauthorizedAccessException error when it reaches the AppendallText:
If File.Exists(myFile) = False Then
' Create a file to write to.
Dim createText As String = logTime & " " & report_data
File.WriteAllText(myFile, createText)
Else
Dim appendText As String = logTime & " " & report_data
File.AppendAllText(myFile, appendText)
End If
I have tried deleting the file and creating it again, that made no difference.
I tried File.SetAttributes(myFile, FileAttributes.Normal)
The IT dept can't see what the problem is.
I can manually open, change and modify the file. The problem only arises if I am trying to do this programmatically.
Is there a different 'user' which tries to modify files? Could the file be open somehow, or would that generate a different error?
I'm using VB.NET 2012, .net framework 4.5, Windows 8.1
The network changes were the problem. It doesn't seem possible to resolve this as it is. Instead I made a copy of the text data, append my new text to that, delete the file, and save the updated text to a new file.

Editting the registry in VB.NET

I used the code necessary to change the DWord of a registry in VB.NET however I need to always Right click and run as administrator for it to work. In order to prevent this I passed the administrator user credentials before executing the command, however I get an error message.
The code I used for this purpose is,
Dim regVersion As RegistryKey
regVersion = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\services\\USBSTOR", True)
Try
Dim intVersion As Integer = 4
intVersion = regVersion.GetValue("Start", 0)
intVersion = intVersion + 1
End If
Dim p As New ProcessInfo(regVersion.SetValue("Start", intVersion))
p.UseShellExecute = False
p.Domain = "domain"
p.UserName = "Yoosuf"
p.Password = New System.Security.SecureString()
Dim q As New System.Security.SecureString()
For Each c As Char In
q.Password.AppendChar(c)
Next
Process.Start(p)
regVersion.Close()
Catch es As Exception
End Try
However I receive an error message on the line
Dim p As New ProcessInfo()
Could anyone please let me know what is the mistake I have done
The error is most likely because this code:
Dim p As New ProcessInfo(regVersion.SetValue("Start", intVersion))
doesn't make any sense. The ProcessInfo constructor is expecting a string, which specifies the name of the file or application to be started. You've passed it the result of the RegistryKey.SetValue method, which does not return a value.
Considering the real problem that you want to solve is,
I need to always Right click and run as administrator for it to work
then the real solution is to add a manifest to your application that indicates it should be launched with administrative privileges. This would free you from having to right-click and explicitly choose "Run as administrator" each time. Instead, the application's process would be automatically elevated (if possible), or you would be prompted for permission by UAC.
To do this in Visual Studio for a VB.NET application, you need to modify the default manifest that is embedded into the application. Here are the steps:
Right-click on your project in the Solution Explorer, and select "Properties".
Open the "Application" tab.
Click "View Windows Settings".
This opens the default manifest. Change the <requestedExecutionLevel> element to requireAdministrator.
It should look like this:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

How to check from .net code whether "Trust access to the VBA project object model" is enabled or not for an Excel application?

How to check from .net code whether "Trust access to the VBA project object model" is enabled or not for an Excel application?
Manually I can check it from Excel application- File>Options>Trust Center>Trust Center Settings>Macro Settings>Trust access to the VBA project object model
The short answer is that you cannot directly access this setting using the Excel object model (i.e. through PIAs).
However, instead, you can check this setting from the registry in the following location (here I assume that you're using Office 2007 - version 12.0):
HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\Security\AccessVBOM
this is a DWORD that will be 0 or 1 depending on whether the "Trust access to VBA Object Model" is enabled.
However, this setting can be overriden by another registry key located at:
HKEY_LOCAL_MACHINE\Software\Microsoft\Office\12.0\Excel\Security\AccessVBOM
this is again a DWORD, however, if this value is 0 this means that no matter what the HKCU value is set to, then access to the VBOM will be denied. If the value in HKLM is 1 or missing, then the HKCU key will control the access to the VBOM.
Therefore, all you need to do is to check these two keys via the Registry methods in .NET.
This worked for me
Function VBATrusted() As Boolean
On Error Resume Next
VBATrusted = (Application.VBE.VBProjects.Count) > 0
End Function
Private Sub Workbook_Open()
If Not VBATrusted() Then
MsgBox "No Access to VB Project" & vbLf & _
"Please allow access in Trusted Sources" & vbLf & _
"File > Options > Trust Center > Trust Center Settings > Macro Settings > Trust Access..."
End If
End Sub
Source https://www.mrexcel.com/forum/excel-questions/659774-checking-if-trust-access-visual-basic-project-ticked.html
Search the registry for all instances of "AccessVBOM" and change the Dword settings to a 1.
That should turn it on.
It has been my experience that Application.VBE will (depending on OFFICE version) either be *null* or throw a COMException whenever the VBA Project Object Model is not trusted.
If one is using Office.Interop in an Add-In then Globals.ThisAddIn.Application.VBE will perform the necessary test.
I have used this proxy for years successfully.