Getting location of file tnsnames.ora by code - c#

How can I get the location of the tnsnames.ora file by code, in a machine with the Oracle client installed?
Is there a windows registry key indicating the location of this file?

Some years ago I had the same problem.
Back then I had to support Oracle 9 and 10 so the code only takes care of those versions, but maybe it saves you from some research.
The idea is to:
search the registry to determine the oracle client version
try to find the ORACLE_HOME
finally get the tnsnames from HOME
public enum OracleVersion
{
Oracle9,
Oracle10,
Oracle0
};
private OracleVersion GetOracleVersion()
{
RegistryKey rgkLM = Registry.LocalMachine;
RegistryKey rgkAllHome = rgkLM.OpenSubKey(#"SOFTWARE\ORACLE\ALL_HOMES");
/*
* 10g Installationen don't have an ALL_HOMES key
* Try to find HOME at SOFTWARE\ORACLE\
* 10g homes start with KEY_
*/
string[] okeys = rgkLM.OpenSubKey(#"SOFTWARE\ORACLE").GetSubKeyNames();
foreach (string okey in okeys)
{
if (okey.StartsWith("KEY_"))
return OracleVersion.Oracle10;
}
if (rgkAllHome != null)
{
string strLastHome = "";
object objLastHome = rgkAllHome.GetValue("LAST_HOME");
strLastHome = objLastHome.ToString();
RegistryKey rgkActualHome = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\ORACLE\HOME" + strLastHome);
string strOraHome = "";
object objOraHome = rgkActualHome.GetValue("ORACLE_HOME");
string strOracleHome = strOraHome = objOraHome.ToString();
return OracleVersion.Oracle9;
}
return OracleVersion.Oracle0;
}
private string GetOracleHome()
{
RegistryKey rgkLM = Registry.LocalMachine;
RegistryKey rgkAllHome = rgkLM.OpenSubKey(#"SOFTWARE\ORACLE\ALL_HOMES");
OracleVersion ov = this.GetOracleVersion();
switch(ov)
{
case OracleVersion.Oracle10:
{
string[] okeys = rgkLM.OpenSubKey(#"SOFTWARE\ORACLE").GetSubKeyNames();
foreach (string okey in okeys)
{
if (okey.StartsWith("KEY_"))
{
return rgkLM.OpenSubKey(#"SOFTWARE\ORACLE\" + okey).GetValue("ORACLE_HOME") as string;
}
}
throw new Exception("No Oracle Home found");
}
case OracleVersion.Oracle9:
{
string strLastHome = "";
object objLastHome = rgkAllHome.GetValue("LAST_HOME");
strLastHome = objLastHome.ToString();
RegistryKey rgkActualHome = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\ORACLE\HOME" + strLastHome);
string strOraHome = "";
object objOraHome = rgkActualHome.GetValue("ORACLE_HOME");
string strOracleHome = strOraHome = objOraHome.ToString();
return strOraHome;
}
default:
{
throw new Exception("No supported Oracle Installation found");
}
}
}
public string GetTNSNAMESORAFilePath()
{
string strOracleHome = GetOracleHome();
if (strOracleHome != "")
{
string strTNSNAMESORAFilePath = strOracleHome + #"\NETWORK\ADMIN\TNSNAMES.ORA";
if (File.Exists(strTNSNAMESORAFilePath))
{
return strTNSNAMESORAFilePath;
}
else
{
strTNSNAMESORAFilePath = strOracleHome + #"\NET80\ADMIN\TNSNAMES.ORA";
if (File.Exists(strTNSNAMESORAFilePath))
{
return strTNSNAMESORAFilePath;
}
else
{
throw new SystemException("Could not find tnsnames.ora");
}
}
}
else
{
throw new SystemException("Could not determine ORAHOME");
}
}

On Windows, the most likely locations are either %ORACLE_HOME%/network/admin or %TNS_ADMIN% (or the TNS_ADMIN registry setting). These two cover almost every installation.
Of course it is possible to have a working Oracle client without this file. Oracle has bewildering array of networking options, and there are plenty of ways to achieve a working setup with using TNSNAMES. Depending on what you are trying to achieve here, your first port of call might be the sqlnet.ora file, which is also found in %ORACLE_HOME%/network/admin. This should contain a line that looks something like this:
NAMES.DIRECTORY_PATH= (LDAP, TNSNAMES, HOSTNAME)
TNSNAMES means it will use the TNSNAMES.ora file (second in this case). LDAP and HOSTNAME are alternate ways of resolving the database. If there is no TNSNAMES the TNSNAMES.ora file will be ignored if it exists in the right place.
In C# / .NET this should get you the environment variables:
Environment.GetEnvironmentVariable("ORACLE_HOME");
Environment.GetEnvironmentVariable("TNS_ADMIN");

List<string> logicalDrives = Directory.GetLogicalDrives().ToList();
List<string> result = new List<string>();
foreach (string drive in logicalDrives)
{
Console.WriteLine("Searching " + drive);
DriveInfo di = new DriveInfo(drive);
if(di.IsReady)
result = Directory.GetFiles(drive, "tnsnames.ora", SearchOption.AllDirectories).ToList();
if (0 < result.Count) return;
}
foreach (string file in result) { Console.WriteLine(result); }

According to the net that depends on the version of Oracle and the working directory of the SQL*Plus process. This first link tells you the environment variable that specifies the base path for some versions (7, 8, 9i) of Oracle. If you use a different one, I'm sure there's a similar way to get to the system directory.
If you spread versions of these files all over the place though and rely on the "look for a local tnsnames.ora first" behaviour of the client, then I guess you're out of luck.

I'm not a C# or a Windows guy for that matter so hopefully this helps. The tnsnames.ora file should be located in:
ORACLE_HOME\network\admin
If an alternate location has been specified, it should be available via the TNS_ADMIN registry key.
See this link for more information on how Oracle handles tns names on Windows.

Related

How to programmatically get information about a running/installed application in windows [duplicate]

How to get the applications installed in the system using c# code?
Iterating through the registry key "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" seems to give a comprehensive list of installed applications.
Aside from the example below, you can find a similar version to what I've done here.
This is a rough example, you'll probaby want to do something to strip out blank rows like in the 2nd link provided.
string registry_key = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using(Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
{
foreach(string subkey_name in key.GetSubKeyNames())
{
using(RegistryKey subkey = key.OpenSubKey(subkey_name))
{
Console.WriteLine(subkey.GetValue("DisplayName"));
}
}
}
Alternatively, you can use WMI as has been mentioned:
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach(ManagementObject mo in mos.Get())
{
Console.WriteLine(mo["Name"]);
}
But this is rather slower to execute, and I've heard it may only list programs installed under "ALLUSERS", though that may be incorrect. It also ignores the Windows components & updates, which may be handy for you.
I wanted to be able to extract a list of apps just as they appear in the start menu. Using the registry, I was getting entries that do not show up in the start menu.
I also wanted to find the exe path and to extract an icon to eventually make a nice looking launcher. Unfortunately, with the registry method this is kind of a hit and miss since my observations are that this information isn't reliably available.
My alternative is based around the shell:AppsFolder which you can access by running explorer.exe shell:appsFolder and which lists all apps, including store apps, currently installed and available through the start menu. The issue is that this is a virtual folder that can't be accessed with System.IO.Directory. Instead, you would have to use native shell32 commands. Fortunately, Microsoft published the Microsoft.WindowsAPICodePack-Shell on Nuget which is a wrapper for the aforementioned commands. Enough said, here's the code:
// GUID taken from https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid
var FOLDERID_AppsFolder = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}");
ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(FOLDERID_AppsFolder);
foreach (var app in (IKnownFolder)appsFolder)
{
// The friendly app name
string name = app.Name;
// The ParsingName property is the AppUserModelID
string appUserModelID = app.ParsingName; // or app.Properties.System.AppUserModel.ID
// You can even get the Jumbo icon in one shot
ImageSource icon = app.Thumbnail.ExtraLargeBitmapSource;
}
And that's all there is to it. You can also start the apps using
System.Diagnostics.Process.Start("explorer.exe", #" shell:appsFolder\" + appModelUserID);
This works for regular Win32 apps and UWP store apps. How about them apples.
Since you are interested in listing all installed apps, it is reasonable to expect that you might want to monitor for new apps or uninstalled apps as well, which you can do using the ShellObjectWatcher:
ShellObjectWatcher sow = new ShellObjectWatcher(appsFolder, false);
sow.AllEvents += (s, e) => DoWhatever();
sow.Start();
Edit: One might also be interested in knowing that the AppUserMoedlID mentioned above is the unique ID Windows uses to group windows in the taskbar.
2022: Tested in Windows 11 and still works great. Windows 11 also seems to cache apps that aren't installed per se, portable apps that don't need installing, for example. They appear in the start menu search results and can also be retrieved from shell:appsFolder as well.
I agree that enumerating through the registry key is the best way.
Note, however, that the key given, #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", will list all applications in a 32-bit Windows installation, and 64-bit applications in a Windows 64-bit installation.
In order to also see 32-bit applications installed on a Windows 64-bit installation, you would also need to enumeration the key #"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall".
You can take a look at this article. It makes use of registry to read the list of installed applications.
public void GetInstalledApps()
{
string uninstallKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(uninstallKey))
{
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
lstInstalled.Items.Add(sk.GetValue("DisplayName"));
}
catch (Exception ex)
{ }
}
}
}
}
While the accepted solution works, it is not complete. By far.
If you want to get all the keys, you need to take into consideration 2 more things:
x86 & x64 applications do not have access to the same registry.
Basically x86 cannot normally access x64 registry. And some
applications only register to the x64 registry.
and
some applications actually install into the CurrentUser registry instead of the LocalMachine
With that in mind, I managed to get ALL installed applications using the following code, WITHOUT using WMI
Here is the code:
List<string> installs = new List<string>();
List<string> keys = new List<string>() {
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
#"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
};
// The RegistryView.Registry64 forces the application to open the registry as x64 even if the application is compiled as x86
FindInstalls(RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64), keys, installs);
FindInstalls(RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64), keys, installs);
installs = installs.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();
installs.Sort(); // The list of ALL installed applications
private void FindInstalls(RegistryKey regKey, List<string> keys, List<string> installed)
{
foreach (string key in keys)
{
using (RegistryKey rk = regKey.OpenSubKey(key))
{
if (rk == null)
{
continue;
}
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
installed.Add(Convert.ToString(sk.GetValue("DisplayName")));
}
catch (Exception ex)
{ }
}
}
}
}
}
it's worth noting that the Win32_Product WMI class represents products as they are installed by Windows Installer. not every application use windows installer
however "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" represents applications for 32 bit. For 64 bit you also need to traverse "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" and since not every software has a 64 bit version the total applications installed are a union of keys on both locations that have "UninstallString" Value with them.
but the best options remains the same .traverse registry keys is a better approach since every application have an entry in registry[including the ones in Windows Installer].however the registry method is insecure as if anyone removes the corresponding key then you will not know the Application entry.On the contrary Altering the HKEY_Classes_ROOT\Installers is more tricky as it is linked with licensing issues such as Microsoft office or other products.
for more robust solution you can always combine registry alternative with the WMI.
string[] registryKeys = new string[] {
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" };
public class InstalledApp
{
public string DisplayName { get; set; }
public string DisplayIcon { get; set; }
public string Version { get; set; }
public string InstallLocation { get; set; }
}
private void AddInstalledAppToResultView(RegistryHive hive, RegistryView view, string registryKey,Dictionary<string,InstalledApp> resultView)
{
using (var key = RegistryKey.OpenBaseKey(hive, view).OpenSubKey(registryKey))
{
foreach (string subKeyName in key.GetSubKeyNames())
{
using (RegistryKey subkey = key.OpenSubKey(subKeyName))
{
var displayName = subkey.GetValue("DisplayName");
var displayIcon = subkey.GetValue("DisplayIcon");
if (displayName == null || displayIcon == null)
continue;
var app = new InstalledApp
{
DisplayName = (string)displayName,
DisplayIcon = (string)displayIcon,
InstallLocation = (string)subkey.GetValue("InstallLocation"),
Version = (string)subkey.GetValue("DisplayVersion")
};
if(!resultView.ContainsKey(app.DisplayName))
{
resultView.Add(app.DisplayName,app);
}
}
}
}
}
void Main()
{
var result = new Dictionary<string,InstalledApp>();
var view = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32;
AddInstalledAppToResultView(RegistryHive.LocalMachine, view, registryKeys[0],result);
AddInstalledAppToResultView(RegistryHive.CurrentUser, view, registryKeys[0],result);
AddInstalledAppToResultView(RegistryHive.LocalMachine, RegistryView.Registry64, registryKeys[1],result);
Console.WriteLine("==============" + result.Count + "=================");
result.Values.ToList().ForEach(item => Console.WriteLine(item));
}
Iterate through "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" keys and check their "DisplayName" values.
Use Windows Installer API!
It allows to make reliable enumeration of all programs. Registry is not reliable, but WMI is heavyweight.
The object for the list:
public class InstalledProgram
{
public string DisplayName { get; set; }
public string Version { get; set; }
public string InstalledDate { get; set; }
public string Publisher { get; set; }
public string UnninstallCommand { get; set; }
public string ModifyPath { get; set; }
}
The call for creating the list:
List<InstalledProgram> installedprograms = new List<InstalledProgram>();
string registry_key = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
using (RegistryKey subkey = key.OpenSubKey(subkey_name))
{
if (subkey.GetValue("DisplayName") != null)
{
installedprograms.Add(new InstalledProgram
{
DisplayName = (string)subkey.GetValue("DisplayName"),
Version = (string)subkey.GetValue("DisplayVersion"),
InstalledDate = (string)subkey.GetValue("InstallDate"),
Publisher = (string)subkey.GetValue("Publisher"),
UnninstallCommand = (string)subkey.GetValue("UninstallString"),
ModifyPath = (string)subkey.GetValue("ModifyPath")
});
}
}
}
}
As others have pointed out, the accepted answer does not return both x86 and x64 installs. Below is my solution for that. It creates a StringBuilder, appends the registry values to it (with formatting), and writes its output to a text file:
const string FORMAT = "{0,-100} {1,-20} {2,-30} {3,-8}\n";
private void LogInstalledSoftware()
{
var line = string.Format(FORMAT, "DisplayName", "Version", "Publisher", "InstallDate");
line += string.Format(FORMAT, "-----------", "-------", "---------", "-----------");
var sb = new StringBuilder(line, 100000);
ReadRegistryUninstall(ref sb, RegistryView.Registry32);
sb.Append($"\n[64 bit section]\n\n{line}");
ReadRegistryUninstall(ref sb, RegistryView.Registry64);
File.WriteAllText(#"c:\temp\log.txt", sb.ToString());
}
private static void ReadRegistryUninstall(ref StringBuilder sb, RegistryView view)
{
const string REGISTRY_KEY = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view);
using var subKey = baseKey.OpenSubKey(REGISTRY_KEY);
foreach (string subkey_name in subKey.GetSubKeyNames())
{
using RegistryKey key = subKey.OpenSubKey(subkey_name);
if (!string.IsNullOrEmpty(key.GetValue("DisplayName") as string))
{
var line = string.Format(FORMAT,
key.GetValue("DisplayName"),
key.GetValue("DisplayVersion"),
key.GetValue("Publisher"),
key.GetValue("InstallDate"));
sb.Append(line);
}
key.Close();
}
subKey.Close();
baseKey.Close();
}
Your best bet is to use WMI. Specifically the Win32_Product class.
Might I suggest you take a look at WMI (Windows Management Instrumentation).
If you add the System.Management reference to your C# project, you'll gain access to the class `ManagementObjectSearcher', which you will probably find useful.
There are various WMI Classes for Installed Applications, but if it was installed with Windows Installer, then the Win32_Product class is probably best suited to you.
ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
I used Nicks approach - I needed to check whether the Remote Tools for Visual Studio are installed or not, it seems a bit slow, but in a seperate thread this is fine for me. - here my extended code:
private bool isRdInstalled() {
ManagementObjectSearcher p = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach (ManagementObject program in p.Get()) {
if (program != null && program.GetPropertyValue("Name") != null && program.GetPropertyValue("Name").ToString().Contains("Microsoft Visual Studio 2012 Remote Debugger")) {
return true;
}
if (program != null && program.GetPropertyValue("Name") != null) {
Trace.WriteLine(program.GetPropertyValue("Name"));
}
}
return false;
}
My requirement is to check if specific software is installed in my system. This solution works as expected. It might help you. I used a windows application in c# with visual studio 2015.
private void Form1_Load(object sender, EventArgs e)
{
object line;
string softwareinstallpath = string.Empty;
string registry_key = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (var baseKey = Microsoft.Win32.RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (var key = baseKey.OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
using (var subKey = key.OpenSubKey(subkey_name))
{
line = subKey.GetValue("DisplayName");
if (line != null && (line.ToString().ToUpper().Contains("SPARK")))
{
softwareinstallpath = subKey.GetValue("InstallLocation").ToString();
listBox1.Items.Add(subKey.GetValue("InstallLocation"));
break;
}
}
}
}
}
if(softwareinstallpath.Equals(string.Empty))
{
MessageBox.Show("The Mirth connect software not installed in this system.")
}
string targetPath = softwareinstallpath + #"\custom-lib\";
string[] files = System.IO.Directory.GetFiles(#"D:\BaseFiles");
// Copy the files and overwrite destination files if they already exist.
foreach (var item in files)
{
string srcfilepath = item;
string fileName = System.IO.Path.GetFileName(item);
System.IO.File.Copy(srcfilepath, targetPath + fileName, true);
}
return;
}

What is the best way to get the fullpath of an application that is not running?

I am trying to get the path of application "WinMergeU.exe" using Path.GetFullPath() but the return value of this code is the folder of my application.
How can i get the fullpath of the application in C: drive while the return value is d using the Path.GetFullPath().
You have to search for the file, e.g.
using system.Linq;
...
// Either full path of "WinMergeU.exe" file or null (if not found)
string result = Directory
.EnumerateFiles(#"c:\", "WinMergeU.exe", SearchOption.AllDirectories)
.FirstOrDefault();
Edit: In case the application is in the C:\Program Files (see comments) we can restrict the scan:
string result = Directory
.EnumerateFiles(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
"WinMergeU.exe",
SearchOption.AllDirectories)
.FirstOrDefault();
Or (if we quite sure in c:\Program Files\WinMerge path) we can just test if the file exits:
string result = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
"WinMerge",
"WinMergeU.exe");
if (File.Exists(result)) {
// we have the file
}
I installed it, as it looked like a handy tool, and searched the registry.
string key = #"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WinMerge.Project.File\shell\open\command";
string path = Microsoft.Win32.Registry.GetValue(key, "", -1);
... seems to contain the value you need. In my case:
"C:\Program Files (x86)\WinMerge\WinMergeU.exe" "%1"
The method will return -1 if the key is not found.
WinMerge doesn't allow to change its installation folder AFAIK, therefore searching the whole drive C is an overkill.
This will suffice:
static string GetWinMergeFullPath()
{
const string executableName = "WinMergeU.exe";
const string installationFolder = "WinMerge";
var locations = new Environment.SpecialFolder[]
{
Environment.SpecialFolder.ProgramFiles,
Environment.SpecialFolder.ProgramFilesX86
};
string fullPath = locations
.Select(l => Path.Combine(Environment.GetFolderPath(l), installationFolder, executableName))
.Where(File.Exists)
.FirstOrDefault();
return fullPath ?? throw new FileNotFoundException(executableName);
}
EDIT
As it was commented the above won't suffice:). The below version uses two registry locations that should contain the path. One is "App Paths" which is provided by the installation, the second one is "Uninstall". While I believe that "App Paths" should be enough I still provided the second one for robustness.Note that it will work even if shell integration is unchecked in the installer! Both 32-bit and 64-bit installations are covered.
static string GetWinMergeFullPathFromRegistryEx()
{
const string executableName = "WinMergeU.exe";
const string appPathKeyName = #"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\";
const string uninstallKeyName = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinMerge_is1";
const string installLocationName = "InstallLocation";
var locations = new List<(string path, string value, bool withFilename)>
{
($"{appPathKeyName}{executableName}", null, true),
(uninstallKeyName, installLocationName, false),
};
List<RegistryView> views = Environment.Is64BitOperatingSystem ?
new List<RegistryView>() { RegistryView.Registry32, RegistryView.Registry64 } :
new List<RegistryView>() { RegistryView.Default };
foreach (var view in views)
{
using (RegistryKey localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view))
foreach (var (path, value, withFilename) in locations)
{
using (RegistryKey key = localMachine.OpenSubKey(path, false))
{
var fullpathValue = key?.GetValue(value);
if (fullpathValue != null)
{
string fullpath = (string)fullpathValue;
if (!withFilename)
fullpath = Path.Combine(fullpath, executableName);
if (File.Exists(fullpath))
return fullpath;
}
}
}
}
throw new FileNotFoundException(executableName);
}
Of course my assumption is that WinMerge was actually installed. If you should support cases when WinMerge was deployed manually then you still can use to the full scan option as a fallback.

OpenSubKey() doesn't contain installed Application that I can see in regedit.exe

I wrote an In/Uninstaller for a custom installation for MongoDb.
My way to install the mongoDB ist the following.
private Process GetInstallMongoProcess() {
Log("Installing MongoDB Version 3.4.10 ...");
Process installProcess = new Process();
installProcess.StartInfo = new ProcessStartInfo("msiexec.exe", $#"/q /Lie {Constants.LogFileName} /i mongodb-win32-x86_64-2008plus-ssl-3.4.10-signed.msi INSTALLLOCATION=""{Constants.Path}3.4\"" ADDLOCAL=""all""");
installProcess.OutputDataReceived += OnInstallProcessDataReceived;
installProcess.Start();
return installProcess;
}
But then I need to check of this Application is installed. The way I do is
private bool CheckIfAlreadyInstalled()
{
string[] registryKeys = { #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", #"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" };
bool appIsInstalled = false;
foreach (string registryKey in registryKeys) {
RegistryKey key = Registry.LocalMachine.OpenSubKey(registryKey);
if (key != null) {
List<string> listOfInstalledApplications = key.GetSubKeyNames().ToList();
appIsInstalled = listOfInstalledApplications.Contains(ApplicationGuid);
}
}
if (appIsInstalled) {
Log("MongoDB is already installed");
}
return appIsInstalled;
}
I can't find my installed application. Neither the name nor the ApplicationGuid. I get about 300 entries, but the entry I need is not present, but I can See the installed Software in Regedit.exe
Do I am searching in wrong node ??

How to find all after effect installed version in c#?

I have problem for detecting the all after effects installed version in c# i used this code for getting the name
static string[] GetAllInstalledSoftware(string strPrefix)
{
const string strUNINSTALL_KEY = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
List<string> listMatches = new List<string>();
// Enumerate all sub keys found under the "Uninstall" key, each sub key represents a installed software
foreach (string strSubKey in Registry.LocalMachine.OpenSubKey(strUNINSTALL_KEY).GetSubKeyNames())
{
// try to get the "DisplayName" for the installed software
object objValue = Registry.LocalMachine.OpenSubKey(strUNINSTALL_KEY + #"\" + strSubKey).GetValue("DisplayName");
if (objValue != null)
{
string strDisplayName = objValue.ToString();
// If display name starts with the desired prefix
if (strDisplayName.StartsWith(strPrefix))
{
// -> add it to the result list
listMatches.Add(strDisplayName);
}
}
}
return listMatches.ToArray();
}
But it only give me only one latest installed name for after effect but i have installed 3 version of after effects CS5, CS6, CC-2014,
so anybody have solution how to find all installed version of after effects?

Access remote registry key with C# in .Net MVC2

I'm using the following code
private static string GetLogonFromMachine(string machine)
{
//1. To read the registry key that stores this value.
//HKEY_Local_Machine\Software\Microsoft\Windows NT\CurrentVersion\WinLogon\DefaultUserName
var rHive = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, machine);
var rKey = rHive.OpenSubKey(#"Software\Microsoft\Windows NT\CurrentVersion\WinLogon");
var rItem = rKey.GetValue("DefaultUserName");
return rItem.ToString();
}
and I've confirmed that my user has access, the MVC site is using integrated authentication and that the listed REG_SZ "DefaultUserName" has a value on the machine targetted but rItem doesn't grab a value.
I guess I'm doing something silly and I'd love to know what!
I was indeed being silly. I wasn't sorting the list of machine names before use and so I was looking at the registry of the wrong machine. The machine that was actually in focus was correctly returning "".
I've ended up with
private static string GetLogonFromMachine(string machine)
{
//1. To read the registry key that stores this value.
//HKEY_Local_Machine\Software\Microsoft\Windows NT\CurrentVersion\WinLogon\DefaultUserName
RegistryKey rHive;
try
{
rHive = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, machine);
}
catch (IOException)
{
return "offline";
}
var rKey = rHive.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon\\");
if (rKey == null)
{
return "No Logon Found";
}
var rItem = rKey.GetValue("DefaultUserName");
return rItem==null ? "No Logon Found" : rItem.ToString();
}

Categories