From where clickonce get the value used in DisplayName from regedit? - c#

From where the clickonce get the value used in DisplayName in the register HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\XXXXXXXX ? I tried the change the application title and assembly name on VS(project -> properties -> application -> assembly information) but this neither change there changed the name used in DisplayName value.
I need this because I want to avoid hard-code my application name on this piece of code that change the unistall icon of my application on add/remove programs
RegistryKey myUninstallKey = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Uninstall");
string[] mySubKeyNames = myUninstallKey.GetSubKeyNames();
for (int i = 0; i < mySubKeyNames.Length; i++)
{
RegistryKey myKey = myUninstallKey.OpenSubKey(mySubKeyNames[i], true);
object myValue = myKey.GetValue("DisplayName");
if (myValue != null && myValue.ToString() == applictionName) /* this must be the same used by clickonce to set DisplayName value */
{
myKey.SetValue("DisplayIcon", iconSourcePath);
break;
}
}

From where clickonce get the value used in DisplayName from regedit?
To set the display name for a ClickOnce app, you specify it in Publish Options inside Visual Studio prior to publishing. This updates the ClickOnce Manifest - information about the ClickOnce application. This information is more important and essentially veteos any details you may specify in Assembly Information.
<project>.Properties.Publish.Options
Also, there is no need to muck about in the Windows Registry for ClickOnce apps. Doing so may block automatic updates.

object myValue = myKey.GetValue("UrlUpdateInfo");
if(myValue != null)
{
string updateinfo = myValue.ToString();
string updateLocation = ApplicationDeployment.CurrentDeployment.UpdateLocation.ToString();
if (updateinfo==updateLocation)
{
myKey.SetValue("DisplayIcon", iconSourcePath);
break;
}
}

Related

Local Machine Registry Key values not matching when trying to fetch from C#

I am trying to get list of all Installed application from Registry but the Key Values from Registry at
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall are not matching with the values my code is fetching.
Code snippet for fetching Keys from Local Machine_32 - similar for CurrentUser and Local Machine 64
key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", false);
foreach (String keyName in key.GetSubKeyNames())
{
RegistryKey subkey = key.OpenSubKey(keyName);
displayName = subkey.GetValue("DisplayName") != null ? subkey.GetValue("DisplayName").ToString() : "";
version = subkey.GetValue("DisplayVersion") != null ? subkey.GetValue("DisplayVersion").ToString() : "";
install_date = subkey.GetValue("InstallDate") != null ? subkey.GetValue("InstallDate").ToString() : "";
publisher = subkey.GetValue("Publisher") != null ? subkey.GetValue("Publisher").ToString() : "";
install_location = subkey.GetValue("InstallSource") != null ? subkey.GetValue("InstallSource").ToString() : "";
if (displayName != "")
{
installedAppsB.Add(new SoftwareInventory()
{
key = keyName,
app_name = displayName,
version = version,
install_date = install_date,
publisher = publisher,
install_location = install_location,
reg_source = "LM-SOFTWARE-Microsoft-Windows-CurrentVersion-Uninstall"
});
}
}
For Example I am not seeing Node.js in my records but it is there in My Registry.
Registry
Data from my Code
I tried elevating permissions using the following value in app.manifest:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
but still no help.
I Also tried matching the list of all Installed Applications found by NirSoft UnintallView which is finding 108 Apps vs my code finding 186 Apps looking in all CurrentUser, LocalMachine_32 & LocalMachine_64 registry.
What am I doing wrong here. Please advice, Thanks
The Debug option on my Visual Studio was set to Any CPU when I changed to config to x64 my code was able to fetch values from correct Registry Key i.e HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall and didn't get redirected to HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall as #Charlieface and #MatthewWatson have mentioned in the comment.

Don't run specified Windows applications using c#

I want to block access to certain apps on my computer. I used the gpedit.msc tool on the computer in the category: dont run specific windows application.
I am now looking for a .netcore C # algorithm that can automatically block an app in gpedit.msc
i use this code:
public static class GPAwareHelper
{
private const String REG_PATH =
"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
public static Object GetGPOverride(
String keyName, Object configValue)
{
Object keyValue = null;
RegistryKey demoKey = null;
//if (isHKLM)
// // open named key in HKEY_LOCAL_MACHINE section
// demoKey = Registry.LocalMachine.OpenSubKey(REG_PATH);
//else
// // open named key in HKEY_CURRENT_USER section
demoKey = Registry.CurrentUser.OpenSubKey(REG_PATH);
if (demoKey != null)
{
// get the specified value from this key
keyValue = demoKey.GetValue(keyName);
demoKey.Close();
// check that a value was found and, if not, return `enter code here`
// the value provided in method parameters
if (keyValue != null)
{
return keyValue;
}
else
return configValue;
}
else
{
// key not found, so return value provided
// in method parameters
return configValue;
}
}
Group Policies are registry entries. Just write those registry entries with .netcore.
You can block certain apps by adding keys in
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies
Here's a good introduction.
To write registry entries with dotnet core you have to add the package Microsoft.Win32.Registry
dotnet add package Microsoft.Win32.Registry

Registry Key Mapping

I am building an application in which I need to be able to gather information from the user's local Registry, and then utilize that to perform various tasks. I know where the certain registry key is located, but I can't seem to figure out how to properly extract the data. Here is the one I am trying to extract:
My ideal event would happen as follows: the utility searches for the registry value, determines it and stores it (in a var or something), then a button is displayed to the user to proceed to the next screen (I'm using WinForms). I have already set the button as "invisible" beforehand. See the attached code.
using (RegistryKey key = Registry.LocalMachine.OpenSubKey("HKEY_LOCAL_MACHINE\Software\Wow6432Node\DovetailGames\FSX\10.0"))
{
if (key != null)
{
Object o = key.GetValue("Install_Path");
if (o != null)
{
sc3op2.Visible = true; //Button is "sc3op2"
}
}
}
I guess my main problem is the formatting of the code to extract these values. Any help would be appreciated. Thanks.
Your answer might be here. Apparently, it has something to do with the virtualization of the application settings for 32 and 64-bit platforms. See the updated section If it returns null, set your build architecture to Any CPU. On my 64-bit platform, I am getting null when built using x86 or Any CPU build configuration. But it is returning the value when built using x64.
const string keyName = #"Software\Wow6432Node\DovetailGames\FSX";
var o = Registry.LocalMachine.OpenSubKey(keyName, false);
var value = o?.GetValue("Install_Path", "-");
Console.WriteLine(value);
First you need to remove HKEY_LOCAL_MACHINE.
You need to use # before the string.
take a look Screenshot
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Apple Inc.\Apple Application Support"))
{
if (key != null)
{
Object o = key.GetValue("Installdir");
if (o != null)
{
// do something
}
}
}

Not able to get Application startup path on click on setup.exe

I am publishing a Windows project and on click on form I am installing another setup to install.
I am not getting the current Application Startup Path on clickevent on button.
On debug and Release it is showing the right path but after publishing it is giving
C:\Users\username\AppData\Local\Apps\2.0 path
Already I have used :
Application.StartupPath
Application.Executablepath
Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location))
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase))
Path.Combine(Directory.GetCurrentDirectory())
But of no use it always show
C:\Users\username\AppData\Local\Apps\2.0 path
You are getting that path because it's the one used by ClickOnce. ClickOnce applications are installed under the profile of the user who installed them.
Edit :
Method 1:
Here's a way to get the path where your application was installed from (works only if your application was installed) (parts of this were written by #codeConcussion) :
// productName is name you assigned to your app in the
// Project properties -> Publish -> Publish Settings
public static string GetInstalledFromDir(string productName)
{
using (var key = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Uninstall"))
{
if (key != null)
{
var appKey = key.GetSubKeyNames().FirstOrDefault(x => GetValue(key, x, "DisplayName") == productName);
return appKey == null ? null : GetValue(key, appKey, "UrlUpdateInfo");
}
}
return null;
}
private static string GetValue(RegistryKey key, string app, string value)
{
using (var subKey = key.OpenSubKey(app))
{
if (subKey == null || !subKey.GetValueNames().Contains(value))
{
return null;
}
return subKey.GetValue(value).ToString();
}
}
Here's how to use it :
Uri uri = new Uri(GetInstalledFromDir("ProductName"));
MessageBox.Show(Path.GetDirectoryName(HttpUtility.UrlDecode(uri.AbsolutePath)));
Method 2 :
You can also try
System.Deployment.Application.ApplicationDeployment.CurrentDeployment.ActivationUri
But I think this one works only if your app was installed from the internet
try this:
Process.GetCurrentProcess().MainModule.FileName
BTW, is it ClickOnce deployment? If so then the directory you are getting looks about right.

creating notify icon in system tray and adding shortcut to startup using .net setup creation wizard

I have searched a lot but still not able to find the right solution.
I want to create a setup using .net setup wizard and add 2 checkbox in the setup wizard.
1st checkbox will ask user to "add program in startup". If it is checked then it will add software to startup.
2nd checkbox will ask for "create system tray notify icon". If checked then it will create a notify icon in system tray. The notify icon must be displayed permanently not only when application runs).
I know it had to do with custom actions but still not able to figure it out. Please provide me some article or code for this with proper explanation.
Actually, the custom actions is the right place to do this. Here's the code I use to create two custom checkboxes during the installation process.
[RunInstaller(true)]
public class DeploymentManager : Installer{
public override void Install(IDictionary stateSaver) {
base.Install (stateSaver);
const string DESKTOP_SHORTCUT_PARAM = "DESKTOP_SHORTCUT";
const string QUICKLAUNCH_SHORTCUT_PARAM = "QUICKLAUNCH_SHORTCUT";
const string ALLUSERS_PARAM = "ALLUSERS";
// The installer will pass the ALLUSERS, DESKTOP_SHORTCUT and QUICKLAUNCH_SHORTCUT
// parameters. These have been set to the values of radio buttons and checkboxes from the
// MSI user interface.
// ALLUSERS is set according to whether the user chooses to install for all users (="1")
// or just for themselves (="").
// If the user checked the checkbox to install one of the shortcuts, then the corresponding
// parameter value is "1". If the user did not check the checkbox to install one of the
// desktop shortcut, then the corresponding parameter value is an empty string.
bool allusers = true; // Context.Parameters[ALLUSERS_PARAM] != string.Empty;
bool installDesktopShortcut = true; //Context.Parameters[DESKTOP_SHORTCUT_PARAM] != string.Empty;
bool installQuickLaunchShortcut = true;// Context.Parameters[QUICKLAUNCH_SHORTCUT_PARAM] != string.Empty;
if (installDesktopShortcut){
// If this is an All Users install then we need to install the desktop shortcut for
// all users. .Net does not give us access to the All Users Desktop special folder,
// but we can get this using the Windows Scripting Host.
string desktopFolder = null;
if (allusers){
try{
// This is in a Try block in case AllUsersDesktop is not supported
object allUsersDesktop = "AllUsersDesktop";
WshShell shell = new WshShellClass();
desktopFolder = shell.SpecialFolders.Item(ref allUsersDesktop).ToString();
}
catch {}
}
if (desktopFolder == null)
desktopFolder = Environment.GetFolderPathEnvironment.SpecialFolder.DesktopDirectory);
CreateShortcut(desktopFolder, ShortcutName, Path.Combine(TargetAssemblyFolder, TargetAssembly), ShortcutDescription, Path.Combine(TargetAssemblyFolder, "your.ico"));
}
if (installQuickLaunchShortcut){
CreateShortcut(QuickLaunchFolder, ShortcutName, ShortcutFullName, ShortcutDescription, Path.Combine(TargetAssemblyFolder, "your.ico"));
}
}
private void CreateShortcut(string folder, string name, string target, string description, string targetIcon){
string shortcutFullName = Path.Combine(folder, name + ".lnk");
try{
WshShell shell = new WshShellClass();
IWshShortcut link = (IWshShortcut)shell.CreateShortcut(shortcutFullName);
link.TargetPath = target;
link.Description = description;
FileInfo fi = new FileInfo(targetIcon);
link.IconLocation = Path.Combine(fi.Directory.FullName, fi.Name);
link.Save();
}catch (Exception ex){
MessageBox.Show(string.Format("The shortcut \"{0}\" could not be created.\n\n{1}", shortcutFullName, ex.ToString()),
"Create Shortcut", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
After you have this code, you can add the Custom Action to the installer to the Install Custom Actions area.
The notification code would be similar for the install process but needs to be added to the registry.

Categories