Skip to content

Commit

Permalink
Allow changing the process name for custom installs
Browse files Browse the repository at this point in the history
  • Loading branch information
sabihoshi committed Jul 18, 2021
1 parent 41e5d60 commit fbd7974
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 13 deletions.
14 changes: 13 additions & 1 deletion GenshinLyreMidiPlayer.Data/Properties/Settings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions GenshinLyreMidiPlayer.Data/Properties/Settings.settings
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,8 @@
<Setting Name="UpgradeRequired" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="GenshinLocation" Type="System.String" Scope="User">
<Value Profile="(Default)">GenshinImpact.exe</Value>
</Setting>
</Settings>
</SettingsFile>
14 changes: 11 additions & 3 deletions GenshinLyreMidiPlayer.WPF/Core/WindowHelper.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using GenshinLyreMidiPlayer.Data.Properties;
using Microsoft.Win32;

namespace GenshinLyreMidiPlayer.WPF.Core
{
public static class WindowHelper
{
private const string GenshinProcessName = "GenshinImpact";
public static string? InstallLocation => Registry.LocalMachine
.OpenSubKey(@"SOFTWARE\launcher", false)
?.GetValue("InstPath") as string;

private static string GenshinProcessName
=> Path.GetFileNameWithoutExtension(Settings.Default.GenshinLocation)!;

private static IntPtr? FindWindowByProcessName(string processName)
{
var process = Process.GetProcessesByName(processName);
return process.FirstOrDefault()?.MainWindowHandle;
return process.FirstOrDefault(p => p.MainWindowHandle != IntPtr.Zero)?.MainWindowHandle;
}

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
Expand Down Expand Up @@ -43,7 +51,7 @@ public static bool IsGameFocused()
{
var genshinWindow = FindWindowByProcessName(GenshinProcessName);
return genshinWindow != null &&
IsWindowFocused((IntPtr) genshinWindow);
IsWindowFocused((IntPtr) genshinWindow);
}
}
}
2 changes: 1 addition & 1 deletion GenshinLyreMidiPlayer.WPF/GenshinLyreMidiPlayer.WPF.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<UseWPF>true</UseWPF>
<StartupObject>GenshinLyreMidiPlayer.WPF.App</StartupObject>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Version>2.2.1</Version>
<Version>2.3.0</Version>
<ApplicationIcon>item_windsong_lyre.ico</ApplicationIcon>
<Nullable>enable</Nullable>
<RepositoryUrl>https://github.com/sabihoshi/GenshinLyreMidiPlayer</RepositoryUrl>
Expand Down
3 changes: 2 additions & 1 deletion GenshinLyreMidiPlayer.WPF/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Linq;
using GenshinLyreMidiPlayer.Data;
using GenshinLyreMidiPlayer.WPF.Views;
using ModernWpf;
using ModernWpf.Controls;
using Stylet;
using StyletIoC;
Expand Down Expand Up @@ -50,6 +49,8 @@ protected override async void OnViewLoaded()
var menuItems = _navView.MenuItems.Cast<NavigationViewItemBase>();
_navView.SelectedItem = menuItems.FirstOrDefault(item => item is NavigationViewItem);

if (!SettingsView.TryGetLocation()) _ = SettingsView.LocationMissing();

if (SettingsView.AutoCheckUpdates)
{
_ = SettingsView.CheckForUpdate()
Expand Down
87 changes: 87 additions & 0 deletions GenshinLyreMidiPlayer.WPF/ViewModels/SettingsPageViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
Expand All @@ -15,7 +16,9 @@
using GenshinLyreMidiPlayer.WPF.ModernWPF;
using GenshinLyreMidiPlayer.WPF.ModernWPF.Animation;
using GenshinLyreMidiPlayer.WPF.ModernWPF.Animation.Transitions;
using Microsoft.Win32;
using ModernWpf;
using ModernWpf.Controls;
using Stylet;
using StyletIoC;

Expand Down Expand Up @@ -158,6 +161,90 @@ public int KeyOffset

public static Version ProgramVersion => Assembly.GetExecutingAssembly().GetName().Version!;

public string GenshinLocation
{
get => Settings.GenshinLocation;
set => Settings.GenshinLocation = value;
}

public bool TryGetLocation()
{
var locations = new[]
{
// User set location
Settings.GenshinLocation,

// Default install location
@"C:\Program Files\Genshin Impact\Genshin Impact Game\GenshinImpact.exe",
@"C:\Program Files\Genshin Impact\Genshin Impact Game\YuanShen.exe",

// Custom install location
Path.Combine(WindowHelper.InstallLocation ?? string.Empty, @"Genshin Impact Game\GenshinImpact.exe"),
Path.Combine(WindowHelper.InstallLocation ?? string.Empty, @"Genshin Impact Game\YuanShen.exe"),

// Relative location
AppContext.BaseDirectory + "GenshinImpact.exe",
AppContext.BaseDirectory + "YuanShen.exe"
};

return locations.Any(TrySetLocation);
}

private bool TrySetLocation(string? location)
{
if (File.Exists(location) && location is not null)
{
Settings.GenshinLocation = location;
NotifyOfPropertyChange(() => Settings.GenshinLocation);
return true;
}

return false;
}

public async Task SetLocation()
{
var openFileDialog = new OpenFileDialog
{
Filter = "Executable|*.exe|All files (*.*)|*.*",
InitialDirectory = WindowHelper.InstallLocation is null
? string.Empty
: Path.Combine(WindowHelper.InstallLocation, "Genshin Impact Game")
};

var success = openFileDialog.ShowDialog() == true;
var set = TrySetLocation(openFileDialog.FileName);

if (!(success && set)) await LocationMissing();
}

public async Task LocationMissing()
{
var dialog = new ContentDialog
{
Title = "Error",
Content = "Could not find Game's Location",

PrimaryButtonText = "Find Manually...",
SecondaryButtonText = "Ignore",
CloseButtonText = "Exit"
};

var result = await dialog.ShowAsync();

switch (result)
{
case ContentDialogResult.None:
RequestClose();
break;
case ContentDialogResult.Primary:
await SetLocation();
break;
case ContentDialogResult.Secondary:
break;
}
}

public async Task StartStopTimer()
{
if (PlayTimerToken is not null)
Expand Down
15 changes: 15 additions & 0 deletions GenshinLyreMidiPlayer.WPF/Views/SettingsPageView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@
</ui:SimpleStackPanel>
</GroupBox>

<GroupBox Header="Location">
<ui:SimpleStackPanel Orientation="Horizontal">
<ui:SimpleStackPanel.Resources>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" />
</ui:SimpleStackPanel.Resources>

<Button Command="{s:Action SetLocation}"
Background="Transparent">
<ui:FontIcon Glyph="&#xE8E5;" />
</Button>
<TextBlock Text="{Binding GenshinLocation}"
VerticalAlignment="Center"/>
</ui:SimpleStackPanel>
</GroupBox>

<GroupBox Header="Theme Mode">
<ui:RadioButtons
SelectedItem="{Binding
Expand Down
12 changes: 5 additions & 7 deletions GenshinLyreMidiPlayer.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<wpf:ResourceDictionary
xml:space="preserve"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml"
xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/OBJECT_CREATION_WHEN_TYPE_NOT_EVIDENT/@EntryValue">TargetTyped</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=YuanShen/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Shen/@EntryIndexedValue">True</s:Boolean>

<s:Boolean x:Key="/Default/UserDictionary/Words/=Stylet/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fody/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fody/@EntryIndexedValue">True</s:Boolean>

<s:Boolean x:Key="/Default/UserDictionary/Words/=sabihoshi/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=prerelease/@EntryIndexedValue">True</s:Boolean>
Expand Down

0 comments on commit fbd7974

Please sign in to comment.