I am using regasm.exe to install my Outlook plugin on the end users' machines. However, I noticed that in a terminal server environment, my addin wouldn't load for all users. I found out that the addin registry keys were being created under the current user hive and not the local machine hive.
Is there something i can add to my plugin which will enable regasm to create/delete the keys under HKLM as well as current user when a user installs or uninstalls the plugin?
I had other, but similar issues with regasm.exe, as I wanted to avoid the UAC in windows when registering the AddIn, so I wrote a com registrar by myself, which does the proper registry keys to register the com addin.
You would have to change this code accordingly to have the registry keys in those places were you want them, and obviously have similar code to rollback those changes on uninstalling your add-in
class ComAddinRegistrar
{
private static string CLSID = "{CLSID}";
private static string ASSEMBLY_NAME = "Outlook.Addin";
private static string ASSEMBLY_DLL = "Outlook.Addin.dll";
private static string VERSION = "1.0.0.0";
private static string IMPLEMENTED_CATEGORY = "{CATEGORY_ID}";
public static void RegisterAddin(bool is64Bit)
{
// Get path of dll:
var apPpath = System.Reflection.Assembly.GetExecutingAssembly().Location;
apPpath = Path.GetDirectoryName(apPpath);
var path = ASSEMBLY_DLL;
var dllPath = Path.Combine(apPpath, path);
// Com registration
RegistryKey rkey;
if (is64Bit)
rkey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)
.OpenSubKey("Software").OpenSubKey("Classes", true);
else
rkey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32)
.OpenSubKey("Software").OpenSubKey("Classes", true);
var comAssemblyNameKey = rkey.CreateSubKey(ASSEMBLY_NAME); //HKCU/Software/Classes/Outlook.Addin
comAssemblyNameKey.SetValue("", ASSEMBLY_NAME); // default value
var clsidAssemblyNameComKey = comAssemblyNameKey.CreateSubKey("CLSID"); //HKCU/Software/Classes/Outlook.Addin/{CLSID}
clsidAssemblyNameComKey.SetValue("", CLSID); // default value
RegistryKey clsidComKey;
if (is64Bit)
clsidComKey = rkey.CreateSubKey("CLSID").CreateSubKey(CLSID); //HKCU\Software\Classes\CLSID\{CLSID}
else
clsidComKey = rkey.CreateSubKey("Wow6432Node").CreateSubKey("CLSID").CreateSubKey(CLSID); //HKCU\Software\Classes\CLSID\{CLSID}
clsidComKey.SetValue("", ASSEMBLY_NAME); // default value
var inProcServerKey = clsidComKey.CreateSubKey("InprocServer32"); //HKCU\Software\Classes\CLSID\{CLSID}\InProcServer32
inProcServerKey.SetValue("", "mscoree.dll");
inProcServerKey.SetValue("ThreadingModel", "Both");
inProcServerKey.SetValue("Class", "Outlook.Addin.Addin");
inProcServerKey.SetValue("Assembly", $"Outlook.Addin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
inProcServerKey.SetValue("RuntimeVersion", "v4.0.30319");
inProcServerKey.SetValue("CodeBase", dllPath);
var versionKey = inProcServerKey.CreateSubKey(VERSION); //HKCU\Software\Classes\CLSID\{CLSID}\InProcServer32\1.0.0.0
versionKey.SetValue("Class", "Outlook.Addin.Addin");
versionKey.SetValue("Assembly", $"Outlook.Addin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
versionKey.SetValue("RuntimeVersion", "v4.0.30319");
versionKey.SetValue("CodeBase", dllPath);
var progIdKey = clsidComKey.CreateSubKey("ProgId"); //HKCU\Software\Classes\CLSID\{CLSID}\ ProgId
progIdKey.SetValue("", ASSEMBLY_NAME);
var implementedCategoryKey = clsidComKey.CreateSubKey("ImplementedCategories"); //HKCU\Software\Classes\CLSID\{CLSID}\ImplementedCategories
implementedCategoryKey.CreateSubKey(IMPLEMENTED_CATEGORY);
//AddIn registration
//HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Outlook\Addins\Outlook.Addin
var okey = Registry.CurrentUser.OpenSubKey("SOFTWARE")
.OpenSubKey("Microsoft")
.OpenSubKey("Office")
.OpenSubKey("Outlook")
.OpenSubKey("Addins", true);
var addinKey = okey.CreateSubKey(ASSEMBLY_NAME);
addinKey.SetValue("FileName", dllPath);
addinKey.SetValue("FriendlyName", "My addin");
addinKey.SetValue("Description", "some addin description");
addinKey.SetValue("LoadBehavior", 3, RegistryValueKind.DWord);
}
}
Found the answer by digging through my sample NetOffice Outlook addin project!
All you need are a couple of public static methods with the ComRegisterFunctionAttribute and ComUnregisterFunctionAttribute attributes. Regasm.exe will automatically execute the code in these methods when your plugin is installed or uninstalled.
See below for the code I am using which is slightly modified from the template to support the HKLM registry key. Add these methods to your Outlook addin class.
Alek's answer can be used if you wish to handle these manually.
[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type type)
{
try
{
// add codebase value
Assembly thisAssembly = Assembly.GetAssembly(typeof(OutlookPlugin));
RegistryKey key = Registry.ClassesRoot.CreateSubKey("CLSID\\{" + type.GUID.ToString().ToUpper() + "}\\InprocServer32\\1.0.0.0");
key.SetValue("CodeBase", thisAssembly.CodeBase);
key.Close();
key = Registry.ClassesRoot.CreateSubKey("CLSID\\{" + type.GUID.ToString().ToUpper() + "}\\InprocServer32");
key.SetValue("CodeBase", thisAssembly.CodeBase);
key.Close();
// add bypass key
// http://support.microsoft.com/kb/948461
key = Registry.ClassesRoot.CreateSubKey("Interface\\{000C0601-0000-0000-C000-000000000046}");
string defaultValue = key.GetValue("") as string;
if (null == defaultValue)
key.SetValue("", "Office .NET Framework Lockback Bypass Key");
key.Close();
// add outlook addin key
Registry.ClassesRoot.CreateSubKey(#"CLSID\{" + type.GUID.ToString().ToUpper() + #"}\Programmable");
Registry.CurrentUser.CreateSubKey(_addinOfficeRegistryKey + _prodId);
RegistryKey rk = Registry.CurrentUser.OpenSubKey(_addinOfficeRegistryKey + _prodId, true);
rk.SetValue("LoadBehavior", Convert.ToInt32(3));
rk.SetValue("FriendlyName", _addinFriendlyName);
rk.SetValue("Description", _addinDescription);
rk.Close();
//Add registry key under HKLM
RegistryKey regHKLM = Registry.LocalMachine;
regHKLM = regHKLM.CreateSubKey(#"SOFTWARE\Microsoft\Office\Outlook\Addins\" + _prodId);
regHKLM.SetValue("Friendly Name", _addinFriendlyName);
regHKLM.SetValue("Description", _addinDescription);
regHKLM.SetValue("LoadBehavior", 3, RegistryValueKind.DWord);
}
catch (System.Exception ex)
{
string details = string.Format("{1}{1}Details:{1}{1}{0}", ex.Message, Environment.NewLine);
MessageBox.Show("An error occured." + details, "Register " + _prodId, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
[ComUnregisterFunctionAttribute]
public static void UnregisterFunction(Type type)
{
try
{
Registry.ClassesRoot.DeleteSubKey(#"CLSID\{" + type.GUID.ToString().ToUpper() + #"}\Programmable", false);
Registry.CurrentUser.DeleteSubKey(_addinOfficeRegistryKey + _prodId, false);
Registry.LocalMachine.DeleteSubKey(#"SOFTWARE\Microsoft\Office\Outlook\Addins\" + _prodId);
}
catch (System.Exception throwedException)
{
string details = string.Format("{1}{1}Details:{1}{1}{0}", throwedException.Message, Environment.NewLine);
MessageBox.Show("An error occured." + details, "Unregister " + _prodId, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Related
"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?
I want to add a directory node to the left navigation pane. It should contain links to subdirectories that are actually on the file system. Currenty it just displays the contents of the last registered path under "Test".
I illustrated the problem: Left side is current state. Right side (photomontage) is how I expect it.
Is this possible or do I have to link to a directory where I add symlinks to my target directories?
That's what I have done so far (basically from a similar SO question and the "Integrate a Cloud Storage Provider" Windows help Page):
class Program
{
static void Main(string[] args)
{
string[] defaultFolders = { "C:\\Intel\\Logs", "C:\\Python27" };
var sm = new ShellextensionManger();
var guid = Guid.Parse("{03d6d437-c11c-49fc-9dcd-aa65e15b77ea}");
sm.createShellFolder(guid.ToString(), "Test", defaultFolders, "C:\\icon.ico");
sm.removeShellFolder(guid.ToString());
}
}
internal class ShellextensionManger
{
private const uint SORT_ORDER_VERY_TOP = 1;
public ShellextensionManger() {}
public void createShellFolder(string strGUID, string strFolderTitle, IEnumerable<string> strTargetFolderPaths, string strIconPath)
{
RegistryKey localKey, keyTemp, rootKey;
localKey = getRegistryKeyArcgIndependent(RegistryHive.CurrentUser);
// Add your CLSID and name your extension
rootKey = localKey.CreateSubKey(#"Software\Classes\CLSID\{" + strGUID + "}");
rootKey.SetValue("", strFolderTitle, RegistryValueKind.String);
// Add your extension to the Navigation Pane and make it visible
rootKey.SetValue("System.IsPinnedToNameSpaceTree", unchecked((int)0x1), RegistryValueKind.DWord);
// Set the location for your extension in the Navigation Pane
rootKey.SetValue("SortOrderIndex", unchecked((int) SORT_ORDER_VERY_TOP), RegistryValueKind.DWord);
// Set the image for your icon
keyTemp = rootKey.CreateSubKey(#"DefaultIcon");
keyTemp.SetValue("", strIconPath, RegistryValueKind.ExpandString);
keyTemp.Close();
// Provide the dll that hosts your extension.
keyTemp = rootKey.CreateSubKey(#"InProcServer32");
keyTemp.SetValue("", #"%systemroot%\system32\shell32.dll", RegistryValueKind.ExpandString);
keyTemp.Close();
/*
* Define the instance object
* Indicate that your namespace extension should function like other file folder structures in File Explorer. For more information about shell instance objects, see Creating Shell Extensions with Shell Instance Objects.
*/
keyTemp = rootKey.CreateSubKey(#"Instance");
keyTemp.SetValue("CLSID", "{0E5AAE11-A475-4c5b-AB00-C66DE400274E}", RegistryValueKind.String);
keyTemp.Close();
foreach (String path in strTargetFolderPaths) {
keyTemp = rootKey.CreateSubKey(#"Instance\InitPropertyBag");
// Provide the file system attributes of the target folder
keyTemp.SetValue("Attributes", unchecked((int) (FileAttributes.Directory & FileAttributes.ReadOnly)), RegistryValueKind.DWord);
// Set the path for the sync root
keyTemp.SetValue("TargetFolderPath", path, RegistryValueKind.ExpandString);
keyTemp.Close();
}
// Set appropriate shell flags
keyTemp = rootKey.CreateSubKey(#"ShellFolder");
keyTemp.SetValue("FolderValueFlags", unchecked((int)0x28), RegistryValueKind.DWord);
// Set the appropriate flags to control your shell behavior
keyTemp.SetValue("Attributes", unchecked((int)0xF080004D), RegistryValueKind.DWord);
keyTemp.Close();
rootKey.Close();
// Register your extension in the namespace root
keyTemp = localKey.CreateSubKey(#"Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\{" + strGUID + "}");
keyTemp.SetValue("", strFolderTitle, RegistryValueKind.String);
keyTemp.Close();
// Hide your extension from the Desktop
keyTemp = localKey.CreateSubKey(#"Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel");
keyTemp.SetValue("{" + strGUID + "}", unchecked((int)0x1), RegistryValueKind.DWord);
keyTemp.Close();
}
public void removeShellFolder(string strGUID)
{
RegistryKey localKey;
localKey = getRegistryKeyArcgIndependent(RegistryHive.CurrentUser);
localKey.DeleteSubKeyTree(#"Software\Classes\CLSID\{" + strGUID + "}", false);
localKey.DeleteSubKey(#"Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\{" + strGUID + "}", false);
localKey.DeleteSubKey(#"Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel", false);
}
private RegistryKey getRegistryKeyArcgIndependent(RegistryHive registryHive) {
RegistryView registryView = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32;
return RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, registryView);
}
}
Please note that I remove that entry at the end of the main for debugging purpose. Set a breakpoint if you try the code.
I'm trying to register my own app so it appears in the list for selecting a a default browser in Windows using info I've found around the internet. The code all runs with no problem, and seems to create the correct registry keys, but my app doesn't show up in the Browser Selection options in Windows 8.1.
I haven't set the UserChoice values shown in some code samples online, as that looks like it'd actually set the default browser (there's only one value), and I'm not trying to do that, only register it as an option.
The relevant code is in RegisterBrowser, but I've included the full class for convenience.
using System;
using System.Reflection;
using Microsoft.Win32;
namespace MyApp
{
class Program
{
const string AppID = "MyApp";
const string AppName = "My App";
const string AppDescription = "My App";
static string AppPath = Assembly.GetExecutingAssembly().Location;
static string AppIcon = AppPath + ",0";
static string AppOpenUrlCommand = AppPath + " %1";
static string AppReinstallCommand = AppPath + " --register";
static void Main(string[] args)
{
if (args == null || args.Length != 1 || !HandleArg(args[0]))
ShowHelpInfo();
}
static bool HandleArg(string arg)
{
if (string.Equals(arg, "--register", StringComparison.OrdinalIgnoreCase))
RegisterBrowser();
else if (string.Equals(arg, "--unregister", StringComparison.OrdinalIgnoreCase))
UnregisterBrowser();
else if (arg.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || arg.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || arg.StartsWith("ftp://", StringComparison.OrdinalIgnoreCase))
LaunchBrowser(arg);
else
return false;
return true;
}
static void ShowHelpInfo()
{
Console.WriteLine("Usage:");
Console.WriteLine(" MyApp.exe --register Register as web browser");
Console.WriteLine(" MyApp.exe --unregister Unregister as web browser");
Console.WriteLine(" MyApp.exe \"http://example.org/\" Launch example.org in specified browser");
}
static void RegisterBrowser()
{
// Register application.
var appReg = Registry.LocalMachine.CreateSubKey(string.Format("SOFTWARE\\Clients\\StartMenuInternet\\{0}", AppID));
appReg.SetValue("", AppName);
appReg.CreateSubKey("DefaultIcon").SetValue("", AppIcon);
appReg.CreateSubKey("shell\\open\\command").SetValue("", AppOpenUrlCommand);
// Install info.
var appInstallInfo = appReg.CreateSubKey("InstallInfo");
appInstallInfo.SetValue("IconsVisible", 1);
appInstallInfo.SetValue("ShowIconsCommand", AppPath); // TOOD: Do I need to support this?
appInstallInfo.SetValue("HideIconsCommand", AppPath); // TOOD: Do I need to support this?
appInstallInfo.SetValue("ReinstallCommand", AppReinstallCommand);
// Register capabilities.
var capabilityReg = appReg.CreateSubKey("Capabilities");
capabilityReg.SetValue("ApplicationName", AppName);
capabilityReg.SetValue("ApplicationIcon", AppIcon);
capabilityReg.SetValue("ApplicationDescription", AppDescription);
// Set up protocols we want to handle.
var urlAssoc = capabilityReg.CreateSubKey("URLAssociations");
urlAssoc.SetValue("http", AppID);
urlAssoc.SetValue("https", AppID);
urlAssoc.SetValue("ftp", AppID);
}
static void UnregisterBrowser()
{
Registry.LocalMachine.DeleteSubKeyTree(string.Format("SOFTWARE\\Clients\\StartMenuInternet\\{0}", AppID), false);
}
static void LaunchBrowser(string arg)
{
Console.WriteLine(arg);
Console.ReadLine();
}
}
}
I don't know about code specifically but if you just need a registry file you can do the following: (it will register your app with the default programs and set up all the handlers for you)
Windows Registry Editor Version 5.00
; Infamous capabilities:
[HKEY_LOCAL_MACHINE\SOFTWARE\MyApp\Capabilities]
"ApplicationDescription"="MyApp"
"ApplicationIcon"="C:\\MyApp\\MyApp.exe,0"
"ApplicationName"="MyApp"
[HKEY_LOCAL_MACHINE\SOFTWARE\MyApp\Capabilities\FileAssociations]
".htm"="MyAppURL"
".html"="MyAppURL"
".shtml"="MyAppURL"
".xht"="MyAppURL"
".xhtml"="MyAppURL"
[HKEY_LOCAL_MACHINE\SOFTWARE\MyApp\Capabilities\URLAssociations]
"ftp"="MyAppURL"
"http"="MyAppURL"
"https"="MyAppURL"
; Register to Default Programs
[HKEY_LOCAL_MACHINE\SOFTWARE\RegisteredApplications]
"MyApp"="Software\\MyApp\\Capabilities"
; MyAppURL HANDLER:
[HKEY_LOCAL_MACHINE\Software\Classes\MyAppURL]
#="MyApp Document"
"FriendlyTypeName"="MyApp Document"
[HKEY_LOCAL_MACHINE\Software\Classes\MyAppURL\shell]
[HKEY_LOCAL_MACHINE\Software\Classes\MyAppURL\shell\open]
[HKEY_LOCAL_MACHINE\Software\Classes\MyAppURL\shell\open\command]
#="\"C:\\MyApp\\MyApp.exe\" \"%1\""
I found this link:
C# Launch default browser with a default search query
But with FireFox as my default browser, it tries to find a file named as whatever is in the quotes in the selected Answer there.
Code;
//ToolStripMenu Click event to launch default browser and search internet for the value in a particular cell
private void tsmSearch_Click(object sender, EventArgs e)
{
int key = mp.GetRowAt(gdcErrorLogDefaultView, rowX, rowY);
if (key < 0)
return;
string ex = gdcErrorLogDefaultView.GetRowCellValue(key, "Exception").ToString();
string name = GetDefaultBrowser();
Process.Start(name, "\"?" + ex + "\"");
}
//Gets default browser from registry
private string GetDefaultBrowser()
{
string name;
RegistryKey regKey = null;
try
{
//set the registry key we want to open
regKey = Registry.ClassesRoot.OpenSubKey("HTTP\\shell\\open\\command", false);
//get rid of the enclosing quotes
name = regKey.GetValue(null).ToString().ToLower().Replace("" + (char)34, "");
//check to see if the value ends with .exe (this way we can remove any command line arguments)
if (!name.EndsWith("exe"))
//get rid of all command line arguments (anything after the .exe must go)
name = name.Substring(0, name.LastIndexOf(".exe") + 4);
}
catch (Exception ex)
{
name = string.Format("ERROR: An exception of type: {0} occurred in method: {1} in the following module: {2}", ex.GetType(), ex.TargetSite, this.GetType());
}
finally
{
//check and see if the key is still open, if so
//then close it
if (regKey != null)
regKey.Close();
}
return name;
}
I found the GetDefaultBrowser() code somewhere on StackOverflow yesterday but I can't find the link now. The weird thing is though, I have Chrome set as my default browser but that registry key still says FireFox.
Is there a more simple way to launch the default browser and use their default search provider to look up a term?
Try this:
string searchQuery = "this is a search";
Process.Start("https://www.google.com/search?q=" + Uri.EscapeDataString(searchQuery));
Edit: Now using correct Google link
I have a web application which is importing DLLs from the bin folder.
const string dllpath = "Utility.dll";
[DllImport(dllpath)]
Now what I want to do is first import the DLLs from a folder not in the current project but at some different location.
The path of that folder is stored in a registry key.
How should I do this?
Edit:
Why can't I work this out???
public partial class Reports1 : System.Web.UI.Page
{
RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(#"Software\xyz");
string pathName = (string)registryKey.GetValue("BinDir");
const string dllpath = pathName;
[DllImport(dllpath)]
public static extern bool GetErrorString(uint lookupCode, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder buf, uint bufSize);
protected void Page_Load(object sender, EventArgs e)
{
string pathName = (string)registryKey.GetValue("BinDir"); is not working here, but is working in the pageload event...
But if I do this DLL import won't work...
How can I fix this?
Reading the registry is pretty straightforward. The Microsoft.Win32 namespace has a Registry static class. To read a key from the HKLM node, the code is:
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("Software\\NodeName")
If the node is HKCU, you can replace LocalMachine with CurrentUser.
Once you have the RegistryKey object, use GetValue to get the value from the registry. Continuing Using the example above, getting the pathName registry value would be:
string pathName = (string) registryKey.GetValue("pathName");
And don't forget to close the RegistryKey object when you are done with it (or put the statement to get the value into a Using block).
Updates
I see a couple of things. First, I would change pathName to be a static property defined as:
Private static string PathName
{
get
{
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(#"Software\Copium"))
{
return (string)registryKey.GetValue("BinDir");
}
}
}
The two issues were:
The RegistryKey reference will keep the registry open. Using that as a static variable in the class will cause issues on the computer.
Registry path's use forward slashes, not back slashes.
None of these answers worked for me. This is what I used:
static void Main()
{
const string dotNetFourPath = "Software\\Microsoft";//note backslash
using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(dotNetFourPath))
{
Console.WriteLine(registryKey.SubKeyCount);//registry is not null
foreach (var VARIABLE in registryKey.GetSubKeyNames())
{
Console.WriteLine(VARIABLE);//here I can see I have many keys
//no need to switch to x64 as suggested on other posts
}
}
}
All these answers may lead to problems running on 64bit OS - which is usual nowadays.
In my situation, i compile to 'Any CPU' target and the software is working fine when i install on 64bit OS.
But my unit tests are running into problems - obviously they are executed in 32bit mode.
In this case not the HKEY_LOCAL_MACHINE\SOFTWARE\MyCompany\MySoftware is searched but HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\MyCompany\MySoftware but there are no entries!
In this situation we have to specify the start point of our search using
RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)
In total we can use.
string configurationDirectory = string.Empty;
using (RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (RegistryKey registryKey = hklm.OpenSubKey(#"SOFTWARE\MyCompany\MySoftware"))
{
if (registryKey != null)
{
configurationDirectory = (string)registryKey.GetValue("ConfigurationDirectory");
}
}
}
try
{
RegistryKey regKey = Registry.LocalMachine;
regKey = regKey.OpenSubKey(#"Software\Application\");
if (regKey != null)
{
return regKey.GetValue("KEY NAME").ToString();
}
else
{
return null;
}
}
catch (Exception ex)
{
return null;
}
You can use this:
/// <summary>
/// To read a registry key.
/// input: KeyName (string)
/// output: value (string)
/// </summary>
public string Read(string KeyName)
{
// Opening the registry key
RegistryKey rk = baseRegistryKey ;
// Open a subKey as read-only
RegistryKey sk1 = rk.OpenSubKey(subKey);
// If the RegistrySubKey doesn't exist -> (null)
if ( sk1 == null )
{
return null;
}
else
{
try
{
// If the RegistryKey exists I get its value
// or null is returned.
return (string)sk1.GetValue(KeyName.ToUpper());
}
catch (Exception e)
{
// AAAAAAAAAAARGH, an error!
ShowErrorMessage(e, "Reading registry " + KeyName.ToUpper());
return null;
}
}
}
For more information visit this web site .