Silverlight version not display in Listbox WPF - c#

Can anyone help me what's the problem.
When I run it, it will show a blank Listbox how can I want to display. Only silver light version.
Thank you.
private void GetSilverLightInstall()
{
string uninstallKey = #"SOFTWARE\Microsoft\Silverlight\Version";
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(uninstallKey))
{
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
lsitBox1.Items.Add(sk.GetValue("DisplayName"));
}
}
}
}

On my system Version is a string value, not a key. Hence the following works for me:
var keyName = #"SOFTWARE\Microsoft\Silverlight";
using (var regKey = Registry.LocalMachine.OpenSubKey(keyName))
{
var version = regKey.GetValue("Version") as string;
Debug.WriteLine(version);
}

Related

How to delete a registry value in C#?

i want to know how can i delete a registry value in C# like "SOFTWARE\Microsoft\Cryptography" and inside Cryptography key i want to delete MachineGuid. i've tried this ("using Microsoft.Win32;")
string keyName = #"Software\Microsoft\Cryptography";
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(keyName, true))
{
if (key == null)
{
MessageBox.Show("Value Cannot Be Found");
}
else
{
key.DeleteValue("MachineGuid");
}
}
But didn't work. (i mean MachineGuid Value was still there)
this should work
string keyName = #"Software\Microsoft\Cryptography";
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true))
{
if (key == null)
{
MessageBox.Show("Value Cannot Be Found");
}
else
{
key.DeleteValue("MachineGuid");
}
}
I dont recommend deleting it though lol

Determine if a Database is "Equal" to a DacPackage

Is there a way to use the SQL Server 2012 Microsoft.SqlServer.Dac Namespace to determine if a database has an identical schema to that described by a DacPackage object? I've looked at the API docs for DacPackage as well as DacServices, but not having any luck; am I missing something?
Yes there is, I have been using the following technique since 2012 without issue.
Calculate a fingerprint of the dacpac.
Store that fingerprint in the target database.
The .dacpac is just a zip file containing goodies like metadata, and
model information.
Here's a screen-grab of what you will find in the .dacpac:
The file model.xml has XML structured like the following
<DataSchemaModel>
<Header>
... developer specific stuff is in here
</Header>
<Model>
.. database model definition is in here
</Model>
</<DataSchemaModel>
What we need to do is extract the contents from <Model>...</Model>
and treat this as the fingerprint of the schema.
"But wait!" you say. "Origin.xml has the following nodes:"
<Checksums>
<Checksum Uri="/model.xml">EB1B87793DB57B3BB5D4D9826D5566B42FA956EDF711BB96F713D06BA3D309DE</Checksum>
</Checksums>
In my experience, this <Checksum> node changes regardless of a schema change in the model.
So let's get to it.
Calculate the fingerprint of the dacpac.
using System.IO;
using System.IO.Packaging;
using System.Security.Cryptography;
static string DacPacFingerprint(byte[] dacPacBytes)
{
using (var ms = new MemoryStream(dacPacBytes))
using (var package = ZipPackage.Open(ms))
{
var modelFile = package.GetPart(new Uri("/model.xml", UriKind.Relative));
using (var streamReader = new System.IO.StreamReader(modelFile.GetStream()))
{
var xmlDoc = new XmlDocument() { InnerXml = streamReader.ReadToEnd() };
foreach (XmlNode childNode in xmlDoc.DocumentElement.ChildNodes)
{
if (childNode.Name == "Header")
{
// skip the Header node as described
xmlDoc.DocumentElement.RemoveChild(childNode);
break;
}
}
using (var crypto = new SHA512CryptoServiceProvider())
{
byte[] retVal = crypto.ComputeHash(Encoding.UTF8.GetBytes(xmlDoc.InnerXml));
return BitConverter.ToString(retVal).Replace("-", "");// hex string
}
}
}
}
With this fingerprint now available, pseudo code for applying a dacpac can be:
void main()
{
var dacpacBytes = File.ReadAllBytes("<path-to-dacpac>");
var dacpacFingerPrint = DacPacFingerprint(dacpacBytes);// see above
var databaseFingerPrint = Database.GetFingerprint();//however you choose to do this
if(databaseFingerPrint != dacpacFingerPrint)
{
DeployDacpac(...);//however you choose to do this
Database.SetFingerprint(dacpacFingerPrint);//however you choose to do this
}
}
Here's what I've come up with, but I'm not really crazy about it. If anyone can point out any bugs, edge cases, or better approaches, I'd be much obliged.
...
DacServices dacSvc = new DacServices(connectionString);
string deployScript = dacSvc.GenerateDeployScript(myDacpac, #"aDb", deployOptions);
if (DatabaseEqualsDacPackage(deployScript))
{
Console.WriteLine("The database and the DacPackage are equal");
}
...
bool DatabaseEqualsDacPackage(string deployScript)
{
string equalStr = string.Format("GO{0}USE [$(DatabaseName)];{0}{0}{0}GO{0}PRINT N'Update complete.'{0}GO", Environment.NewLine);
return deployScript.Contains(equalStr);
}
...
What I really don't like about this approach is that it's entirely dependent upon the format of the generated deployment script, and therefore extremely brittle. Questions, comments and suggestions very welcome.
#Aaron Hudon answer does not account for post script changes. Sometimes you just add a new entry to a type table without changing the model. In our case we want this to count as new dacpac. Here is my modification of his code to account for that
private static string DacPacFingerprint(string path)
{
using (var stream = File.OpenRead(path))
using (var package = Package.Open(stream))
{
var extractors = new IDacPacDataExtractor [] {new ModelExtractor(), new PostScriptExtractor()};
string content = string.Join("_", extractors.Select(e =>
{
var modelFile = package.GetPart(new Uri($"/{e.Filename}", UriKind.Relative));
using (var streamReader = new StreamReader(modelFile.GetStream()))
{
return e.ExtractData(streamReader);
}
}));
using (var crypto = new MD5CryptoServiceProvider())
{
byte[] retVal = crypto.ComputeHash(Encoding.UTF8.GetBytes(content));
return BitConverter.ToString(retVal).Replace("-", "");// hex string
}
}
}
private class ModelExtractor : IDacPacDataExtractor
{
public string Filename { get; } = "model.xml";
public string ExtractData(StreamReader streamReader)
{
var xmlDoc = new XmlDocument() { InnerXml = streamReader.ReadToEnd() };
foreach (XmlNode childNode in xmlDoc.DocumentElement.ChildNodes)
{
if (childNode.Name == "Header")
{
// skip the Header node as described
xmlDoc.DocumentElement.RemoveChild(childNode);
break;
}
}
return xmlDoc.InnerXml;
}
}
private class PostScriptExtractor : IDacPacDataExtractor
{
public string Filename { get; } = "postdeploy.sql";
public string ExtractData(StreamReader stream)
{
return stream.ReadToEnd();
}
}
private interface IDacPacDataExtractor
{
string Filename { get; }
string ExtractData(StreamReader stream);
}

Check if application is installed in registry

Right now I use this to list all the applications listed in the registry for 32bit & 64.
I have seen the other examples of how to check if an application is installed without any luck.
string registryKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
foreach (String a in key.GetSubKeyNames())
{
RegistryKey subkey = key.OpenSubKey(a);
Console.WriteLine(subkey.GetValue("DisplayName"));
}
}
registryKey = #"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
foreach (String a in key.GetSubKeyNames())
{
RegistryKey subkey = key.OpenSubKey(a);
Console.WriteLine(subkey.GetValue("DisplayName"));
}
}
So this snippet lists it all in the console window and what I am trying to do is
just find one program title out of the list of display names to see if it's installed.
The last thing I tried was
if (subkey.Name.Contains("OpenSSL"))
Console.Writeline("OpenSSL Found");
else
Console.Writeline("OpenSSL Not Found");
Anything I tried came back either false or a false positive. Is there anyone that can show me how to just grab a title out of the list?
Please don't post up the well-known private static void IsApplicationInstalled(p_name) function. It does not work for me at all.
After searching and troubleshooting, I got it to work this way:
public static bool checkInstalled (string c_name)
{
string displayName;
string registryKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
foreach (RegistryKey subkey in key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName)))
{
displayName = subkey.GetValue("DisplayName") as string;
if (displayName != null && displayName.Contains(c_name))
{
return true;
}
}
key.Close();
}
registryKey = #"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
foreach (RegistryKey subkey in key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName)))
{
displayName = subkey.GetValue("DisplayName") as string;
if (displayName != null && displayName.Contains(c_name))
{
return true;
}
}
key.Close();
}
return false;
}
And I simply just call it using
if(checkInstalled("Application Name"))
This is a clean way to do this without that much code.
private static bool IsSoftwareInstalled(string softwareName)
{
var key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") ??
Registry.LocalMachine.OpenSubKey(
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
if (key == null)
return false;
return key.GetSubKeyNames()
.Select(keyName => key.OpenSubKey(keyName))
.Select(subkey => subkey.GetValue("DisplayName") as string)
.Any(displayName => displayName != null && displayName.Contains(softwareName));
}
Call it with a if-statement:
if (IsSoftwareInstalled("OpenSSL"))
I have checked #Stellan Lindell's code and it doesn't work in all cases.
My version should work in all scenarios and checks the specific version of installed programs(x86, x64).
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Win32;
namespace Test
{
internal class Program
{
public enum ProgramVersion
{
x86,
x64
}
private static IEnumerable<string> GetRegisterSubkeys(RegistryKey registryKey)
{
return registryKey.GetSubKeyNames()
.Select(registryKey.OpenSubKey)
.Select(subkey => subkey.GetValue("DisplayName") as string);
}
private static bool CheckNode(RegistryKey registryKey, string applicationName, ProgramVersion? programVersion)
{
return GetRegisterSubkeys(registryKey).Any(displayName => displayName != null
&& displayName.Contains(applicationName)
&& displayName.Contains(programVersion.ToString()));
}
private static bool CheckApplication(string registryKey, string applicationName, ProgramVersion? programVersion)
{
RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null)
{
if (CheckNode(key, applicationName, programVersion))
return true;
key.Close();
}
return false;
}
public static bool IsSoftwareInstalled(string applicationName, ProgramVersion? programVersion)
{
string[] registryKey = new [] {
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
};
return registryKey.Any(key => CheckApplication(key, applicationName, programVersion));
}
private static void Main()
{
// Examples
Console.WriteLine("Notepad++: " + IsSoftwareInstalled("Notepad++", null));
Console.WriteLine("Notepad++(x86): " + IsSoftwareInstalled("Notepad++", ProgramVersion.x86));
Console.WriteLine("Notepad++(x64): " + IsSoftwareInstalled("Notepad++", ProgramVersion.x64));
Console.WriteLine("Microsoft Visual C++ 2009: " + IsSoftwareInstalled("Microsoft Visual C++ 2009", null));
Console.WriteLine("Microsoft Visual C-- 2009: " + IsSoftwareInstalled("Microsoft Visual C-- 2009", null));
Console.WriteLine("Microsoft Visual C++ 2013: " + IsSoftwareInstalled("Microsoft Visual C++ 2013", null));
Console.WriteLine("Microsoft Visual C++ 2012 Redistributable (x86): " + IsSoftwareInstalled("Microsoft Visual C++ 2013", ProgramVersion.x86));
Console.WriteLine("Microsoft Visual C++ 2012 Redistributable (x64): " + IsSoftwareInstalled("Microsoft Visual C++ 2013", ProgramVersion.x64));
Console.ReadKey();
}
}
}
The solution #Hyperion is ok but it has an error because for 32 bit configurations. No 64 bit registers are returned. To receive 64 bit registers, do the following:
string registryKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey key64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey key = key64.OpenSubKey(registryKey);
Solutions above are really good, but sometimes you have to check if product is installed also on another machine. So there is a version based on solutions above from #Stellan Lindell and #Mroczny Arturek
This method works OK for local machine and also remote machine...
public static bool IsSoftwareInstalled(string softwareName, string remoteMachine = null, StringComparison strComparison = StringComparison.Ordinal)
{
string uninstallRegKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryView[] enumValues = (RegistryView[])Enum.GetValues(typeof(RegistryView));
//Starts from 1, because first one is Default, so we dont need it...
for (int i = 1; i < enumValues.Length; i++)
{
//This one key is all what we need, because RegView will do the rest for us
using (RegistryKey key = (string.IsNullOrWhiteSpace(remoteMachine))
? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, enumValues[i]).OpenSubKey(uninstallRegKey)
: RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, remoteMachine, enumValues[i]).OpenSubKey(uninstallRegKey))
{
if (key != null)
{
if (key.GetSubKeyNames()
.Select(keyName => key.OpenSubKey(keyName))
.Select(subKey => subKey.GetValue("DisplayName") as string)
//SomeTimes we really need the case sensitive/insensitive option...
.Any(displayName => displayName != null && displayName.IndexOf(softwareName, strComparison) >= 0))
{ return true; }
}
}
}
return false;
}
The registry version is only one from two standard options.. Another option is using WMI, but the registry one is much better due to performance, so take WMI only as a alternative.
//This one does't have a case sensitive/insesitive option, but if you need it, just don't use LIKE %softwareName%
//and get all products (SELECT Name FROM Win32_Product). After that just go trough the result and compare...
public static bool IsSoftwareInstalledWMI(string softwareName, string remoteMachine = null)
{
string wmiPath = (!string.IsNullOrEmpty(remoteMachine))
? #"\\" + remoteMachine + #"\root\cimv2"
: #"\\" + Environment.MachineName + #"\root\cimv2";
SelectQuery select = new SelectQuery(string.Format("SELECT * FROM Win32_Product WHERE Name LIKE \"%{0}%\"", softwareName));
if (SelectStringsFromWMI(select, new ManagementScope(wmiPath)).Count > 0) { return true; }
return false;
}
There is my SelectStringsFromWMI method, but you can do this on your own, this is not important part of this solution. But if you are intersted, there it is...
public static List<Dictionary<string, string>> SelectStringsFromWMI(SelectQuery select, ManagementScope wmiScope)
{
List<Dictionary<string, string>> result = new List<Dictionary<string, string>>();
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiScope, select))
{
using (ManagementObjectCollection objectCollection = searcher.Get())
{
foreach (ManagementObject managementObject in objectCollection)
{
//With every new object we add new Dictionary
result.Add(new Dictionary<string, string>());
foreach (PropertyData property in managementObject.Properties)
{
//Always add data to newest Dictionary
result.Last().Add(property.Name, property.Value?.ToString());
}
}
return result;
}
}
}
!!UPDATE!!
Due to really bad performance, there is another improvement. Just get values async..
public static bool IsSoftwareInstalled(string softwareName, string remoteMachine = null, StringComparison strComparison = StringComparison.Ordinal)
{
string uninstallRegKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryView[] enumValues = (RegistryView[])Enum.GetValues(typeof(RegistryView));
//Starts from 1, because first one is Default, so we dont need it...
for (int i = 1; i < enumValues.Length; i++)
{
//This one key is all what we need, because RegView will do the rest for us
using (RegistryKey regKey = (string.IsNullOrWhiteSpace(remoteMachine))
? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, enumValues[i]).OpenSubKey(uninstallRegKey)
: RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, remoteMachine, enumValues[i]).OpenSubKey(uninstallRegKey))
{
if (SearchSubKeysForValue(regKey, "DisplayName", softwareName, strComparison).Result)
{ return true; }
}
}
return false;
}
And the SearchSubKeysForValue method (can be build as extension method):
public static async Task<bool> SearchSubKeysForValue(RegistryKey regKey, string valueName, string searchedValue, StringComparison strComparison = StringComparison.Ordinal)
{
bool result = false;
string[] subKeysNames = regKey.GetSubKeyNames();
List<Task<bool>> tasks = new List<Task<bool>>();
for (int i = 0; i < subKeysNames.Length - 1; i++)
{
//We have to save current value for i, because we cannot use it in async task due to changed values for it during foor loop
string subKeyName = subKeysNames[i];
tasks.Add(Task.Run(() =>
{
string value = regKey.OpenSubKey(subKeyName)?.GetValue(valueName)?.ToString() ?? null;
return (value != null && value.IndexOf(searchedValue, strComparison) >= 0);
}));
}
bool[] results = await Task.WhenAll(tasks).ConfigureAwait(false);
result = results.Contains(true);
return result;
}
I tried the solutions here, but they didnt work in some cases. The reason was, that my programm is 32 bit and runs on 64 bit Windows. With the solutions posted here a 32bit process can not check whether a 64 bit application is installed.
How to access 64 bit registry with a 32 bit process
RegistryKey.OpenBaseKey
I modifed the solutions here to get a working one for this issue:
Usage example
Console.WriteLine(IsSoftwareInstalled("Notepad++"));
Code
public static bool IsSoftwareInstalled(string softwareName)
{
var registryUninstallPath = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
var registryUninstallPathFor32BitOn64Bit = #"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
if (Is32BitWindows())
return IsSoftwareInstalled(softwareName, RegistryView.Registry32, registryUninstallPath);
var is64BitSoftwareInstalled = IsSoftwareInstalled(softwareName, RegistryView.Registry64, registryUninstallPath);
var is32BitSoftwareInstalled = IsSoftwareInstalled(softwareName, RegistryView.Registry64, registryUninstallPathFor32BitOn64Bit);
return is64BitSoftwareInstalled || is32BitSoftwareInstalled;
}
private static bool Is32BitWindows() => Environment.Is64BitOperatingSystem == false;
private static bool IsSoftwareInstalled(string softwareName, RegistryView registryView, string installedProgrammsPath)
{
var uninstallKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView)
.OpenSubKey(installedProgrammsPath);
if (uninstallKey == null)
return false;
return uninstallKey.GetSubKeyNames()
.Select(installedSoftwareString => uninstallKey.OpenSubKey(installedSoftwareString))
.Select(installedSoftwareKey => installedSoftwareKey.GetValue("DisplayName") as string)
.Any(installedSoftwareName => installedSoftwareName != null && installedSoftwareName.Contains(softwareName));
}
Here is my version for 64 bits
public static string[] checkInstalled(string findByName)
{
string[] info = new string[3];
string registryKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
//64 bits computer
RegistryKey key64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey key = key64.OpenSubKey(registryKey);
if (key != null)
{
foreach (RegistryKey subkey in key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName)))
{
string displayName = subkey.GetValue("DisplayName") as string;
if (displayName != null && displayName.Contains(findByName))
{
info[0] = displayName;
info[1] = subkey.GetValue("InstallLocation").ToString();
info[2] = subkey.GetValue("Version").ToString();
}
}
key.Close();
}
return info;
}
you can call this method like this
string[] JavaVersion = Software.checkInstalled("Java(TM) SE Development Kit");
if the array is empty means no installation found. if it is not empty it will give you the original name, relative path, and location which in most cases that is all we are looking to get.

C# Exception reading registry: Null reference exception

I'm trying to develop a method to read the programs installed on the machine.
public void refreshProgramsFromWindows () {
string SoftwareKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products";
RegistryKey rk = default(RegistryKey);
rk = Registry.LocalMachine.OpenSubKey(SoftwareKey);
//string skname = null;
string sname = string.Empty;
// New list from scratch
this.installedSoftwareList = new List<software>();
// Object software info
software aSoftware = new software();
foreach (string skname in rk.GetSubKeyNames())
{
// Reset software info
aSoftware.reset();
try
{
// Name of the programm
sname = Registry.LocalMachine.OpenSubKey(SoftwareKey).OpenSubKey(skname).OpenSubKey("InstallProperties").GetValue("DisplayName").ToString();
aSoftware.name = sname;
// Write program to the list
installedSoftwareList.Add(aSoftware);
}
catch (Exception ex)
{
}
}
Net Framework is 4.5 and i'm over Windows 7/8. When i debug this piece of code var rk is null, and it's throwing a null reference exception in the foreach. The app manifest is set to require admin Privileges, so the registry is readable. What is the problem?
Thanks you in advance.
Cheers.
64 bits registry problem:
Added (to handle 64 bit registry):
public static RegistryKey GetRegistryKey()
{
return GetRegistryKey(null);
}
public static RegistryKey GetRegistryKey(string keyPath)
{
RegistryKey localMachineRegistry
= RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
Environment.Is64BitOperatingSystem
? RegistryView.Registry64
: RegistryView.Registry32);
return string.IsNullOrEmpty(keyPath)
? localMachineRegistry
: localMachineRegistry.OpenSubKey(keyPath);
}
public static object GetRegistryValue(string keyPath, string keyName)
{
RegistryKey registry = GetRegistryKey(keyPath);
return registry.GetValue(keyName);
}
And changed:
rk = Registry.LocalMachine.OpenSubKey(SoftwareKey);
to
rk = GetRegistryKey(SoftwareKey);
And now it works.

Check if SQL server (any version) is installed?

I need to find if SQL server is installed on a machine. It could be any version of SQL server (7, 2005,8, sql express etc). We need to know this information as we are writing an installer and need to show to the user that if SQL server has not been found, the installation cannot proceed.
I have seen versions that use the registry, wmi, SMO or simply just connect to SQL server instance (although would not help here as we do not know the server name).
We are using the Wix Installer.
What is the correct way to do this?
JD
A simple way to list all SQL Servers on the network is this:
using System.Data;
using System.Data.Sql;
using System;
...
SqlDataSourceEnumerator sqldatasourceenumerator1 = SqlDataSourceEnumerator.Instance;
DataTable datatable1 = sqldatasourceenumerator1.GetDataSources();
foreach (DataRow row in datatable1.Rows)
{
Console.WriteLine("****************************************");
Console.WriteLine("Server Name:"+row["ServerName"]);
Console.WriteLine("Instance Name:"+row["InstanceName"]);
Console.WriteLine("Is Clustered:"+row["IsClustered"]);
Console.WriteLine("Version:"+row["Version"]);
Console.WriteLine("****************************************");
}
Taken from this blog post.
Another simple alternative would be to use the following command line inside your installer:
sc queryex type= service | find "MSSQL"
The command above simply lists the all the services containing the MSSQL part, listing named and default SQL Server instances. This command returns nothing if nothing is found. It returns something like this:
SERVICE_NAME: MSSQL$SQLEXPRESS
Hope this helps.
Have a look at this question: How can I determine installed SQL Server instances and their versions?
One of the answers lists the registry keys you could check to determine the installed SQL Server version(s).
Or check this codeproject article if you need to find any SQL Servers in the local network: http://www.codeproject.com/KB/database/locate_sql_servers.aspx
I needed something similar, to discover a local SQLServer instance to perform automated tests against.
The SmoApplication was perfect for this requirement - my code looks like this:
public static string GetNameOfFirstAvailableSQLServerInstance()
{
// Only search local instances - pass true to EnumAvailableSqlServers
DataTable dataTable = SmoApplication.EnumAvailableSqlServers(true);
DataRow firstRow = dataTable.Rows[0];
string instanceName = (string)firstRow["Name"];
return instanceName;
}
Another helpful but, late (10 years ago) answer:
public static bool CheckSQLInstalled()
{
bool isOk1 = false;
bool isOk2 = false;
RegistryView registryView = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32;
if (Environment.Is64BitOperatingSystem)
{
using (RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView))
{
RegistryKey instanceKey = hklm.OpenSubKey(#"SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server\Instance Names\SQL", false);
if (instanceKey != null)
{
foreach (var instanceName in instanceKey.GetValueNames())
{
isOk2 = true;
break;
}
}
}
}
using (RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView))
{
RegistryKey instanceKey = hklm.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL", false);
if (instanceKey != null)
{
foreach (var instanceName in instanceKey.GetValueNames())
{
isOk1 = true;
break;
}
}
}
return isOk1 || isOk2;
}
public static bool CheckInstanceInstalled()
{
bool isOk1 = false;
bool isOk2 = false;
RegistryView registryView = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32;
if (Environment.Is64BitOperatingSystem)
{
using (RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView))
{
RegistryKey instanceKey = hklm.OpenSubKey(#"SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server\Instance Names\SQL", false);
if (instanceKey != null)
{
foreach (string instanceName in instanceKey.GetValueNames())
{
if (instanceName.ToUpperInvariant() == "DATABASE_NAME")
{
isOk2 = true;
break;
}
}
}
}
}
using (RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView))
{
RegistryKey instanceKey = hklm.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL", false);
if (instanceKey != null)
{
foreach (var instanceName in instanceKey.GetValueNames())
{
if (instanceName.ToUpperInvariant() == "DATABASE_NAME")
{
isOk1 = true;
break;
}
}
}
}
return isOk1 || isOk2;
}
Add a reference to System.ServiceProcess
then we can query all the services and get any service with SQL string
ServiceController[] sc = ServiceController.GetServices();
foreach (ServiceController item in sc)
{
if (item.ServiceName.Contains("SQL"))
{
MessageBox.Show($#"Service Name: {item.ServiceName}"+"\n"+$#" Status: {item.Status}");
}
}

Categories

Resources