From eb1feafc34d1ccd305e3e894176b3b1d1ea65d9b Mon Sep 17 00:00:00 2001 From: Kody Brown Date: Mon, 1 Feb 2016 16:03:49 -0700 Subject: [PATCH 1/9] Added support for including additional arguments to each browser in the [browsers] section. Added support for using the `{url}` keyword in the [browsers] section of the INI file. Added support for full regular expressions, indicated when the key is enclosed in /'s (in the [urls] section). When using full regular expressions, the domain and path are used in the comparison; not just the domain. Updated BrowserSelector.ini with a couple examples. --- DanTup.BrowserSelector/BrowserSelector.ini | 21 +++++-- DanTup.BrowserSelector/Program.cs | 70 +++++++++++++++------- 2 files changed, 66 insertions(+), 25 deletions(-) diff --git a/DanTup.BrowserSelector/BrowserSelector.ini b/DanTup.BrowserSelector/BrowserSelector.ini index 0f81a25..7ed2adb 100644 --- a/DanTup.BrowserSelector/BrowserSelector.ini +++ b/DanTup.BrowserSelector/BrowserSelector.ini @@ -1,15 +1,26 @@ ; Default browser is first in list -; Micrsoft Edge is a UWP app and requires no path [browsers] chrome = C:\Program Files (x86)\Google\Chrome\Application\chrome.exe +chrome_def = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Default" +chrome_prof8 = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Profile 8" ff = C:\Program Files (x86)\Mozilla Firefox\firefox.exe -edge = +ffd = C:\Program Files\Firefox Developer Edition\firefox.exe +edge = microsoft-edge:{url} ie = iexplore.exe ; Url preferences. ; Only * is treated as a special character (wildcard). -; Matches are domain-only. Protocols and paths are ignored. +; Matches are domain-only. Protocols and paths are ignored (except when specifying a regex, obviously). ; Use "*.blah.com" for subdomains, not "*blah.com" as that would also match "abcblah.com". [urls] -microsoft.com = ie -*.microsoft.com = ie +microsoft.com = edge +*.microsoft.com = edge + +customer.realdomain = chrome_prof8 +customer.local = chrome_prof8 + +; if the key is wrapped in /'s, it is treated as a regex. +/sites\.google\.com/a/customer.realdomain\.com/ = chrome_prof8 + +google.com = chrome_def +*.google.com = chrome_def diff --git a/DanTup.BrowserSelector/Program.cs b/DanTup.BrowserSelector/Program.cs index 5754eb9..1e5fcd2 100644 --- a/DanTup.BrowserSelector/Program.cs +++ b/DanTup.BrowserSelector/Program.cs @@ -10,18 +10,13 @@ namespace DanTup.BrowserSelector { class Program { - static readonly Dictionary SpecialCommands = new Dictionary - { - {"edge", "microsoft-edge:{0}"} - }; - - static void Main(string[] args) + static void Main( string[] args ) { if (args == null || args.Length != 1 || !HandleArg(args[0])) ShowHelpInfo(); } - static bool HandleArg(string arg) + static bool HandleArg( string arg ) { if (string.Equals(arg, "--register", StringComparison.OrdinalIgnoreCase)) { @@ -57,7 +52,7 @@ Launch example.org Once you have registered the app as a browser, you should use visit ""Set Default Browser"" in Windows to set this app as the default browser."); } - static void EnsureAdmin(string arg) + static void EnsureAdmin( string arg ) { WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); if (!principal.IsInRole(WindowsBuiltInRole.Administrator)) @@ -73,29 +68,64 @@ static void EnsureAdmin(string arg) } - static void LaunchBrowser(string url) + static void LaunchBrowser( string url ) { try { var urlPreferences = ConfigReader.GetUrlPreferences(); + string _url = url; + Uri uri = new Uri(_url); + + string pattern; + string domain = "", urlPattern; foreach (var preference in urlPreferences) { - // Escape the input for regex; the only special character we support is a * - var regex = Regex.Escape(preference.UrlPattern); - // Unescape * as a wildcard. - var pattern = string.Format("^{0}$", regex.Replace("\\*", ".*")); + urlPattern = preference.UrlPattern; - // We're only checking the domain. - var domain = new Uri(url).Authority; + if (urlPattern.StartsWith("/") && urlPattern.EndsWith("/")) + { + // The domain from the INI file is a regex.. + domain = uri.Authority + uri.AbsolutePath; + pattern = urlPattern.Substring(1, urlPattern.Length - 2); + } + else + { + // We're only checking the domain. + domain = uri.Authority; + + // Escape the input for regex; the only special character we support is a * + var regex = Regex.Escape(urlPattern); + // Unescape * as a wildcard. + pattern = string.Format("^{0}$", regex.Replace("\\*", ".*")); + } if (Regex.IsMatch(domain, pattern)) { - if (SpecialCommands.ContainsKey(preference.Browser.Name)) - Process.Start(string.Format(SpecialCommands[preference.Browser.Name], url)); - else - Process.Start(preference.Browser.Location, url); - return; + string loc = preference.Browser.Location; + if (loc.IndexOf("{url}") > -1) + { + loc = loc.Replace("{url}", _url); + _url = ""; + } + if (loc.StartsWith("\"") && loc.IndexOf('"', 2) > -1) + { + // Assume the quoted item is the executable, while everything + // after (the second quote), is part of the command-line arguments. + loc = loc.Substring(1); + int pos = loc.IndexOf('"'); + string args = loc.Substring(pos + 1).Trim(); + loc = loc.Substring(0, pos).Trim(); + Process.Start(loc, args + " " + _url); + } + else + { + // The browser specified in the INI file is a single executable + // without any other arguments. + // (normal/original behavior) + Process.Start(loc, _url); + } + return; } } From b656e5ff971c15fe55bc94264abcf51e6dc47a2f Mon Sep 17 00:00:00 2001 From: Kody Brown Date: Mon, 1 Feb 2016 16:39:33 -0700 Subject: [PATCH 2/9] Updated README.md and sample BrowserSelector.ini files. --- DanTup.BrowserSelector/BrowserSelector.ini | 22 +++++----- README.md | 48 +++++++++++++++++++--- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/DanTup.BrowserSelector/BrowserSelector.ini b/DanTup.BrowserSelector/BrowserSelector.ini index 7ed2adb..d70f47a 100644 --- a/DanTup.BrowserSelector/BrowserSelector.ini +++ b/DanTup.BrowserSelector/BrowserSelector.ini @@ -1,26 +1,26 @@ ; Default browser is first in list +; Use `{url}` to specify UWP app browser details [browsers] chrome = C:\Program Files (x86)\Google\Chrome\Application\chrome.exe -chrome_def = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Default" -chrome_prof8 = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Profile 8" ff = C:\Program Files (x86)\Mozilla Firefox\firefox.exe -ffd = C:\Program Files\Firefox Developer Edition\firefox.exe edge = microsoft-edge:{url} ie = iexplore.exe +chrome_prof8 = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Profile 8" ; Url preferences. ; Only * is treated as a special character (wildcard). -; Matches are domain-only. Protocols and paths are ignored (except when specifying a regex, obviously). +; Matches are domain-only. Protocols and paths are ignored. ; Use "*.blah.com" for subdomains, not "*blah.com" as that would also match "abcblah.com". [urls] -microsoft.com = edge -*.microsoft.com = edge +microsoft.com = ie +*.microsoft.com = ie -customer.realdomain = chrome_prof8 -customer.local = chrome_prof8 +; Use my project-based Chrome profile +myproject.live = chrome_prof8 +myproject.local = chrome_prof8 ; if the key is wrapped in /'s, it is treated as a regex. -/sites\.google\.com/a/customer.realdomain\.com/ = chrome_prof8 +/sites\.google\.com/a/myproject.live\.com/ = chrome_prof8 -google.com = chrome_def -*.google.com = chrome_def +google.com = chrome +visualstudio.com = edge \ No newline at end of file diff --git a/README.md b/README.md index dee4879..4023945 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,10 @@ Small utility to launch a different browser depending on the domain of the url being launched. -### Only tested on Windows 8.1 so far :) +So far, it has been tested on the following: + +* Windows 8.1 +* Windows 10 Pro ## Setting Up @@ -17,12 +20,13 @@ Small utility to launch a different browser depending on the domain of the url b Config is a poor mans INI file: ; Default browser is first in list - ; Micrsoft Edge is a UWP app and requires no path + ; Use `{url}` to specify UWP app browser details [browsers] chrome = C:\Program Files (x86)\Google\Chrome\Application\chrome.exe ff = C:\Program Files (x86)\Mozilla Firefox\firefox.exe - edge = + edge = microsoft-edge:{url} ie = iexplore.exe + chrome_prof8 = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Profile 8" ; Url preferences. ; Only * is treated as a special character (wildcard). @@ -31,12 +35,44 @@ Config is a poor mans INI file: [urls] microsoft.com = ie *.microsoft.com = ie + + ; Use my project-based Chrome profile + myproject.live = chrome_prof8 + myproject.local = chrome_prof8 + + ; if the key is wrapped in /'s, it is treated as a regex. + /sites\.google\.com/a/myproject.live\.com/ = chrome_prof8 + google.com = chrome visualstudio.com = edge -Notes: +### Browsers + +- Browser exes must be exact paths to the browser executable. +- Arguments are optional. However, if you provide arguments the exe _must_ be enclosed in quotes. If there are no arguments, then the exe paths do not need to be quoted. + +Special cases: + +- For special exe paths, you can append the `{url}` flag to its path. This is required when specifying UWP app's such as Microsoft Edge (see example above). This allows better control over the browser command-line arguments. +- By default, the url used as the first argument to the exe. If the `{url}` is specified, it will not be added to the arguments. + +### Urls + +There are two ways to specify an Url. You can use simple wildcards or full regular expressions. + +#### Simple wildcards: -- Browser paths must be exact paths to exes with no arguments (or in `PATH`). Values do not need to be quoted. Microsoft Edge is a UWP app which cannot be started like other browsers. The path can thus remain empty. -- Only * is treated as a special character in URL patterns, and matches any characters. + microsoft.com = ie + *.microsoft.com = ie + +- Only `*` is treated as a special character in URL patterns, and matches any characters (equivalent to the `.*` regex syntax). - Only the domain part (or IP address) of a URL is checked. - There is no implied wildcard at the start or end, so you must include these if you need them, but be aware that "microsoft.*" will not only match "microsoft.com" and "microsoft.co.uk" but also "microsoft.somethingelse.com". + +#### Full regular expressions: + + /sites\.google\.com/a/myproject.live\.com/ = chrome_prof8 + +- Full regular expressions are specified by wrapping it in /'s. +- The domain _and_ path are used in the Url comparison. +- The regular expression syntax is based on the Microsoft .NET implementation. From 58e4049c2dc812dfbfb9084fa778bdb6fc088e7f Mon Sep 17 00:00:00 2001 From: Kody Brown Date: Mon, 1 Feb 2016 16:39:33 -0700 Subject: [PATCH 3/9] Updated README.md and sample BrowserSelector.ini files. --- README.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4023945..8e4091b 100644 --- a/README.md +++ b/README.md @@ -48,19 +48,26 @@ Config is a poor mans INI file: ### Browsers + chrome = C:\Program Files (x86)\Google\Chrome\Application\chrome.exe + chrome_prof8 = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Profile 8" + - Browser exes must be exact paths to the browser executable. -- Arguments are optional. However, if you provide arguments the exe _must_ be enclosed in quotes. If there are no arguments, then the exe paths do not need to be quoted. +- Arguments are optional. However, if you provide arguments the exe _must_ be enclosed in quotes. +- If there are no arguments, then the exe paths do not need to be quoted. -Special cases: +**Special cases:** + + edge = microsoft-edge:{url} -- For special exe paths, you can append the `{url}` flag to its path. This is required when specifying UWP app's such as Microsoft Edge (see example above). This allows better control over the browser command-line arguments. -- By default, the url used as the first argument to the exe. If the `{url}` is specified, it will not be added to the arguments. +- For special browsers, you can include the `{url}` flag. This allows better control over the browser command-line arguments. +- This is required when specifying UWP app's such as Microsoft Edge. +- By default, the url is used as an argument when launching the exe. If the `{url}` flag is specified, it will not be added to the arguments. (In other words, it _won't_ be added twice..) ### Urls There are two ways to specify an Url. You can use simple wildcards or full regular expressions. -#### Simple wildcards: +**Simple wildcards:** microsoft.com = ie *.microsoft.com = ie @@ -69,7 +76,7 @@ There are two ways to specify an Url. You can use simple wildcards or full regul - Only the domain part (or IP address) of a URL is checked. - There is no implied wildcard at the start or end, so you must include these if you need them, but be aware that "microsoft.*" will not only match "microsoft.com" and "microsoft.co.uk" but also "microsoft.somethingelse.com". -#### Full regular expressions: +**Full regular expressions:** /sites\.google\.com/a/myproject.live\.com/ = chrome_prof8 From e6b5f376329aafcb86a43db9e69f0318f104957d Mon Sep 17 00:00:00 2001 From: Kody Brown Date: Tue, 2 Feb 2016 09:36:52 -0700 Subject: [PATCH 4/9] Added support for opening (associating with) .url and .webloc (osx) files. BrowserSelector will get the url from those files and open that address using the normal rules. --- DanTup.BrowserSelector/Program.cs | 324 +++++++++++++++++++----------- 1 file changed, 205 insertions(+), 119 deletions(-) diff --git a/DanTup.BrowserSelector/Program.cs b/DanTup.BrowserSelector/Program.cs index 1e5fcd2..5de6250 100644 --- a/DanTup.BrowserSelector/Program.cs +++ b/DanTup.BrowserSelector/Program.cs @@ -1,44 +1,50 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Reflection; using System.Security.Principal; using System.Text.RegularExpressions; using System.Windows.Forms; +using System.Xml; namespace DanTup.BrowserSelector { - class Program - { - static void Main( string[] args ) - { - if (args == null || args.Length != 1 || !HandleArg(args[0])) - ShowHelpInfo(); - } - - static bool HandleArg( string arg ) - { - if (string.Equals(arg, "--register", StringComparison.OrdinalIgnoreCase)) - { - EnsureAdmin(arg); - RegistrySettings.RegisterBrowser(); - } - else if (string.Equals(arg, "--unregister", StringComparison.OrdinalIgnoreCase)) - { - EnsureAdmin(arg); - RegistrySettings.UnregisterBrowser(); - } - else if (arg.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || arg.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || arg.StartsWith("ftp://", StringComparison.OrdinalIgnoreCase)) - LaunchBrowser(arg); - else - return false; - - return true; - } - - static void ShowHelpInfo() - { - MessageBox.Show(@"Usage: + class Program + { + static void Main(string[] args) + { + if (args == null || args.Length != 1 || !HandleArg(args[0])) + ShowHelpInfo(); + } + + static bool HandleArg(string arg) + { + if (string.Equals(arg, "--register", StringComparison.OrdinalIgnoreCase)) + { + EnsureAdmin(arg); + RegistrySettings.RegisterBrowser(); + } + else if (string.Equals(arg, "--unregister", StringComparison.OrdinalIgnoreCase)) + { + EnsureAdmin(arg); + RegistrySettings.UnregisterBrowser(); + } + else if (arg.EndsWith(".url", StringComparison.InvariantCultureIgnoreCase)) + LaunchUrlFile(arg); + else if (arg.EndsWith(".webloc", StringComparison.InvariantCultureIgnoreCase)) + LaunchWeblocFile(arg); + else if (arg.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || arg.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || arg.StartsWith("ftp://", StringComparison.OrdinalIgnoreCase)) + LaunchBrowser(arg); + else + return false; + + return true; + } + + static void ShowHelpInfo() + { + MessageBox.Show(@"Usage: BrowserSelector.exe --register Register as web browser @@ -49,92 +55,172 @@ Unregister as web browser BrowserSelector.exe ""http://example.org/"" Launch example.org -Once you have registered the app as a browser, you should use visit ""Set Default Browser"" in Windows to set this app as the default browser."); - } - - static void EnsureAdmin( string arg ) - { - WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); - if (!principal.IsInRole(WindowsBuiltInRole.Administrator)) - { - Process.Start(new ProcessStartInfo - { - FileName = Assembly.GetExecutingAssembly().Location, - Verb = "runas", - Arguments = arg - }); - Environment.Exit(0); - } - } - - - static void LaunchBrowser( string url ) - { - try - { - var urlPreferences = ConfigReader.GetUrlPreferences(); - string _url = url; - Uri uri = new Uri(_url); - - string pattern; - string domain = "", urlPattern; - - foreach (var preference in urlPreferences) - { - urlPattern = preference.UrlPattern; - - if (urlPattern.StartsWith("/") && urlPattern.EndsWith("/")) - { - // The domain from the INI file is a regex.. - domain = uri.Authority + uri.AbsolutePath; - pattern = urlPattern.Substring(1, urlPattern.Length - 2); - } - else - { - // We're only checking the domain. - domain = uri.Authority; - - // Escape the input for regex; the only special character we support is a * - var regex = Regex.Escape(urlPattern); - // Unescape * as a wildcard. - pattern = string.Format("^{0}$", regex.Replace("\\*", ".*")); - } - - if (Regex.IsMatch(domain, pattern)) - { - string loc = preference.Browser.Location; - if (loc.IndexOf("{url}") > -1) - { - loc = loc.Replace("{url}", _url); - _url = ""; - } - if (loc.StartsWith("\"") && loc.IndexOf('"', 2) > -1) - { - // Assume the quoted item is the executable, while everything - // after (the second quote), is part of the command-line arguments. - loc = loc.Substring(1); - int pos = loc.IndexOf('"'); - string args = loc.Substring(pos + 1).Trim(); - loc = loc.Substring(0, pos).Trim(); - Process.Start(loc, args + " " + _url); - } - else - { - // The browser specified in the INI file is a single executable - // without any other arguments. - // (normal/original behavior) - Process.Start(loc, _url); - } - return; - } - } - - MessageBox.Show(string.Format("Unable to find a suitable browser matching {0}.", url)); - } - catch (Exception ex) - { - MessageBox.Show(string.Format("Unable to launch browser, sorry :(\r\n\r\nPlease send a copy of this error to DanTup.\r\n\r\n{0}.", ex.ToString())); - } - } - } +Once you have registered the app as a browser, you should use visit ""Set Default Browser"" in Windows to set this app as the default browser.", "BrowserSelector", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + static void EnsureAdmin(string arg) + { + WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); + if (!principal.IsInRole(WindowsBuiltInRole.Administrator)) + { + Process.Start(new ProcessStartInfo + { + FileName = Assembly.GetExecutingAssembly().Location, + Verb = "runas", + Arguments = arg + }); + Environment.Exit(0); + } + } + + + static void LaunchUrlFile(string file) + { + string url = ""; + bool firstLine = true; + string[] lines; + + if (!File.Exists(file)) + { + MessageBox.Show("Could not find or do not have access to .url file.", "BrowserSelector", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + lines = File.ReadAllLines(file); + if (lines.Length < 2) + { + MessageBox.Show("Invalid .url file format.", "BrowserSelector", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + foreach (string l in lines) + { + if (firstLine) + { + if (!l.Trim().Equals("[InternetShortcut]", StringComparison.InvariantCultureIgnoreCase)) + { + MessageBox.Show("Invalid .url file format.", "BrowserSelector", MessageBoxButtons.OK, MessageBoxIcon.Error); + break; + } + firstLine = false; + } + if (l.StartsWith("URL=", StringComparison.InvariantCulture)) + { + url = l.Substring(4); + break; + } + } + + if (url.Length > 0) + { + LaunchBrowser(url); + } + } + + static void LaunchWeblocFile(string file) + { + string url = ""; + XmlDocument doc; + XmlNode node; + + if (!File.Exists(file)) + { + MessageBox.Show("Could not find or do not have access to .url file.", "BrowserSelector", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + doc = new XmlDocument(); + try + { + doc.Load(file); + } + catch (Exception) + { + MessageBox.Show("Could not read the .webloc file.", "BrowserSelector", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + node = doc.DocumentElement.SelectSingleNode("//plist/dict/string"); + if (node == null) + { + MessageBox.Show("Unknown or invalid .webloc file format.", "BrowserSelector", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + url = node.InnerText; + if (url.Length > 0) + { + LaunchBrowser(url); + } + } + + static void LaunchBrowser(string url) + { + try + { + var urlPreferences = ConfigReader.GetUrlPreferences(); + string _url = url; + Uri uri = new Uri(_url); + + string pattern; + string domain = "", urlPattern; + + foreach (var preference in urlPreferences) + { + urlPattern = preference.UrlPattern; + + if (urlPattern.StartsWith("/") && urlPattern.EndsWith("/")) + { + // The domain from the INI file is a regex.. + domain = uri.Authority + uri.AbsolutePath; + pattern = urlPattern.Substring(1, urlPattern.Length - 2); + } + else + { + // We're only checking the domain. + domain = uri.Authority; + + // Escape the input for regex; the only special character we support is a * + var regex = Regex.Escape(urlPattern); + // Unescape * as a wildcard. + pattern = string.Format("^{0}$", regex.Replace("\\*", ".*")); + } + + if (Regex.IsMatch(domain, pattern)) + { + string loc = preference.Browser.Location; + if (loc.IndexOf("{url}") > -1) + { + loc = loc.Replace("{url}", _url); + _url = ""; + } + if (loc.StartsWith("\"") && loc.IndexOf('"', 2) > -1) + { + // Assume the quoted item is the executable, while everything + // after (the second quote), is part of the command-line arguments. + loc = loc.Substring(1); + int pos = loc.IndexOf('"'); + string args = loc.Substring(pos + 1).Trim(); + loc = loc.Substring(0, pos).Trim(); + Process.Start(loc, args + " " + _url); + } + else + { + // The browser specified in the INI file is a single executable + // without any other arguments. + // (normal/original behavior) + Process.Start(loc, _url); + } + return; + } + } + + MessageBox.Show(string.Format("Unable to find a suitable browser matching {0}.", url), "BrowserSelector", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + catch (Exception ex) + { + MessageBox.Show(string.Format("Unable to launch browser, sorry :(\r\n\r\nPlease send a copy of this error to DanTup.\r\n\r\n{0}.", ex.ToString()), "BrowserSelector", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } } From 0e23f8213a310300e6c64c4cf3dc23cbe8e5e014 Mon Sep 17 00:00:00 2001 From: Kody Brown Date: Wed, 3 Feb 2016 08:42:34 -0700 Subject: [PATCH 5/9] Added an option to create a sample/default settings file, using the checked in BrowserSelector.ini file in the project (now embedded in the build). Added support for the `--wait` flag. Added support for opening multiple urls/files from the same command-line. Updated the README and usage. --- DanTup.BrowserSelector/ConfigReader.cs | 56 +- .../DanTup.BrowserSelector.csproj | 10 +- DanTup.BrowserSelector/Program.cs | 512 ++++++++++-------- README.md | 42 +- 4 files changed, 399 insertions(+), 221 deletions(-) diff --git a/DanTup.BrowserSelector/ConfigReader.cs b/DanTup.BrowserSelector/ConfigReader.cs index 841d8a1..78adb67 100644 --- a/DanTup.BrowserSelector/ConfigReader.cs +++ b/DanTup.BrowserSelector/ConfigReader.cs @@ -3,6 +3,8 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Text; +using System.Windows.Forms; namespace DanTup.BrowserSelector { @@ -11,7 +13,7 @@ static class ConfigReader /// /// Config lives in the same folder as the EXE, name "BrowserSelector.ini". /// - static string ConfigPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "BrowserSelector.ini"); + public static string ConfigPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "BrowserSelector.ini"); static internal IEnumerable GetUrlPreferences() { @@ -62,6 +64,58 @@ static KeyValuePair SplitConfig(string configLine) var parts = configLine.Split(new[] { '=' }, 2); return new KeyValuePair(parts[0].Trim(), parts[1].Trim()); } + + public static void CreateSampleIni() + { + Assembly assembly; + Stream stream; + StringBuilder result; + + assembly = Assembly.GetExecutingAssembly(); + //stream = assembly.GetManifestResourceStream("DanTup.BrowserSelector.BrowserSelector.ini"); + stream = assembly.GetManifestResourceStream(assembly.GetManifestResourceNames()[0]); + if (stream == null) + { + return; + } + + result = new StringBuilder(); + + using (StreamReader reader = new StreamReader(stream)) + { + result.Append(reader.ReadToEnd()); + reader.Close(); + } + + if (result.Length > 0) + { + if (File.Exists(ConfigPath)) + { + string newName = GetBackupFileName(ConfigPath); + File.Move(ConfigPath, newName); + } + + File.WriteAllText(ConfigPath, result.ToString()); + } + } + + static string GetBackupFileName(string fileName) + { + string newName; + string fname; + string fext; + int index = 0; + + fname = Path.GetDirectoryName(fileName) + "\\" + Path.GetFileNameWithoutExtension(fileName); + fext = Path.GetExtension(fileName); + + do + { + newName = string.Format("{0}.{1:0000}{2}", fname, ++index, fext); + } while (File.Exists(newName)); + + return newName; + } } class Browser diff --git a/DanTup.BrowserSelector/DanTup.BrowserSelector.csproj b/DanTup.BrowserSelector/DanTup.BrowserSelector.csproj index 23b4efc..27a2915 100644 --- a/DanTup.BrowserSelector/DanTup.BrowserSelector.csproj +++ b/DanTup.BrowserSelector/DanTup.BrowserSelector.csproj @@ -38,6 +38,9 @@ Browser.ico + + OnOutputUpdated + @@ -57,14 +60,17 @@ - + PreserveNewest - + + + if exist "%25Bin%25\apps\$(TargetName)\$(TargetFileName)" copy /Y /V /B "$(TargetPath)" "%25Bin%25\apps\$(TargetName)\$(TargetFileName)" +