I am trying to query the following registry key values:
HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\SharedMemoryOn
HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\SuperSocketNetLib\ProtocolOrder
But depending on which machine I'm running the program the query returns null. When I debug on my local machine and I inspect the value for ValueCount for:
HKLM\SOFTWARE\Microsoft\MSSQLServer\Client
HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\SuperSocketNetLib
The count is 0 and OpenSubKey returns null.
I am a domain admin, in the local administrators group and have added the following to my app.manifest:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Any idea why?
private static void ValidateSqlClientSettings()
{
Console.WriteLine("\r\n/////////////// LOCAL SQL CLIENT PROTOCOLS ////////////////");
RegistryKey keyHKLM = Registry.LocalMachine;
///TODO: nullreferenceexception - connect to remote machine and find out why
RegistryKey sqlClientKey = keyHKLM.OpenSubKey(#"SOFTWARE\Microsoft\MSSQLServer\Client");
if (sqlClientKey == null)
{
WriteLine2Console(#"WARNING: unable to read registry key '{0}\SOFTWARE\Microsoft\MSSQLServer\Client'", ConsoleColor.Yellow);
}
var cliKeyNames = from k in sqlClientKey.GetSubKeyNames()
where k == "SuperSocketNetLib"
select k;
///TODO: find out why these values are always missing (even if I can see them in regedit)
Console.Write("Shared Memory Disabled (cliconfg): ");
if (Convert.ToBoolean(sqlClientKey.GetValue("SharedMemoryOn")))
WriteLine2Console("FAILED", ConsoleColor.Red);
else if(sqlClientKey.GetValue("SharedMemoryOn") == null)
WriteLine2Console(String.Format("WARNING - unable to read '{0}\\SharedMemoryOn'", sqlClientKey.Name), ConsoleColor.Yellow);
else
WriteLine2Console("PASS", ConsoleColor.Green);
Console.Write("Client Protocol Order (cliconfg - tcp first): ");
foreach (string cliKey in cliKeyNames)
{
RegistryKey subKey = sqlClientKey.OpenSubKey(cliKey);
object order = subKey.GetValue("ProtocolOrder");
if (order != null && order.ToString().StartsWith("tcp") == false)
{
WriteLine2Console("FAILED", ConsoleColor.Red);
}
else if (order == null)
{
WriteLine2Console(String.Format("WARNING - unable to read '{0}\\ProtocolOrder'", subKey.Name), ConsoleColor.Yellow);
}
else
{
WriteLine2Console("PASS", ConsoleColor.Green);
}
subKey.Close();
}
sqlClientKey.Close();
keyHKLM.Close();
}
Another factor you should pay attention to is application bitness.
On Windows x64, your x86 build will look for the registry keys under (in regedit) "SOFTWARE\WOW6432Node\Microsoft\MSSQLServer\Client", when you specify (in code) "Software\Microsoft\MSSQLServer\Client"
That's a WOW64 redirection for registry keys.
As Visual Studio 2010 by default creates exe in x86 mode, you should pay attention to this tip.
Try changing your sqlclientkey to the following:
RegistryKey sqlClientKey = keyHKLM.OpenSubKey(#"SOFTWARE\\Microsoft\\MSSQLServer\\Client");
Related
I'm unable to take ownership of some keys in the registry with my C# code.
I'm trying take ownership on
Software\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace{1CF1260C-4DD0-4ebb-811F-33C572699FDE}
My app is launched as administrator with the requireAdministrator flag on the app.manifest.
UAC is disabled to test without this security that might interfere.
I'm setting the token SeTakeOwnershipPrivilege properly on my process (Process Explorer confirms me that is enabled on my process).
But when I'm running my code it returns a null key at the OpenSubKey call.
Here is my method :
public void takeKeyOwnership(RegistryHive root, string path)
{
RegistryKey RootKey = GetKey(root);
var key = RootKey.OpenSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership);
if(key == null)
{
logger.Warn("[takeKeyOwnership] Unable to take ownership on key " + root + "\\" + path);
return;
}
var acl = key.GetAccessControl(AccessControlSections.None);
var localAdmins = new SecurityIdentifier(Constants.LocalAdministratorsSID);
acl.SetOwner(localAdmins);
key.SetAccessControl(acl);
key.Close();
}
My question is different from : How do I programmatically give ownership of a Registry Key to Administrators? as I've set the SeTakeOwnerShipPrivilege as specified earlier.
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();
}
}
I have this code:
RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\MSDTC\\Security");
if (key != null)
{
Object o = key.GetValue("NetworkDtcAccessInbound");
if (o != null)
{
}
}
It returns the correct value (1) when i use in normal project, but in Unit Test project it returns wrong value (0), i know coz i see in regedit.
If i check for these keys: LuTransactions, XaTransactions, it returns correct, even in Unit Test Project.
If i check for these: NetworkDtcAccessInbound, NetworkDtcAccessOutbound, NetworkDtcAccess it returns wrong just in Unit Test Project
anyone knows about this behavior?
As #AlexeiLevenkov said it was a x86/x64 mismatch, the Unit Test runs as x86, but my system is x64, i did a web search for a code that read registry for each operation system type.
The code below is for x86 operation system, but my computer is x64, so the code below returned a wrong value (value = 0).
string value32 = string.Empty;
RegistryKey localKey32 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32);
localKey32 = localKey32.OpenSubKey("Software\\Microsoft\\MSDTC\\Security");
if (localKey32 != null)
{
value32 = localKey32.GetValue("NetworkDtcAccessInbound").ToString();
}
The code below is for x64 operation system, my computer is x64, so the code below returned a correct value (value = 1).
string value64 = string.Empty;
RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
localKey = localKey.OpenSubKey("Software\\Microsoft\\MSDTC\\Security");
if (localKey != null)
{
value64 = localKey.GetValue("NetworkDtcAccessInbound").ToString();
}
thats all folks.
What is the best way to find out if reportviewer and WindowsInstaller-KB893803-v2-x86 is installed on a PC? Is there a way to find out what public key to use to find out if a specific program is installed on a PC? (Tried this, didn't work)
Best Way To Determine If .NET 3.5 Is Installed
This is how to check if .NET 3.5 is installed, but i take it you need a another public key to know if report viewer is installed, but I don't know how to get the public key.
All I can think of is to check if the installation directory exists on the computer, would that be an acceptable way to check?
You could check in the Registry
public bool IsInstalled()
{
RegistryKey registryBase = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, string.Empty);
if (registryBase != null)
{
return registryBase.OpenSubKey("Software\\Microsoft\\ReportViewer\\v2.0.50727") != null;
}
return false;
}
In my machine (Win7 & Server 2012), the registry key is different.
bool exist = false;
RegistryKey registryBase = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, string.Empty);
if (registryBase != null)
{
exist = registryBase.OpenSubKey("Software\\Wow6432Node\\Microsoft\\.NETFramework\\v2.0.50727\\AssemblyFoldersEx\\ReportViewer v10") != null;
}
You could also query the GAC for the assemblies, as shown in this SO question.
I did a Regshot diff on a MS Report Viewer version 10 install to find the key because neither of the others posted here were working.
Here is the actual diff results on a fresh windows server VM.
Anyways, the key I found for this version was:
SOFTWARE\Wow6432Node\Microsoft\ReportViewer\v10.0
The code I used:
public bool IsInstalledReportViewer()
{
try
{
RegistryKey registryBase = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, string.Empty);
if (registryBase != null)
{
// check the two possible reportviewer v10 registry keys
return registryBase.OpenSubKey(#"Software\Microsoft\ReportViewer\v2.0.50727") != null
|| registryBase.OpenSubKey(#"Software\Wow6432Node\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\ReportViewer v10") != null
|| registryBase.OpenSubKey(#"SOFTWARE\Wow6432Node\Microsoft\ReportViewer\v10.0") != null;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
// put proper exception handling here
}
return false;
}
I've recently been writing an application that needs access to the following registry key :
HKLM\SOFTWARE\Wow6432Node\Classes\CLSID
For some odd reason, I'm not allowed access to this key on any system I've tested on. I'm using administrative rights and everything in between to attempt to accomplish this. I've searched through the first 5 Google result pages and still turned up empty.
Things to note :
1. The keys I'm attemping to delete may or may not contain subkeys, I've thoroughly tested "DeleteSubKey" and "DeleteSubKeyTree".
2. I've tried OpenSubKey("Key",True), both false and true values still disallowed me access.
3. I'm also not allowed access to the non-64 bit location (HKLM\Software\Classes\CLSID).
4. I've tested this on XP, 7 & 8. XP didn't give me an issue.
5. The exact error I'm receiving can be found below :
Requested registry access is not allowed. at
Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
PLEASE help me..this has been killing me for a few days now. Any help is greatly appreciated.
Microsoft.Win32.RegistryKey m_RegEntry = Microsoft.Win32.Registry.LocalMachine;
m_RegEntry = m_RegEntry.OpenSubKey(#"SYSTEM\CurrentControlSet\Control\Class\{4D36E96D-E325-11CE-BFC1-08002BE10318}");
//string
int i = 0;
string[] m_szModemEntries = m_RegEntry.GetSubKeyNames();
This return many entries connected Devices to COM port . and an entry of "Properties" that we don't need to access.
below I am attaching a simple code to work with it.
string[] m_szModem;
Microsoft.Win32.RegistryKey m_RegEntry = Microsoft.Win32.Registry.LocalMachine;
m_RegEntry = m_RegEntry.OpenSubKey(#"SYSTEM\CurrentControlSet\Control\Class\{4D36E96D-E325-11CE-BFC1-08002BE10318}");
//string
int i = 0;
string[] m_szModemEntries = m_RegEntry.GetSubKeyNames();
m_szModem = new string[m_szModemEntries.Length];
string m_szModemPort = null;
string m_szModemName = null;
foreach (string m_szModemEntry in m_szModemEntries)
{
if (!IsNumber(m_szModemEntry))
{
}
else
{
m_RegEntry.Close();
m_RegEntry = Microsoft.Win32.Registry.LocalMachine;
string m_szKeyName = #"SYSTEM\CurrentControlSet\Control\Class\{4D36E96D-E325-11CE-BFC1-08002BE10318}\" + m_szModemEntry;
m_RegEntry = m_RegEntry.OpenSubKey(m_szKeyName);
m_szModemPort = m_RegEntry.GetValue("AttachedTo").ToString();
m_szModemName = m_RegEntry.GetValue("Model").ToString();
if (m_szModemName.Contains("<device name>"))
{
CommPort = m_szModemPort;
lbldevicename.Text = "Device connected!";
lbldevicename.ForeColor = Color.Green;
cmdProgram.Enabled = true;
DeviceConnected = true;
break;
}
CommPort = "";
cmdProgram.Enabled = false;
lbldevicename.Text = "Device not connected!";
lbldevicename.ForeColor = Color.Red;
DeviceConnected = false;
}
}
//and IsNumber Function
public Boolean IsNumber(String s)
{
foreach (Char ch in s)
{
if (!Char.IsDigit(ch)) return false;
}
return true;
}
You may need to modify the access control security. Use GetAccessControl to get the ACL for the registry key, modify it, and then save it with SetAccessControl.
Here's a solution I've found which works without Admin rights: just leave out the 'true' paramter, and it will read it all. Worked for me!
First login with Local Admin account. Then run regedit.exe and click on the registry key to be edited. From the Edit menu select premissions. Check the permissions of the related user.
I guess related accounts do not have permission to modify the registry key.
in vb.net you can use this to get access of the key before doing any operation on it
x.GetAccessControl(System.Security.AccessControl.AccessControlSections.All)
where x is any reg. key
after seeing your code i tried this and it works
Dim r As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\test", Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree)
r.DeleteSubKey("subkey", True)
Add an app.manifest in Visual studio
add item then search for application manifest file
then Replace the start of it until with this
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
</requestedPrivileges>
</security>
</trustInfo>