WPF application doesn't work with its own registry key - c#

I'm trying to add the classic "Send with MyApp" in the ContextMenu.
The fact is that my program modifies the windows registry, but it seems that it can't see the update version of it. Indeed, if I start again my program leaving the keys that it modified, it works fine.
How can I solve this (without create another program that modfies the windows registry and then call mine)?
Thank you in advance for the help.
P.s.
Here are the functions that I use to modify the registry
private void AddOption_ContextMenu()
{
RegistryKey _key1 = Registry.ClassesRoot.OpenSubKey("Folder\\shell", true);
RegistryKey _key = Registry.ClassesRoot.OpenSubKey("*\\shell", true);
RegistryKey newkey = _key.CreateSubKey("MyApp");
RegistryKey newkey1 = _key1.CreateSubKey("MyApp");
RegistryKey command = newkey.CreateSubKey("command");
RegistryKey command1 = newkey1.CreateSubKey("command");
string program = Path.GetDirectoryName(Application.ResourceAssembly.Location);
for (int i = 0; i < 3; i++)
program = Path.GetDirectoryName(program);
program = #"""" + program + #"\\MyApp\\bin\\Debug\\MyApp.exe"" ""%1""";
command.SetValue("", program);
command1.SetValue("", program);
newkey.SetValue("", "Send with MyApp");
newkey.SetValue("Icon", Path.GetDirectoryName(Application.ResourceAssembly.Location) + "\\icon.ico");
newkey1.SetValue("", "Send with MyApp");
newkey1.SetValue("Icon", Path.GetDirectoryName(Application.ResourceAssembly.Location) + "\\icon.ico");
command.Close();
command1.Close();
newkey1.Close();
newkey.Close();
_key.Close();
}
public void RemoveOption_ContextMenu()
{
RegistryKey _key = Registry.ClassesRoot.OpenSubKey("*\\shell", true);
RegistryKey _key1 = Registry.ClassesRoot.OpenSubKey("Folder\\shell", true);
_key.DeleteSubKeyTree("MyApp");
_key1.DeleteSubKeyTree("MyApp");
_key1.Close();
_key.Close();
}

Have you tried to read this?
Edited the registry with C# but cannot find the change with regedit
I found this issue years ago and I think that is mandatory to use (at least) two different C# threads to see changes in registry key -->
ref:
C# : How to change windows registry and take effect immediately

Related

How Can I edit the registry with C# UWP

"You was read registry values from a Win32 runFullTrust background process launched from a UWP application, and you can write values in the HKEY_CURRENT_USER hive from an "elevated" Win32 application launched from that runFullTrust process." follow link
Registry functions for modern apps
I tried on this solution but I have some problems. I did not get registry values.
ex: "The Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\GameDVR has AppCaptureEnabled key and value of AppCaptureEnabled is 1. I run execute win32app and get value of AppCaptureEnabled = 1. When I call execute win32app file from UWP app and get value of AppCaptureEnabled = 0."
The source code such as below:
string value64 = string.Empty;
string value32 = string.Empty;
RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, RegistryView.Registry64);
localKey = localKey.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\GameDVR", true);
if (localKey != null)
{
value64 = localKey.GetValue("AppCaptureEnabled").ToString();
MessageBox.Show("AppCaptureEnabled = " + value64);
}
RegistryKey localKey32 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, RegistryView.Registry32);
localKey32 = localKey32.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\GameDVR", true);
if (localKey32 != null)
{
value32 = localKey32.GetValue("AppCaptureEnabled").ToString();
MessageBox.Show("AppCaptureEnabled = " + value32);
}
Please help me explain why I can not get/save value of key?

How can I detect if Microsoft Edge is installed?

I'm writing a windows form application (c#) and I need to detect whether the user have "Microsoft-Edge" installed in his/her machine or not.
I'm currently using this registry location:
[HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages\Microsoft.MicrosoftEdge_20.10240.16384.0_neutral__8wekyb3d8bbwe]
"Path"="C:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe"
With a regex after the "Microsoft.MicrosoftEdge". If the "path" exist then I know edge is installed.
Is there a better way to detect edge? would it be better if I detect that I'm running on Windows 10 and by default Win10 come with edge? What is the best way for that?
In case you want to have a small program getting that version number:
static void Main(string[] args)
{
string EdgeVersion = string.Empty;
//open the registry and parse through the keys until you find Microsoft.MicrosoftEdge
RegistryKey reg = Registry.ClassesRoot.OpenSubKey(#"Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages");
if (reg != null)
{
foreach (string subkey in reg.GetSubKeyNames())
{
if (subkey.StartsWith("Microsoft.MicrosoftEdge"))
{
//RegEx: (Microsoft.MicrosoftEdge_)(\d +\.\d +\.\d +\.\d +)(_neutral__8wekyb3d8bbwe])
Match rxEdgeVersion = null;
rxEdgeVersion = Regex.Match(subkey, #"(Microsoft.MicrosoftEdge_)(?<version>\d+\.\d+\.\d+\.\d+)(_neutral__8wekyb3d8bbwe)");
//just after that value, you need to use RegEx to find the version number of the value in the registry
if ( rxEdgeVersion.Success )
EdgeVersion = rxEdgeVersion.Groups["version"].Value;
}
}
}
Console.WriteLine("Edge Version(empty means not found): {0}", EdgeVersion);
Console.ReadLine();
}
Thank you for the registry link for finding the version number.
If you're on the desktop or mobile version of Windows 10 then Edge is pre-installed and can't be uninstalled.
To detect if running on Windows 10 use the System.Environment.OSVersion property or the Version Helper functions. (See also https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx)
If you want to detect the default browser you should see How to determine the Windows default browser (at the top of the start menu)
Relevant to 15.11.2016:
The only way that I found working is to use this registry location:
[HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages\Microsoft.MicrosoftEdge_20.10240.16384.0_neutral__8wekyb3d8bbwe]
"Path"="C:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe"
With a regex after the "Microsoft.MicrosoftEdge".
If the "path" exist then I know edge is installed.
In reference to other answers: my installation of Windows 10 does not have this key: Microsoft.MicrosoftEdge_20.10240.16384.0_neutral__8wekyb3d8bbwe
In:
[HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages\]
Instead, it has the following keys:
Microsoft.MicrosoftEdge_38.14393.0.0_neutral__8wekyb3d8bbwe
Microsoft.MicrosoftEdge_40.15063.674.0_neutral__8wekyb3d8bbwe
The following code could be used to detect if Edge is installed:
class Program
{
static void Main(string[] args)
{
var edgeFound = false;
using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(#"Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages\"))
{
if (key != null)
{
foreach (var subkey in key.GetSubKeyNames())
{
if (subkey.StartsWith("Microsoft.MicrosoftEdge_"))
{
edgeFound = true;
break;
}
}
}
}
Console.Write(edgeFound);
Console.ReadLine();
}
}

get installed version of an application using c#

I would to get installed version of an application (say, MyApp) using C#.
I will do this much,
1. Create a 'Set Up' for MyApp of version 5.6
2. Install MyApp.
I will create another application (say VersionTracker)to get the version of installed applications. So if I pass the name 'MyApp' I would like to get the version as '5.6'. If another application say Adobe Reader is installed in my system, I want to get the version of Adobe Reader if I pass 'Adobe Reader'.
I need to know how to build 'VersionTracker'
The first and the most important thing is that not all applications do save their version somewhere in the system. To be honest, only a few of them do that. The place where you should look are the Windows Registry. Most of installed applications put their installation data into the following place:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
However, it's not that easy - on 64bit Windows, the 32bit (x86) applications save their installation data into another key, which is:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
In these keys there are many keys, some of them have got "easy-readable" name, such as Google Chrome, some of them got names such as {63E5CDBF-8214-4F03-84F8-CD3CE48639AD}. You must parse all these keys into your application and start looking for the application names. There are usually in DisplayName value, but it's not always true. The version of the application is usually in DisplayVersion value, but some installers do use another values, such as Inno Setup: Setup Version, ... Some application do have their version written in their name, so it's possible that the application version is already in the DisplayName value.
Note: It's not easy to parse all these registry keys and values and to "pick" the correct values. Not all installers save the application data into these keys, some of them do not save the application version there, etcetera. However, it's usual that the application use these registry keys. [Source: StackOverflow: Detecting installed programs via registry, browsing my own registry]
Alright, so now when you know where you should look, you have to program it all in C#. I won't write the application for you, but I'll tell you what classes you should use and how to. First, you need these:
using System;
using Microsoft.Win32;
To get to your HKEY_LOCAL_MACHINE, create a RegistryKey like this:
RegistryKey baseRegistryKey = Registry.LocalMachine;
Now you need to define subkeys:
string subKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
// or "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
Now you need to go to the subkey, so create a new RegistryKey:
RegistryKey uninstallKey = baseRegistryKey.OpenSubKey(subKey);
Now you need to go thru all the subkeys that are there, so first we get the names of all the subkeys:
string[] allApplications = uninstallKey.GetSubKeyNames();
Now you must go thru all the subkeys yourself, one by one, by creating a new registry key (you don't have to, but I'll do it):
RegistryKey appKey = baseRegistryKey.OpenSubKey(subKey + "\\" + applicationSubKeyName);
where applicationSubKeyName is the name of the subkey you're currently checking. I recommend foreach statement, which helps you (you must however have some experience with C# already, I'm not going to tell you how to use foreach here).
Now check the application's name and compare it with name of your desired application (you cannot rely on the subkey name, because, as I already said, they can be called for example {63E5CDBF-8214-4F03-84F8-CD3CE48639AD}, so you must check the name here):
string appName = (string)appKey.GetValue("DisplayName");
If it's the correct application (you must check it yourself), find the version:
string appVersion = (string)appKey.GetValue("DisplayVersion");
Et voilà, you have the version. At least there's like a 60 - 80% chance you have...
Remember! If some key or value doesn't exist, the method returns null. Remember to check if the returned value is null everytime, otherwise your application will crash.
Where to find more? The Code Project: Read, write and delete from registry with C#
I really hope I helped you. And if you wanted to know something else and I didn't understand your question, then, please, ask better next time. :)
///
/// Author : Muhammed Rauf K
/// Date : 03/07/2011
/// A Simple console application to create and display registry sub keys
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// it's required for reading/writing into the registry:
using Microsoft.Win32;
namespace InstallationInfoConsole
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Registry Information ver 1.0");
Console.WriteLine("----------------------------");
Console.Write("Input application name to get the version info. (for example 'Nokia PC Suite'): ");
string nameToSearch = Console.ReadLine();
GetVersion(nameToSearch);
Console.WriteLine("----------------------------");
Console.ReadKey();
}
///
/// Author : Muhammed Rauf K
/// Date : 03/07/2011
/// Create registry items
///
static void Create()
{
try
{
Console.WriteLine("Creating registry...");
// Create a subkey named Test9999 under HKEY_CURRENT_USER.
string subKey;
Console.Write("Input registry sub key :");
subKey = Console.ReadLine();
RegistryKey testKey = Registry.CurrentUser.CreateSubKey(subKey);
Console.WriteLine("Created sub key {0}", subKey);
Console.WriteLine();
// Create two subkeys under HKEY_CURRENT_USER\Test9999. The
// keys are disposed when execution exits the using statement.
Console.Write("Input registry sub key 1:");
subKey = Console.ReadLine();
using (RegistryKey testKey1 = testKey.CreateSubKey(subKey))
{
testKey1.SetValue("name", "Justin");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
static void GetVersion(string nameToSearch)
{
// Get HKEY_LOCAL_MACHINE
RegistryKey baseRegistryKey = Registry.LocalMachine;
// If 32-bit OS
string subKey
//= "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
// If 64-bit OS
= "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
RegistryKey unistallKey = baseRegistryKey.OpenSubKey(subKey);
string[] allApplications = unistallKey.GetSubKeyNames();
foreach (string s in allApplications)
{
RegistryKey appKey = baseRegistryKey.OpenSubKey(subKey + "\\" + s);
string appName = (string)appKey.GetValue("DisplayName");
if(appName==nameToSearch)
{
string appVersion = (string)appKey.GetValue("DisplayVersion");
Console.WriteLine("Name:{0}, Version{1}", appName, appVersion);
break;
}
}
}
static void ListAll()
{
// Get HKEY_LOCAL_MACHINE
RegistryKey baseRegistryKey = Registry.LocalMachine;
// If 32-bit OS
string subKey
//= "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
// If 64-bit OS
= "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
RegistryKey unistallKey = baseRegistryKey.OpenSubKey(subKey);
string[] allApplications = unistallKey.GetSubKeyNames();
foreach (string s in allApplications)
{
RegistryKey appKey = baseRegistryKey.OpenSubKey(subKey + "\\" + s);
string appName = (string)appKey.GetValue("DisplayName");
string appVersion = (string)appKey.GetValue("DisplayVersion");
Console.WriteLine("Name:{0}, Version{1}", appName, appVersion);
}
}
}
}
Next code base on similar solution is working for me:
var version = GetApplicationVersion("Windows Application Driver");
string GetApplicationVersion(string appName)
{
string displayName;
// search in: CurrentUser
var key = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
foreach (var keyName in key.GetSubKeyNames())
{
var subKey = key.OpenSubKey(keyName);
displayName = subKey.GetValue("DisplayName") as string;
if (appName.Equals(displayName, StringComparison.OrdinalIgnoreCase))
return subKey.GetValue("DisplayVersion").ToString();
}
// search in: LocalMachine_32
key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
foreach (var keyName in key.GetSubKeyNames())
{
var subKey = key.OpenSubKey(keyName);
displayName = subKey.GetValue("DisplayName") as string;
if (appName.Equals(displayName, StringComparison.OrdinalIgnoreCase))
return subKey.GetValue("DisplayVersion").ToString();
}
// search in: LocalMachine_64
key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
foreach (var keyName in key.GetSubKeyNames())
{
var subKey = key.OpenSubKey(keyName);
displayName = subKey.GetValue("DisplayName") as string;
if (appName.Equals(displayName, StringComparison.OrdinalIgnoreCase))
return subKey.GetValue("DisplayVersion").ToString();
}
// NOT FOUND
return null;
}

hijack program’s command to run notepad

I have a utility programs’s EXE file, when i run this file there is a winform only and there is button when we click on it, it run windows’s notepad. Now I want to hijack this program’s command to run notepad and instead of running notepad I want to run MS Word. I know C# and VB.NET. What I need to do this ?
You can try to add in folder with this program your own program called notepad.exe that should do only one thing: run word.
If you want to do it programatically in C then you should read this page - maybe it helps: Intercepted: Windows Hacking via DLL Redirection
You can use a trick to replace programs with another by making changes to the registry. This will work even if the program you are running uses absolute paths to run notepad. It overrides any instance of the running program with the chosen one no matter where it resides. And you won't have to patch the file. The key you'd be interested in is:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
Add a key with the name of the program and add a Debugger string with the path to the program you want to replace it with. Of course you need to have permissions to make the necessary modifications. This page explains how you can replace Windows Notepad with another program. You can apply the same process here.
Though you'll probably not want to have this permanent change, so you can write up a program to temporarily add/change the key, run your program then change it back. Here's a complete one I just whipped up to temporarily replace Notepad with Word for a demonstration. Seems to work perfectly fine (though as always, use at your own risk). Just make all the necessary changes to fit your situation.
using System.Diagnostics;
using Microsoft.Win32;
namespace ProgramLauncher
{
class Program
{
// change the following constants as needed
const string PROGRAM_NAME = #"notepad.exe";
const string REPLACEMENT_PATH = #"C:\Program Files (x86)\Microsoft Office\Office12\WINWORD.EXE";
const string RUNNING_PATH = #"C:\Windows\notepad.exe";
// root key
const string KEY = #"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options";
static void Main(string[] args)
{
using (var rootKey = Registry.LocalMachine.OpenSubKey(KEY, RegistryKeyPermissionCheck.ReadWriteSubTree))
{
var oldPath = default(string);
var needsRestoration = false;
try
{
oldPath = BackupKey(rootKey, PROGRAM_NAME, REPLACEMENT_PATH);
needsRestoration = true;
Process.Start(RUNNING_PATH).WaitForExit();
}
finally
{
if (needsRestoration)
RestoreKey(rootKey, PROGRAM_NAME, oldPath);
}
}
}
static string BackupKey(RegistryKey rootKey, string programName, string newPath)
{
Debug.Assert(rootKey != null);
Debug.Assert(!string.IsNullOrEmpty(programName));
Debug.Assert(!string.IsNullOrEmpty(newPath) && System.IO.File.Exists(newPath));
if (newPath.Contains(" "))
newPath = string.Format("\"{0}\"", newPath);
using (var programKey = rootKey.CreateSubKey(programName, RegistryKeyPermissionCheck.ReadWriteSubTree))
{
var oldDebugger = programKey.GetValue("Debugger") as string;
programKey.SetValue("Debugger", newPath, RegistryValueKind.String);
return oldDebugger;
}
}
static void RestoreKey(RegistryKey rootKey, string programName, string oldPath)
{
Debug.Assert(rootKey != null);
Debug.Assert(!string.IsNullOrEmpty(programName));
if (oldPath != null)
{
using (var programKey = rootKey.OpenSubKey(programName, RegistryKeyPermissionCheck.ReadWriteSubTree))
programKey.SetValue("Debugger", oldPath);
}
else
{
rootKey.DeleteSubKey(programName);
}
}
}
}

C# Issue creating method to delete a registry key

I confess I’m new to C#. I am struggling with creating a method to delete a registry key using .NET. The method takes one string parameter which contains the complete key to be removed. Here’s a sample of what I’m trying to do that doesn’t work (obviously):
namespace NameHere
{
class Program
{
static void Main(string[] args)
{
RegistryKey hklm = Registry.LocalMachine;
hklm = hklm.OpenSubKey(#"SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\")
string strKey=”Test123”;
string fullPath = hklm + "\\" + strKey;
deleteRegKey(fullPath);
}
static void deleteRegKey(string keyName)
{
Registry.LocalMachine.DeleteSubKey(keyName);
}
}
}
I’ve tried a few other iterations and googled for solutions but have, so far, been unable to put the pieces together. Any help would be greatly appreciated. Also, any explanation for why my lame attempt doesn’t work to help clarrify my knowledge gap would be awesome.
This routine should really be a one-liner, like:
Registry.LocalMachine.DeleteSubKey( #"SYSTEM\ControlSet...\etc..." );
You shouldn't need to open a RegistryKey object, because Registry.LocalMachine is kind of already open for you.
If you do need to open a RegistryKey object to do something else, be aware that RegistryKey implements IDisposable, so now that you've created an object, you're responsible for disposing of it no matter what. So, you have to surround your code with try { ... } and call Dispose() in the finally block. Fortunately, this can be coded in C# more elegantly using using:
using( RegistryKey key = Registry.LocalMachine.OpenSubKey(...) ) {
...
}
I believe you have too many \'s. Try this:
RegistryKey hklm = Registry.LocalMachine;
hklm = hklm.OpenSubKey(#"SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\")
string strKey=”Test123”;
string fullPath = hklm + strKey;
deleteRegKey(fullPath);
I think #Correl has it.
But one way to help you debug would be to use this form of DeleteSubkey:
public void DeleteSubKey(
string subkey,
bool throwOnMissingSubKey
)
instead of the one you call with only one argument, and pass true as the second argument. That way, if
...the specified subkey does not exist, then an exception is raised.
The exception you get would be an ArgumentException.

Categories

Resources