├── SteamAccountSwitcher ├── SteamAccountSwitcher.ico ├── FodyWeavers.xml ├── SteamAccount.cs ├── MyTaskbarIcon.cs ├── App.xaml ├── ObjectToTypeConverter.cs ├── Options.xaml.cs ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── SteamIdToAvatarConverter.cs ├── AppResources.xaml.cs ├── SteamAccountSwitcher.csproj ├── AppResources.xaml ├── App.config ├── SteamAccountCollection.cs ├── App.xaml.cs ├── Options.xaml ├── Resources │ └── Licenses.txt └── SteamClient.cs ├── .github └── workflows │ ├── build.yml │ └── deploy.yml ├── SteamAccountSwitcher.sln ├── LICENSE ├── README.md ├── Product.wxs └── .gitignore /SteamAccountSwitcher/SteamAccountSwitcher.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielchalmers/SteamAccountSwitcher/HEAD/SteamAccountSwitcher/SteamAccountSwitcher.ico -------------------------------------------------------------------------------- /SteamAccountSwitcher/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | deploy: 9 | runs-on: windows-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | 13 | - uses: actions/setup-dotnet@v2 14 | 15 | - name: Build 16 | run: dotnet build 17 | -------------------------------------------------------------------------------- /SteamAccountSwitcher/SteamAccount.cs: -------------------------------------------------------------------------------- 1 | namespace SteamAccountSwitcher 2 | { 3 | public record class SteamAccount 4 | { 5 | public string ID { get; set; } 6 | 7 | public string Name { get; set; } 8 | 9 | public string Alias { get; set; } 10 | 11 | public override string ToString() => Alias ?? Name; 12 | } 13 | } -------------------------------------------------------------------------------- /SteamAccountSwitcher/MyTaskbarIcon.cs: -------------------------------------------------------------------------------- 1 | using H.NotifyIcon; 2 | 3 | namespace SteamAccountSwitcher 4 | { 5 | public class MyTaskbarIcon : TaskbarIcon 6 | { 7 | public MyTaskbarIcon() 8 | { 9 | ForceCreate(); 10 | } 11 | 12 | public void ShowRunningInTrayNotification() 13 | { 14 | ShowNotification("Running in the tray", "Click the icon to see your accounts"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /SteamAccountSwitcher/App.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /SteamAccountSwitcher/ObjectToTypeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | using System.Windows.Markup; 5 | 6 | namespace SteamAccountSwitcher 7 | { 8 | [ValueConversion(typeof(object), typeof(Type))] 9 | public class ObjectToTypeConverter : MarkupExtension, IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | return value.GetType(); 14 | } 15 | 16 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 17 | { 18 | throw new NotImplementedException(); 19 | } 20 | 21 | public override object ProvideValue(IServiceProvider serviceProvider) => this; 22 | } 23 | } -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | deploy: 10 | runs-on: windows-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - uses: actions/setup-dotnet@v2 15 | 16 | - name: Build 17 | run: dotnet publish -o "publish" -c Release -r win-x64 18 | 19 | - name: Create installer 20 | run: | 21 | dotnet tool install --global wix --version 4.0.0-preview.1 22 | wix build Product.wxs -o "publish/Install Steam Account Switcher.msi" 23 | 24 | - name: Create GitHub release 25 | uses: ncipollo/release-action@v1 26 | with: 27 | artifacts: "publish/*.exe,publish/*.msi" 28 | allowUpdates: true 29 | artifactErrorsFailBuild: true 30 | prerelease: contains(github.ref, 'beta') 31 | -------------------------------------------------------------------------------- /SteamAccountSwitcher.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.22609.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamAccountSwitcher", "SteamAccountSwitcher\SteamAccountSwitcher.csproj", "{AC008FC6-F8BF-44E3-AEBD-A0FCECC5253F}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {AC008FC6-F8BF-44E3-AEBD-A0FCECC5253F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {AC008FC6-F8BF-44E3-AEBD-A0FCECC5253F}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {AC008FC6-F8BF-44E3-AEBD-A0FCECC5253F}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {AC008FC6-F8BF-44E3-AEBD-A0FCECC5253F}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Daniel Chalmers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SteamAccountSwitcher/Options.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Windows; 4 | using SteamAccountSwitcher.Properties; 5 | 6 | namespace SteamAccountSwitcher 7 | { 8 | /// 9 | /// Interaction logic for Options.xaml 10 | /// 11 | public partial class Options : Window 12 | { 13 | public Options() 14 | { 15 | InitializeComponent(); 16 | Settings.Default.Save(); 17 | } 18 | 19 | private void GitHubHyperlink_Click(object sender, RoutedEventArgs e) 20 | { 21 | Process.Start(Properties.Resources.GitHub); 22 | } 23 | 24 | private void LicensesHyperlink_Click(object sender, RoutedEventArgs e) 25 | { 26 | MessageBox.Show(Properties.Resources.Licenses); 27 | } 28 | 29 | private void OkButton_Click(object sender, RoutedEventArgs e) 30 | { 31 | DialogResult = true; 32 | } 33 | 34 | private void CancelButton_Click(object sender, RoutedEventArgs e) 35 | { 36 | DialogResult = false; 37 | } 38 | 39 | private void Window_Closed(object sender, EventArgs e) 40 | { 41 | if (DialogResult == true) 42 | { 43 | Settings.Default.Save(); 44 | } 45 | else 46 | { 47 | Settings.Default.Reload(); 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /SteamAccountSwitcher/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | True 10 | 11 | 12 | False 13 | 14 | 15 | 30000 16 | 17 | 18 | 100 19 | 20 | 21 | 22 | 23 | 24 | True 25 | 26 | 27 | -------------------------------------------------------------------------------- /SteamAccountSwitcher/SteamIdToAvatarConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Controls; 4 | using System.Windows.Data; 5 | using System.Windows.Markup; 6 | using System.Windows.Media.Imaging; 7 | using System.Xml; 8 | using SteamAccountSwitcher.Properties; 9 | 10 | namespace SteamAccountSwitcher; 11 | 12 | [ValueConversion(typeof(string), typeof(Image))] 13 | public class SteamIdToAvatarConverter : MarkupExtension, IValueConverter 14 | { 15 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 16 | { 17 | try 18 | { 19 | if (Settings.Default.ShowAvatars && value is string id) 20 | { 21 | var profileDocument = new XmlDocument(); 22 | 23 | profileDocument.Load($"https://steamcommunity.com/profiles/{id}?xml=1"); 24 | 25 | var avatarIconNode = profileDocument.DocumentElement.SelectSingleNode("/profile/avatarIcon"); 26 | 27 | return new Image { Source = new BitmapImage(new Uri(avatarIconNode.InnerText)) }; 28 | } 29 | } 30 | catch 31 | { 32 | // Couldn't load the image. 33 | } 34 | 35 | return null; 36 | } 37 | 38 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 39 | { 40 | throw new NotImplementedException(); 41 | } 42 | 43 | public override object ProvideValue(IServiceProvider serviceProvider) => this; 44 | } -------------------------------------------------------------------------------- /SteamAccountSwitcher/AppResources.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | 6 | namespace SteamAccountSwitcher 7 | { 8 | public partial class AppResources : ResourceDictionary 9 | { 10 | public AppResources() 11 | { 12 | InitializeComponent(); 13 | } 14 | 15 | private async void MenuItem_Click(object sender, RoutedEventArgs e) 16 | { 17 | var menuItem = (MenuItem)sender; 18 | 19 | if (menuItem.CommandParameter is string stringParameter) 20 | { 21 | if (stringParameter == "add-account") 22 | { 23 | await SteamClient.LogOut(); 24 | } 25 | else if (stringParameter == "options") 26 | { 27 | var optionsDialog = Application.Current.Windows.OfType().FirstOrDefault() ?? new Options(); 28 | 29 | if (optionsDialog.IsVisible) 30 | { 31 | optionsDialog.Activate(); 32 | return; 33 | } 34 | 35 | optionsDialog.ShowDialog(); 36 | } 37 | else if (stringParameter == "exit") 38 | { 39 | Application.Current.Shutdown(); 40 | } 41 | } 42 | else if (menuItem.CommandParameter is SteamAccount account) 43 | { 44 | menuItem.IsEnabled = false; 45 | await SteamClient.LogIn(account); 46 | menuItem.IsEnabled = true; 47 | } 48 | else 49 | { 50 | throw new NotImplementedException(); 51 | } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Steam Account Switcher 2 | 3 | [![Release](https://img.shields.io/github/release/danielchalmers/SteamAccountSwitcher?label=Release&include_prereleases)](https://github.com/danielchalmers/SteamAccountSwitcher/releases) 4 | [![License](https://img.shields.io/github/license/danielchalmers/SteamAccountSwitcher?label=License)](LICENSE) 5 | 6 | Quickly switch between your Steam accounts with a lightweight and easy to use menu. 7 | 8 | ![Tray menu](https://user-images.githubusercontent.com/7112040/205158482-606f7df8-bdfc-4249-881f-018e300a340d.png) 9 | 10 | ## Features 11 | 12 | ✅ Fast — switch users through the tray icon 13 | ✅ Easy — accounts are found automatically 14 | ✅ Safe — no VAC risk & doesn't store passwords 15 | ✅ Open — free & open source forever 16 | 17 | ## Download 18 | 19 | ➡️ Get it from the [Releases](https://github.com/danielchalmers/SteamAccountSwitcher/releases) page (see `Assets`). 20 | 21 | Windows 10 [version 1903](https://support.microsoft.com/en-us/windows/which-version-of-windows-operating-system-am-i-running-628bec99-476a-2c13-5296-9dd081cdd808) or newer is recommended. 22 | 23 | ## What's new in v3.0 24 | 25 | - The tray icon is now the default and the main window has been removed in order to streamline the app. 26 | - Accounts are now automatically discovered — no setup needed! 27 | - Passwords are handled entirely by Steam for extra security and ease of use. 28 | - Steam Guard is not required on every login like before. 29 | - Cleaner codebase that's easier to understand and change. 30 | 31 | ## v2.3.1 32 | 33 | Looking for the old version? [Download v2.3.1 here](https://github.com/danielchalmers/SteamAccountSwitcher/releases/tag/v2.3.1). 34 | 35 | ![v2.3.1 Main window](https://user-images.githubusercontent.com/7112040/33782616-6809ccfc-dc27-11e7-8323-cf9771d89b9a.png) 36 | -------------------------------------------------------------------------------- /SteamAccountSwitcher/SteamAccountSwitcher.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net48 4 | WinExe 5 | true 6 | true 7 | latest 8 | SteamAccountSwitcher.ico 9 | Steam Account Switcher 10 | Daniel Chalmers 11 | Steam Account Switcher 12 | © Daniel Chalmers 2022 13 | 3.0.0 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | PublicResXFileCodeGenerator 27 | Resources.Designer.cs 28 | 29 | 30 | True 31 | True 32 | Resources.resx 33 | 34 | 35 | SettingsSingleFileGenerator 36 | Settings.Designer.cs 37 | 38 | 39 | True 40 | True 41 | Settings.settings 42 | 43 | 44 | -------------------------------------------------------------------------------- /SteamAccountSwitcher/AppResources.xaml: -------------------------------------------------------------------------------- 1 | 5 | 9 | 10 | 11 | 12 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /SteamAccountSwitcher/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | True 21 | 22 | 23 | False 24 | 25 | 26 | 27 | 28 | 29 | True 30 | 31 | 32 | 33 | 34 | 35 | 36 | 30000 37 | 38 | 39 | 100 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /SteamAccountSwitcher/SteamAccountCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.IO; 5 | using Gameloop.Vdf; 6 | 7 | namespace SteamAccountSwitcher 8 | { 9 | public class SteamAccountCollection : ObservableCollection 10 | { 11 | private FileSystemWatcher _watcher; 12 | private string _installDirectory; 13 | private string _configDirectory; 14 | 15 | /// 16 | /// Sets the Steam installation directory to be used, and reloads the list of accounts. 17 | /// 18 | public void SetDirectory(string installDirectory) 19 | { 20 | if (string.IsNullOrEmpty(installDirectory) || !Directory.Exists(installDirectory)) 21 | throw new ArgumentException("The directory doesn't exist.", nameof(installDirectory)); 22 | 23 | _installDirectory = installDirectory; 24 | _configDirectory = Path.Combine(installDirectory, "config"); 25 | 26 | // Reinitialize filesystem watcher with the new directory. 27 | _watcher?.Dispose(); 28 | _watcher = new(_configDirectory, "loginusers.vdf") 29 | { 30 | EnableRaisingEvents = true 31 | }; 32 | _watcher.Changed += OnFileChanged; 33 | 34 | Reload(); 35 | } 36 | 37 | /// 38 | /// Reloads the list of accounts by reading from the Steam directory. 39 | /// 40 | public void Reload() 41 | { 42 | if (string.IsNullOrEmpty(_installDirectory) || !Directory.Exists(_installDirectory)) 43 | throw new InvalidOperationException("Can't reload; Steam directory doesn't exist!"); 44 | 45 | Clear(); 46 | foreach (var account in GetAccounts(_configDirectory)) 47 | Add(account); 48 | } 49 | 50 | private void OnFileChanged(object sender, FileSystemEventArgs e) 51 | { 52 | System.Windows.Application.Current.Dispatcher.Invoke(Reload); 53 | } 54 | 55 | private string GetLoginUsersVdfContent(string configDirectory) 56 | { 57 | var loginUsersVdfPath = Path.Combine(configDirectory, "loginusers.vdf"); 58 | 59 | var triesLeft = 10; 60 | while (true) 61 | { 62 | try 63 | { 64 | return File.ReadAllText(loginUsersVdfPath); 65 | } 66 | catch (IOException) 67 | { 68 | // Keep trying to read file if it's locked by another process. 69 | triesLeft--; 70 | 71 | if (triesLeft == 0) 72 | { 73 | // Give up. 74 | throw; 75 | } 76 | 77 | // Blocking the thread is not ideal, but it's a rare situation anyway. 78 | System.Threading.Thread.Sleep(200); 79 | } 80 | } 81 | } 82 | 83 | private IEnumerable GetAccounts(string configDirectory) 84 | { 85 | dynamic loginUsers = VdfConvert.Deserialize(GetLoginUsersVdfContent(configDirectory)); 86 | 87 | foreach (var loginUser in loginUsers.Value) 88 | { 89 | yield return new() 90 | { 91 | ID = loginUser.Key, 92 | Name = loginUser.Value.AccountName.Value, 93 | Alias = loginUser.Value.PersonaName?.Value, 94 | }; 95 | } 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /Product.wxs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /SteamAccountSwitcher/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Threading; 3 | using System.Windows; 4 | using System.Windows.Threading; 5 | using Microsoft.Win32; 6 | using SteamAccountSwitcher.Properties; 7 | 8 | namespace SteamAccountSwitcher 9 | { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application 14 | { 15 | public App() 16 | { 17 | Dispatcher.UnhandledException += OnDispatcherUnhandledException; 18 | } 19 | 20 | public static Mutex AppMutex { get; private set; } 21 | public static MyTaskbarIcon TrayIcon { get; private set; } 22 | 23 | protected override void OnStartup(StartupEventArgs e) 24 | { 25 | base.OnStartup(e); 26 | 27 | AppMutex = new Mutex(true, "22E1FAEA-639E-400B-9DCB-F2D04EC126E1", out var isNewInstance); 28 | 29 | // Exit if another instance is already running. 30 | if (!isNewInstance) 31 | { 32 | Shutdown(1); 33 | return; 34 | } 35 | 36 | // Upgrade settings from an earlier version. 37 | if (Settings.Default.MustUpgrade) 38 | { 39 | Settings.Default.Upgrade(); 40 | Settings.Default.MustUpgrade = false; 41 | Settings.Default.Save(); 42 | } 43 | 44 | // Load tray icon. 45 | TrayIcon = (MyTaskbarIcon)FindResource("TrayIcon"); 46 | TrayIcon.ShowRunningInTrayNotification(); 47 | 48 | // Pre-render menu. 49 | TrayIcon.ContextMenu.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 50 | TrayIcon.ContextMenu.Arrange(new Rect(new Point(0, 0), TrayIcon.ContextMenu.DesiredSize)); 51 | 52 | LoadAccounts(); 53 | 54 | Settings.Default.PropertyChanged += Settings_PropertyChanged; 55 | } 56 | 57 | protected override void OnExit(ExitEventArgs e) 58 | { 59 | base.OnExit(e); 60 | 61 | AppMutex?.Dispose(); 62 | TrayIcon?.Dispose(); 63 | } 64 | 65 | private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) 66 | { 67 | TrayIcon.ShowNotification("An unhandled error occurred", e.Exception.Message); 68 | } 69 | 70 | private void Settings_PropertyChanged(object sender, PropertyChangedEventArgs e) 71 | { 72 | switch (e.PropertyName) 73 | { 74 | case nameof(Settings.Default.RunOnStartup): 75 | SetRunOnStartup(Settings.Default.RunOnStartup); 76 | break; 77 | 78 | case nameof(Settings.Default.SteamInstallDirectory): 79 | case nameof(Settings.Default.ShowAvatars): 80 | LoadAccounts(); 81 | break; 82 | } 83 | } 84 | 85 | private void LoadAccounts() 86 | { 87 | var steamDirectory = SteamClient.FindInstallDirectory(); 88 | 89 | if (steamDirectory != null) 90 | SteamClient.Accounts.SetDirectory(steamDirectory); 91 | } 92 | 93 | private void SetRunOnStartup(bool runOnStartup) 94 | { 95 | using var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true); 96 | 97 | if (runOnStartup) 98 | { 99 | key?.SetValue(SteamAccountSwitcher.Properties.Resources.AppPathName, ResourceAssembly.Location); 100 | } 101 | else 102 | { 103 | key?.DeleteValue(SteamAccountSwitcher.Properties.Resources.AppPathName, false); 104 | } 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /SteamAccountSwitcher/Options.xaml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 42 | 43 | 46 | 47 | 51 | 52 | 55 | 56 | 61 | 62 | 65 | 66 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | Licenses... 91 | 92 | 93 | 94 | 95 | 96 | View on GitHub 97 | 98 | 99 | 100 |