I have a service I am trying to create in Visual Studio that checks the values of 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' when the service starts and stores it as a hashset. Every 20 minutes, it pulls another hashset of the directory and compares the two sets to effectively see if a program is installed based on the addition of the uninstalled value in the registry. I used a separate project, also using Visual Studio that is a console app for ease of testing the logic before I created the service app.
The issue I am running into is that the code is logically the same from the service to the console app, however only the console app functions as anticipated. When I install a program, my test is TeamViewer, it sees the new entry in the registry and set, then sends an email/writes to console that a change was found. I believe the main difference is that the service was forced to be built with .net framework and the console app is just .net.
The main service directory is WatchTower. The console testing directory is Consoletest. The class file in question is InstalledApps.cs for both directories.
the code can be found here: https://github.com/TartCart/WatchTower.git
I have printed the output of the service to a logfile and see that it is able to access the registry, and populate the hash sets, but it seems like the service is unable to get an updates set from the registry after it accesses it for the first time.. whereas in the console app it gets the updated set. I've checked permissions and utilized chatGPT to its fullest extent for testing/debugging but something under the hood is just not giving as far as I can tell with my limited experience.
I am inexperienced with software development as I am sure my code will reveal - any feedback would be greatly appreciated. Thanks
Make sure you are checking both the 32-bit and 64-bit registry locations.
SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
You can do that by specifying the RegistryView
on the base key:
const string KeyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
var allSubKeyNames = new List<string>();
foreach (var regView in new List<RegistryView> { RegistryView.Registry32, RegistryView.Registry64 })
{
using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, regView))
{
using (var subKey = baseKey.OpenSubKey(KeyName))
{
allSubKeyNames.AddRange(subKey.GetSubKeyNames());
}
}
}
using (var subKey = Registry.CurrentUser.OpenSubKey(KeyName))
{
allSubKeyNames.AddRange(subKey.GetSubKeyNames());
}
//do something with allSubKeyNames
More info here
Additionally, you should probably open and close the key inside Timer_Elapsed
rather than opening it and holding it static.