1) I am trying to make a simple BHO in C# like here already answered: https://stackoverflow.com/a/5740004/285594
2) But unfortunately they all tried less then IE11, where some made it work and some failed too
3) after following everything as mentioned in that answer, i also purchased official code sign but it simply does not working in IE11 Windows 7 64-bit.
You can download my prepared version of Visual studio 2013: which includes all the source code and details for IE11:
https://www.dropbox.com/s/60kg212vkjb7yud/ClassLibrary2.rar
Q. Can anyone please advise/suggest/help how can i make one hello world of this BHO?
I have also tried others sample from codeproject, but still none of them i was able to make work yet, trying since 4 weeks, i am lost, please advise what is wrong in my ClassLibrary2.rar which is not hilighting the text "browser"?
I am completely lost, please advise.
EDIT:
IEAddon.cs
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Win32;
using mshtml;
using SHDocVw;
namespace InternetExplorerExtension
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("D40C654D-7C51-4EB3-95B2-1E23905C2A2D")]
[ProgId("MyBHO.WordHighlighter")]
public class WordHighlighterBHO : IObjectWithSite, IOleCommandTarget
{
const string DefaultTextToHighlight = "browser";
IWebBrowser2 browser;
private object site;
#region Highlight Text
void OnDocumentComplete(object pDisp, ref object URL)
{
try
{
// This will prevent this method being executed more than once.
if (pDisp != this.site)
return;
var document2 = browser.Document as IHTMLDocument2;
var document3 = browser.Document as IHTMLDocument3;
var window = document2.parentWindow;
window.execScript(#"function FncAddedByAddon() { alert('Message added by addon.'); }");
Queue<IHTMLDOMNode> queue = new Queue<IHTMLDOMNode>();
foreach (IHTMLDOMNode eachChild in document3.childNodes)
queue.Enqueue(eachChild);
while (queue.Count > 0)
{
// replacing desired text with a highlighted version of it
var domNode = queue.Dequeue();
var textNode = domNode as IHTMLDOMTextNode;
if (textNode != null)
{
if (textNode.data.Contains(TextToHighlight))
{
var newText = textNode.data.Replace(TextToHighlight, "<span style='background-color: yellow; cursor: hand;' onclick='javascript:FncAddedByAddon()' title='Click to open script based alert window.'>" + TextToHighlight + "</span>");
var newNode = document2.createElement("span");
newNode.innerHTML = newText;
domNode.replaceNode((IHTMLDOMNode)newNode);
}
}
else
{
// adding children to collection
var x = (IHTMLDOMChildrenCollection)(domNode.childNodes);
foreach (IHTMLDOMNode eachChild in x)
{
if (eachChild is mshtml.IHTMLScriptElement)
continue;
if (eachChild is mshtml.IHTMLStyleElement)
continue;
queue.Enqueue(eachChild);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion
#region Load and Save Data
static string TextToHighlight = DefaultTextToHighlight;
public static string RegData = "Software\\MyIEExtension";
[DllImport("ieframe.dll")]
public static extern int IEGetWriteableHKCU(ref IntPtr phKey);
private static void SaveOptions()
{
// In IE 7,8,9,(desktop)10 tabs run in Protected Mode
// which prohibits writes to HKLM, HKCU.
// Must ask IE for "Writable" registry section pointer
// which will be something like HKU/S-1-7***/Software/AppDataLow/
// In "metro" IE 10 mode, tabs run in "Enhanced Protected Mode"
// where BHOs are not allowed to run, except in edge cases.
// see http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx
IntPtr phKey = new IntPtr();
var answer = IEGetWriteableHKCU(ref phKey);
RegistryKey writeable_registry = RegistryKey.FromHandle(
new Microsoft.Win32.SafeHandles.SafeRegistryHandle(phKey, true)
);
RegistryKey registryKey = writeable_registry.OpenSubKey(RegData, true);
if (registryKey == null)
registryKey = writeable_registry.CreateSubKey(RegData);
registryKey.SetValue("Data", TextToHighlight);
writeable_registry.Close();
}
private static void LoadOptions()
{
// In IE 7,8,9,(desktop)10 tabs run in Protected Mode
// which prohibits writes to HKLM, HKCU.
// Must ask IE for "Writable" registry section pointer
// which will be something like HKU/S-1-7***/Software/AppDataLow/
// In "metro" IE 10 mode, tabs run in "Enhanced Protected Mode"
// where BHOs are not allowed to run, except in edge cases.
// see http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx
IntPtr phKey = new IntPtr();
var answer = IEGetWriteableHKCU(ref phKey);
RegistryKey writeable_registry = RegistryKey.FromHandle(
new Microsoft.Win32.SafeHandles.SafeRegistryHandle(phKey, true)
);
RegistryKey registryKey = writeable_registry.OpenSubKey(RegData, true);
if (registryKey == null)
registryKey = writeable_registry.CreateSubKey(RegData);
registryKey.SetValue("Data", TextToHighlight);
if (registryKey == null)
{
TextToHighlight = DefaultTextToHighlight;
}
else
{
TextToHighlight = (string)registryKey.GetValue("Data");
}
writeable_registry.Close();
}
#endregion
[Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
[InterfaceType(1)]
public interface IServiceProvider
{
int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject);
}
#region Implementation of IObjectWithSite
int IObjectWithSite.SetSite(object site)
{
this.site = site;
if (site != null)
{
LoadOptions();
var serviceProv = (IServiceProvider)this.site;
var guidIWebBrowserApp = Marshal.GenerateGuidForType(typeof(IWebBrowserApp)); // new Guid("0002DF05-0000-0000-C000-000000000046");
var guidIWebBrowser2 = Marshal.GenerateGuidForType(typeof(IWebBrowser2)); // new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E");
IntPtr intPtr;
serviceProv.QueryService(ref guidIWebBrowserApp, ref guidIWebBrowser2, out intPtr);
browser = (IWebBrowser2)Marshal.GetObjectForIUnknown(intPtr);
((DWebBrowserEvents2_Event)browser).DocumentComplete +=
new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
}
else
{
((DWebBrowserEvents2_Event)browser).DocumentComplete -=
new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
browser = null;
}
return 0;
}
int IObjectWithSite.GetSite(ref Guid guid, out IntPtr ppvSite)
{
IntPtr punk = Marshal.GetIUnknownForObject(browser);
int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
Marshal.Release(punk);
return hr;
}
#endregion
#region Implementation of IOleCommandTarget
int IOleCommandTarget.QueryStatus(IntPtr pguidCmdGroup, uint cCmds, ref OLECMD prgCmds, IntPtr pCmdText)
{
return 0;
}
int IOleCommandTarget.Exec(IntPtr pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
{
try
{
// Accessing the document from the command-bar.
var document = browser.Document as IHTMLDocument2;
var window = document.parentWindow;
var result = window.execScript(#"alert('You will now be allowed to configure the text to highlight...');");
var form = new HighlighterOptionsForm();
form.InputText = TextToHighlight;
if (form.ShowDialog() != DialogResult.Cancel)
{
TextToHighlight = form.InputText;
SaveOptions();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return 0;
}
#endregion
#region Registering with regasm
public static string RegBHO = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";
public static string RegCmd = "Software\\Microsoft\\Internet Explorer\\Extensions";
[ComRegisterFunction]
public static void RegisterBHO(Type type)
{
string guid = type.GUID.ToString("B");
// BHO
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegBHO, true);
if (registryKey == null)
registryKey = Registry.LocalMachine.CreateSubKey(RegBHO);
RegistryKey key = registryKey.OpenSubKey(guid);
if (key == null)
key = registryKey.CreateSubKey(guid);
key.SetValue("Alright", 1);
registryKey.Close();
key.Close();
}
// Command
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegCmd, true);
if (registryKey == null)
registryKey = Registry.LocalMachine.CreateSubKey(RegCmd);
RegistryKey key = registryKey.OpenSubKey(guid);
if (key == null)
key = registryKey.CreateSubKey(guid);
key.SetValue("ButtonText", "Highlighter options");
key.SetValue("CLSID", "{1FBA04EE-3024-11d2-8F1F-0000F87ABD16}");
key.SetValue("ClsidExtension", guid);
key.SetValue("Icon", "");
key.SetValue("HotIcon", "");
key.SetValue("Default Visible", "Yes");
key.SetValue("MenuText", "&Highlighter options");
key.SetValue("ToolTip", "Highlighter options");
//key.SetValue("KeyPath", "no");
registryKey.Close();
key.Close();
}
}
[ComUnregisterFunction]
public static void UnregisterBHO(Type type)
{
string guid = type.GUID.ToString("B");
// BHO
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegBHO, true);
if (registryKey != null)
registryKey.DeleteSubKey(guid, false);
}
// Command
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegCmd, true);
if (registryKey != null)
registryKey.DeleteSubKey(guid, false);
}
}
#endregion
}
}
i'm trying to do the same - and i've just noticed that in build log there was an error
Failure adding assembly to the cache: Attempt to install an assembly
without a strong name
so i've added *.snk and highlighting worked (using ie11 to, x64), but 'highlight options' menu item isn't working
IEExtension example
although your IE11 runs in a 64bit Windows, but the default IE instance is 32bit version. The enhanced protection mode need to be enabled so that IE11 will run in 64bit mode.
Another trick is for 32bit IE, you have to register 32bit extension, and vice versa for 64bit. My suggestion is as follows:
make sure your IE11 mode is 32bit or 64bit
register only 32bit or 64bit extension, if both registered, the extension can NOT work either. You have to double check your registry to delete the one un-necessary
I warmly suggest you this post of Pavel Zolnikov published in 2002!
http://www.codeproject.com/Articles/2219/Extending-Explorer-with-Band-Objects-using-NET-and
It is based on the use of Band objects and is compiled using .Net 2.0.
As you will read on the post comments, it works perfectly well for IE 11 and on Windows 7 and Windows 10.
Tutorial source code is provided and opens and compiles well with Visual Studio 2013.
Enjoy!
Related
This code below checking if MySQL is installed works perfectly.
public bool MySql()
{
try
{
using (var key = Registry.CurrentUser.OpenSubKey("Software\\MySQL AB\\MySQL Server 5.6"))
{
var keyObject = key?.GetValue("installed");
var keyToString = keyObject?.ToString();
if (keyToString == "1")
return true;
}
return false;
}
catch (Exception)
{
return false;
}
}
However using the exact same code I try to see if OpenSSL is installed.
public bool OpenSsl()
{
try
{
using (var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1"))
{
var keyObject = key?.GetValue("NoModify");
var keyToString = keyObject?.ToString();
if (keyToString == "1")
return true;
}
return false;
}
catch (Exception)
{
return false;
}
}
Setting breakpoints in the code revealed that key is returning null. I'm not sure why. Yes the path is correct.
A 32-bit application on a 64-bit OS is routed to HKLM\Software\Wow6432Node. To read the 64-bit version of the key, we need to use the RegistryView
C# 4.0 code sample
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);
}
If your using .NET 3.5 or below p/invoke is the only solution.
http://www.rhyous.com/2011/01/24/how-read-the-64-bit-registry-from-a-32-bit-application-or-vice-versa/
During my installation (I'm using Clickonce) I'd like to create registry my project is with .Net 3.5 currently.
My application is 32 bits and it can be installed in a 32 or 64 bits machine, I have some issue while creating the registry.
In the function VerifyReg I create the registry if they didn't exist (My program is the name of the parent branch that should be under Software depending in 32 or 64 bits machine.
My problem is in the function : CreateMoreRegistryKeys in
RegistryKey RegKeyWow64 = RegKeyMain.OpenSubKey(#"SOFTWARE\Wow6432Node", true);
I have an error writing into the registry even if I'm an Administrator of the machine
This is the function did I miss something during the creation and the reading ?
public void VerifyReg()
{
string keyName = #"SOFTWARE\Myprogram";
RegistryKey RegKeyMain = Registry.LocalMachine;
RegistryKey skSub = null;
skSub = RegKeyMain.OpenSubKey(keyName);
if (skSub == null)
{
skSub = RegKeyMain.CreateSubKey(keyName);
}
CreateMoreRegistryKeys();
}
public void CreateMoreRegistryKeys()
{
bool bIs64bits = Environment.Is64BitOperatingSystem;
string keyName = #"SOFTWARE\Myprogram\Folder";
RegistryKey RegKeyMain = Registry.LocalMachine;
if (bIs64bits)
{
keyName = #"Myprogram\Folder";
RegistryKey RegKeyWow64 = RegKeyMain.OpenSubKey(#"SOFTWARE\Wow6432Node", true);
CreateRegKeyFor64or32Bits(RegKeyWow64, keyName);
}
else
{
CreateRegKeyFor64or32Bits(RegKeyMain, keyName);
}
}
public void CreateRegKeyFor64or32Bits(RegistryKey RegKeyMain, string keyName)
{
RegistryKey skSubWy = RegKeyMain.CreateSubKey(keyName, RegistryKeyPermissionCheck.ReadWriteSubTree);
if (skSubWy != null)
{
..Do something
}
}
I am trying to retrieve data from a particular installed application, such as the Installation Folder, Uninstall String, Version number, etc. When I run the following code, I get the Install Folder but it returns four rows of question marks for the UninstallString value. Any ideas?
public static void FindInstalled(string AppName)
{
StringBuilder sbProductCode = new StringBuilder(39);
int iIdx = 0;
while (
0 == MsiEnumProducts(iIdx++, sbProductCode))
{
Int32 productNameLen = 512;
StringBuilder sbProductName = new StringBuilder(productNameLen);
MsiGetProductInfo(sbProductCode.ToString(), "ProductName", sbProductName, ref productNameLen);
if (sbProductName.ToString().Contains(AppName))
{
Int32 installDirLen = 1024;
StringBuilder sbInstallDir = new StringBuilder(installDirLen);
MsiGetProductInfo(sbProductCode.ToString(), "InstallLocation", sbInstallDir, ref installDirLen);
Console.Writeline("Install Directory - {0}",sbInstallDir.ToString());
MsiGetProductInfo(sbProductCode.ToString(), "UninstallString", sbInstallDir, ref installDirLen);
Console.Writeline("Uninstall String - {0}", sbInstallDir.ToString());
}
}
}
UninstallString isn't a valid property. See http://msdn.microsoft.com/en-us/library/aa370130(VS.85).aspx for a list of valid properties.
If you open the Windows Installer header file ("msi.h") and search for the text "UninstallString", you won't find it. Also if you look in the property reference at http://msdn.microsoft.com/en-us/library/aa370905(VS.85).aspx and search that page for "UninstallString", you won't find it either.
My advice would be to read the properties out of the registry instead. See http://msdn.microsoft.com/en-us/library/aa372105(VS.85).aspx for details. You can get the details you need from that.
How about something like this:
public static void FindInstalled(AppName)
{
RegistryKey myRegKey = Registry.LocalMachine;
myRegKey = myRegKey.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall");
String[] subkeyNames = myRegKey.GetSubKeyNames();
foreach (String s in subkeyNames)
{
RegistryKey UninstallKey = Registry.LocalMachine;
UninstallKey = UninstallKey.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + s);
Object oValue = UninstallKey.GetValue("DisplayName");
if (oValue != null)
{
if (oValue.ToString() == AppName)
{
oValue = UninstallKey.GetValue("UninstallString");
Console.Writeline("Uninstall URL - {0}", oValue.ToString());
break;
}
}
}
}
I have a C# program where I have to get the product code of an installed msi. I have only the msi name as the input. Can this be done programmatically?
Do the answers to this question help? They want to get the product name, but maybe it works for the product code, too?
EDIT
If you do not have the MSI file itself to access the database (as suggested by the above link to the other question), you may try to search the following registry path for the name of your MSI file:
HKEY_CLASSES_ROOT\Installer\Products\*\SourceList
There are many entries under the Products branch. Each of them is a product key. Every branch should contain the SourceList node, which in turn should contain the value PackageName. That value holds the name of the MSI file.
So what I'd do is:
for each key in Products
{
open SourceList subkey
read PackageName value
if name equals my msi file name
{
return key-name formatted as GUID
}
}
This is the code I used to get the UninstallString of any MSI.
private string GetUninstallString(string msiName)
{
Utility.WriteLog("Entered GetUninstallString(msiName) - Parameters: msiName = " + msiName);
string uninstallString = string.Empty;
try
{
string path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products";
RegistryKey key = Registry.LocalMachine.OpenSubKey(path);
foreach (string tempKeyName in key.GetSubKeyNames())
{
RegistryKey tempKey = key.OpenSubKey(tempKeyName + "\\InstallProperties");
if (tempKey != null)
{
if (string.Equals(Convert.ToString(tempKey.GetValue("DisplayName")), msiName, StringComparison.CurrentCultureIgnoreCase))
{
uninstallString = Convert.ToString(tempKey.GetValue("UninstallString"));
uninstallString = uninstallString.Replace("/I", "/X");
uninstallString = uninstallString.Replace("MsiExec.exe", "").Trim();
uninstallString += " /quiet /qn";
break;
}
}
}
return uninstallString;
}
catch (Exception ex)
{
throw new ApplicationException(ex.Message);
}
}
This will give a result like this:
MsiExec.exe /I{6BB09011-69E1-472F-ACAD-FA0E7DA3E2CE}
From this string, you can take the substring within the braces {}, which will be 6BB09011-69E1-472F-ACAD-FA0E7DA3E2CE. I hope this might be the product code.
There is most fast and simply way - to use WMI with conditional query string.
public string GetProductCode(string productName)
{
string query = string.Format("select * from Win32_Product where Name='{0}'", productName);
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
{
foreach (ManagementObject product in searcher.Get())
return product["IdentifyingNumber"].ToString();
}
return null;
}
This code obtains the product code directly from an MSI file. So this allows reading the code without installing the file.
class MsiHandle : SafeHandleMinusOneIsInvalid
{
public MsiHandle()
: base(true)
{ }
protected override bool ReleaseHandle()
{
return NativeMethods.MsiCloseHandle(handle) == 0;
}
}
class NativeMethods
{
const string MsiDll = "Msi.dll";
[DllImport(MsiDll, CharSet = CharSet.Unicode, ExactSpelling = true)]
public extern static uint MsiOpenPackageW(string szPackagePath, out MsiHandle product);
[DllImport(MsiDll, ExactSpelling=true)]
public extern static uint MsiCloseHandle(IntPtr hAny);
[DllImport(MsiDll, CharSet = CharSet.Unicode, ExactSpelling = true)]
static extern uint MsiGetProductPropertyW(MsiHandle hProduct, string szProperty, StringBuilder value, ref int length);
[DllImport(MsiDll, ExactSpelling = true)]
public static extern int MsiSetInternalUI(int value, IntPtr hwnd);
public static uint MsiGetProductProperty(MsiHandle hProduct, string szProperty, out string value)
{
StringBuilder sb = new StringBuilder(1024);
int length = sb.Capacity;
uint err;
value = null;
if(0 == (err = MsiGetProductPropertyW(hProduct, szProperty, sb, ref length)))
{
sb.Length = length;
value = sb.ToString();
return 0;
}
return err;
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static int Main(string[] args)
{
string msiFile = args[0];
NativeMethods.MsiSetInternalUI(2, IntPtr.Zero); // Hide all UI. Without this you get a MSI dialog
MsiHandle msi;
uint err;
if (0 != (err = NativeMethods.MsiOpenPackageW(args[0], out msi)))
{
Console.Error.WriteLine("Can't open MSI, error {0}", err);
return 1;
}
// Strings available in all MSIs
string productCode;
using (msi)
{
if (0 != NativeMethods.MsiGetProductProperty(msi, "ProductCode", out productCode))
throw new InvalidOperationException("Can't obtain product code");
Console.WriteLine(productCode);
return 0;
}
}
}
Full example in Subversion on http://ankhsvn.open.collab.net/svn/ankhsvn/trunk/src/tools/Ankh.Chocolatey/
Use username 'guest' and no password.
private static bool GetUninstallString(string ProductName)
{
try
{
RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
var key = localKey.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") ??
localKey.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(ProductName));
}
catch
{
// Log message
return false;
}
}
This is very usefull for search string by productname
What RegKey can you get the default browser application's path from?
Best way to get to it from C#/.NET?
Here's the key you want:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\http\shell\open\command
And here's a quick registry tutorial for C#, if you need it.
Edit:
For per-user settings, use this key:
HKEY_CLASSES_ROOT\http\shell\open\command
(HKCR has both machine and user settings, user takes priority).
Note that this might not work on Vista. For more info, see here.
for windows 7 default browser path save in following registry key
HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\ Associations\UrlAssociations\http
by using c# you can get it as follows -
RegistryKey regkey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\shell\\Associations\\UrlAssociations\\http\\UserChoice", false);
string browser = regkey.GetValue("Progid").ToString();
Based on your answers I wrote this sample code that should do what you want (not tested)
public static string GetDefaultBrowserPath()
{
string defaultBrowserPath = null;
RegistryKey regkey;
// Check if we are on Vista or Higher
OperatingSystem OS = Environment.OSVersion;
if ((OS.Platform == PlatformID.Win32NT) && (OS.Version.Major >= 6))
{
regkey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\shell\\Associations\\UrlAssociations\\http\\UserChoice", false);
if (regkey != null)
{
defaultBrowserPath = regkey.GetValue("Progid").ToString();
}
else
{
regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Classes\\IE.HTTP\\shell\\open\\command", false);
defaultBrowserPath = regkey.GetValue("").ToString();
}
}
else
{
regkey = Registry.ClassesRoot.OpenSubKey("http\\shell\\open\\command", false);
defaultBrowserPath = regkey.GetValue("").ToString();
}
return defaultBrowserPath;
}
I just made a function for this:
public void launchBrowser(string url)
{
string browserName = "iexplore.exe";
using (RegistryKey userChoiceKey = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice"))
{
if (userChoiceKey != null)
{
object progIdValue = userChoiceKey.GetValue("Progid");
if (progIdValue != null)
{
if(progIdValue.ToString().ToLower().Contains("chrome"))
browserName = "chrome.exe";
else if(progIdValue.ToString().ToLower().Contains("firefox"))
browserName = "firefox.exe";
else if (progIdValue.ToString().ToLower().Contains("safari"))
browserName = "safari.exe";
else if (progIdValue.ToString().ToLower().Contains("opera"))
browserName = "opera.exe";
}
}
}
Process.Start(new ProcessStartInfo(browserName, url));
}