GetValueNames() of protected registry in vb.net - windows

I have the following folder in registry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths
But how can I show their value name to listbox?
Here is my code:
Dim FontKey As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths")
For Each ValueName As String In FontKey.GetValueNames()
Dim Value As Object = FontKey.GetValue(ValueName) 'Get the value (data) of the specified value name.
If Value IsNot Nothing Then 'Make sure it exists.
ListBox1.Items.Add(Value.ToString())
End If
Next
FontKey.Close()
P/s: I get this error: (Because I do not have the requisite permissions to create a new key)
System.NullReferenceException: 'Object reference not set to an instance of an object.'
FontKey was Nothing.

If you want to show the value name then just ignore retrieving the value and add the ValueName variable to the list box instead:
For Each ValueName As String In FontKey.GetValueNames()
ListBox1.Items.Add(ValueName)
Next
As for the error:
There's a difference between a NullReferenceException and the SecurityException that is actually thrown when you don't have access to a registry key. In this case the former occurs because the key you opened doesn't exist, which is likely caused by your application viewing the 32-bit version of the registry key (HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\...) rather than the 64-bit version (HKEY_LOCAL_MACHINE\SOFTWARE\...).
To fix this, either compile your application as x64 or AnyCPU, or force it to view the 64-bit registry. See my answer here for more information: NullReferenceException when opening a subkey I know exists

Related

Is there a way for VB6 to throw a type mismatch error when assigning a variable of the same type?

I am trying to figure out the cause of a type mismatch error, but I don't understand the reason it is even being thrown. I am assigning to a variable of the same type that is being assigned from.
Begin bxControls.starTable m_tblClaims 'Defined at the top of the form file
Dim objTable As PVDataTable5.DataTable
Set objTable = m_tblClaims.Table
Begin PVDataTable5.DataTable dtTable 'Defined at the top of the .ctl file
'Property inside of bxControls.starTable
Public Property Get Table() As Object
Attribute Table.VB_MemberFlags = "40"
Set Table = dtTable
End Property
As you can see, the assignment taking place should not be having a type mismatch since they are the same type. Any help would be awesome. TIA
Try this
Dim objTable As PVDataTable5.DataTable
Set objTable = m_tblClaims.Table.Object
Note that this might work in IDE but fail when compiled.
The story of user-controls is mostly of complete lies from the IDE. For instance all user-control properties/methods are called late-bound, even if the IDE intellisense gives look like the callsite is early-bound.
For each user-control type that is currently loaded in the IDE (as part of a project group for instance) the IDE creates surrogate date-type with merged original control properties/methods and some VB supplied ones (like Visible etc.) which are coming from VBControlExtender class.
That is why Dim objTable As PVDataTable5.DataTable sometimes is not declaration of PVDataTable5.DataTable data-type but of the surrogate PVDataTable5.DataTable from an OCA file, that is when the user-control is loaded in the IDE.
The only sane way to pass references to VB6 user-controls that works both if the user-control is loaded and when referenced in compiled OCX is to pass VBControlExtender instead and use its Object property to access the wrapped reference.

Unable to change registry on Windows 10

I'm trying to change the value of the Shell registry key on Windows 10 using the following code:
Public Function overwriteStartup()
Try
Dim winlogon As RegistryKey = My.Computer.Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", True)
winlogon.SetValue("AutoRestartShell", 0, RegistryValueKind.DWord)
winlogon.SetValue("Shell", Application.ExecutablePath, RegistryValueKind.String)
winlogon.Flush()
winlogon.Close()
Return True
Catch ex As Exception
Return False
End Try
End Function
The issue is that Shell and AutoRestartShell are not changing.
If I add MessageBox.Show(My.Computer.Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon").GetValue("Shell")) between winlogon.Close() and Return True, I get a message box that shows the correct value (which means that the value was changed), but when I check regedit, it shows the original value, so it did not actually change the value.
If your app can read the registry value - You must need to provide administrative privileges before letting your app write registry values. Go to the app manifest and set the privilege to requireAdministrator then try again, it should work.
If you remove the exception handling Try Catch, then you'll get to know the exact reason.
I changed the target framework to .NET 4 and set target CPU to AnyCPU, it works now.

Check for COM Object Collection Propertys Existence

I have been pondering this one for a while. I am programatically (in VB6) sifting through Outlook PSTs, indexing items that are in them. I have happened on to one that is a little corrupted and this is where I am having difficulty. My program attaches the PST and starts drilling down through the folders (olFolder). These Outlook created objects are supposed to have a collection that would normally hold sub folders (appropriately named Folders).
During the execution of my code I recursively call the process folder function to process all folders in the current folder, but I have one that does not have a collection. This causes an exception because I am checking the count of folders in the collection and there is nothing to check. I understand how to check for the existence of an object, but I am having a hard time checking for the existence of a collection in and object.
Update
The expression:
If Not fl.Folders Is Nothing Then
ends up throwing the exception too. The exception that I am getting is the following:
Could not complete the operation because the service provider does not support it.
This is only when trying to access this corrupted folder which appears to have a Folders Collection Property that is FUBARed.
Final
Alright; in this case I am just going to put in some in-line error handling.
If Not Err.Number = -2147221246 Then
'Do the thing with the other thing
End If
Err.Clear
If you are talking about checking whether obj.Coll.Count = 0, then see if obj.Coll Is Nothing.
well when i work web services on vb6 i have check some cases if property exist. i used that method.
It is slow but i hope that help you.
Public Function HasProperty(ByRef obj As Object, ByVal nameProperty As String) As Boolean
On Local Error GoTo hasProperty_Error
Dim Result
Result = CallByName(obj, nameProperty, VbGet)
hasProperty = True
hasProperty_Done:
Exit Function
hasProperty_Error:
If Err.Number = 438 Then
hasProperty = False
End If
Resume hasProperty_Done
End Function

How to fetch registry path from EventArrivedEventArgs object

I try to watch the registry events via WMI. I use the below query to watch any events inside HKLM\softwares
WqlEventQuery query = new WqlEventQuery(
"SELECT * FROM RegistryTreeChangeEvent WHERE " +
"(Hive = 'HKEY_LOCAL_MACHINE')" +
"AND Rootpath = 'Software'"
As expected it catches all events in EventArrivedEventArgs.
example: 1) if there is a newkey inside Hklm\software\microsoft, it captures
2) if there is a value change inside Hklm\software\microsoft\windows, it captures
However I need to know the registry path or key or value in which change has occured.
I dont know how to interpret the EventArrivedEventArgs object to get it.
Can anyone help me.
I don't believe this is possible. EventArrivedEventArgs will return an instance of RegistryTreeChangeEvent and the only thing you know about the event is the root path you are monitoring. You can work around this using the RegistryKeyChangeEvent class, specifying more than one key in the query Where clause. For example (not tested):
SELECT * FROM RegistryKeyChangeEvent
WHERE Hive='HKEY_LOCAL_MACHINE' AND
(KeyPath='SOFTWARE\Microsoft' OR
KeyPath='SOFTWARE\Microsoft\Windows')
In this case you would use EventArrivedEventArgs.NewEvent property to get the RegistryKeyChangeEvent instance and its Keypath property to get the registry key that was changed.
After the analysis, Its clear that Key path for subkeys couldnot be obtained through registry events. Because Regkeychangeevent could not monitor subkeys and reg treechange event monitors subkeys which would not give the key path, the change has occured. Hence preimage post image's diff should be the only solution so far.

CustomActionData does not seem to be populated or accessable by my vbscript

Ok, this is driving me crazy.
I have a CA that needs to know the path of the INSTALLDIR to edit an XML file.
So, I set up a set property custom action that sets a property named RemoveAuthTypesNode to [INSTALLDIR]. Then I have a RemoveAuthTypesNode CA that is sequenced after SetConfigFolder (a set property that sets installdir to a system searched path) in the Install Execute Sequence, Deferred in System Context (doesn't work when just Deferred Exec either).
In the log I see that RemoveAuthTypesNode is set:
MSI (c) (D4:EC) [16:12:05:314]:
PROPERTY CHANGE: Adding
RemoveAuthTypesNode property. Its
value is 'C:\Program Files\Microsoft
SQL
Server\MSRS10.MSSQLSERVER\Reporting
Services\ReportServer\'.
The custom action errors:
Error 1720.There is a problem with
this Windows Installer package. A
script required for this install to
complete could not be run. Contact
your support personnel or package
vendor. Custom action
RemoveAuthTypesNode script error
-2146827864, Microsoft VBScript runtime error: Object required:
'objXMLDOMNode' Line 9, Column 1, MSI
(s) (78:EC) [16:12:23:916]: Product:
ASMI User Defined Reports -- Error
1720.There is a problem with this Windows Installer package. A script
required for this install to complete
could not be run. Contact your support
personnel or package vendor. Custom
action RemoveAuthTypesNode script
error -2146827864, Microsoft VBScript
runtime error: Object required:
'objXMLDOMNode' Line 9, Column 1,
This is failing because the path isn't correct so the XMLDom object never loads. I know this because if I hardcode the path everything works fine.
Also, when I search the log for CustomActionData I expected that it would be in there as being set.
Here is the code from the custom action. The msgbox is just for debugging. It is always displaying nothing.
strConfigFile = session.Property("CustomActionData") & "rsreportserver.config"
MsgBox session.Property("CustomActionData")
Set xDoc = CreateObject("Microsoft.XMLDOM")
xDoc.async = False
xDoc.Load(strConfigFile)
set objXMLDOMNode = xDoc.selectSingleNode("//Configuration/Authentication/AuthenticationTypes")
set objParentNode = objXMLDOMNode.parentNode
objParentNode.removeChild(objXMLDOMNode)
xDoc.save(strConfigFile)
Set xDoc = Nothing
What am I doing wrong? I'm sure it's something simple stupid. Help greatly appreciated.
The custom action that sets the property named for the vbscript custom action was setting a private property (not all upper case). So, the set property custom action had to be sequenced in the Execute sequence rather than the UI sequence. Once I made this change the correct data was being retrieved in the script.
It is expected if I have made a public property (all UPPER case) it would have work being in the UI sequence, however, I didn't test that theory.

Resources