Display Icon to the grid and use process to start app and verify is running

pull/105/head
stevealexandre 2 years ago
parent 903619ba0b
commit 4133cfefc3

@ -4,6 +4,7 @@ using System.Drawing;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Windows.Media.Imaging;
namespace UWPHook namespace UWPHook
{ {
@ -24,6 +25,16 @@ namespace UWPHook
} }
} }
/// <summary>
/// Gets or sets the icon for the app
/// </summary>
private BitmapImage _icon;
public BitmapImage Icon
{
get { return _icon; }
set { _icon = value; }
}
private string _name; private string _name;
/// <summary> /// <summary>
@ -55,18 +66,6 @@ namespace UWPHook
set { _aumid = value; } set { _aumid = value; }
} }
/// <summary>
/// Gets or sets the icon for the app
/// </summary>
private string _icon;
public string Icon
{
get { return _icon; }
set { _icon = value; }
}
/// <summary> /// <summary>
/// Sets the path where icons for the app is /// Sets the path where icons for the app is
/// </summary> /// </summary>

@ -22,6 +22,7 @@ namespace UWPHook
private static int runningProcessId; private static int runningProcessId;
private static bool isLauncherProcess; private static bool isLauncherProcess;
private static string executablePath; private static string executablePath;
private static string executableName;
/// <summary> /// <summary>
/// Launch a UWP App using a ApplicationActivationManager and sets a internal id to launched proccess id /// Launch a UWP App using a ApplicationActivationManager and sets a internal id to launched proccess id
@ -35,6 +36,7 @@ namespace UWPHook
// 2 is the executable, the rest are extras // 2 is the executable, the rest are extras
string aumid = args[1]; string aumid = args[1];
executablePath = args[2].Contains("/") ? args[2].Replace('/', '\\') : args[2]; executablePath = args[2].Contains("/") ? args[2].Replace('/', '\\') : args[2];
executableName = args[2].Contains("/") ? args[2].Substring(args[2].LastIndexOf("/") + 1) : args[2];
Log.Verbose("Arguments => " + String.Join("/", args)); Log.Verbose("Arguments => " + String.Join("/", args));
var mgr = new ApplicationActivationManager(); var mgr = new ApplicationActivationManager();
uint processId; uint processId;
@ -46,12 +48,15 @@ namespace UWPHook
try try
{ {
mgr.ActivateApplication(aumid, extra_args, ActivateOptions.None, out processId); Process process = new Process();
runningProcessId = (int) processId; ProcessStartInfo processStartInfo = new ProcessStartInfo();
Log.Verbose("Process ID => " + runningProcessId.ToString()); processStartInfo.UseShellExecute = true;
processStartInfo.FileName = @"shell:appsFolder\" + aumid;
process.StartInfo = processStartInfo;
process.Start();
//mgr.ActivateApplication(aumid, extra_args, ActivateOptions.None, out processId);
//Bring the launched app to the foreground, this fixes in-home streaming //Bring the launched app to the foreground, this fixes in-home streaming
BringProcess(); //BringProcess();
} }
catch (Exception e) catch (Exception e)
{ {
@ -66,61 +71,33 @@ namespace UWPHook
/// <returns>True if the perviously launched app is running, false otherwise</returns> /// <returns>True if the perviously launched app is running, false otherwise</returns>
public static Boolean IsRunning() public static Boolean IsRunning()
{ {
try bool secondCheck = false;
{ do
Log.Debug("Checking PID => " + runningProcessId.ToString());
// PID 0 means an error during launch for the game
// (Example : Game no more available on gamepass or problem with installation) so instant exit in this case
if (runningProcessId == 0)
{
Log.Debug("PID is 0");
return false;
}
Process.GetProcessById(runningProcessId);
Log.Debug("Process is running");
return true;
}
catch
{ {
// Check only at launch if started by a launcher // Handle process running by some launcher by checking their executable path and name
if (!isLauncherProcess) var processes = GetProcess();
foreach (var process in processes)
{ {
Log.Debug("initial PID is not running anymore, checking other possible process runing before stop"); string executableFile = executablePath.Contains('\\') ? executablePath.Substring(executablePath.LastIndexOf('\\') + 1) : executablePath;
bool secondCheck = false; Log.Verbose("Process " + process.Value.Path + " contains " + executablePath + " ? : " + process.Value.Path.Contains(executablePath).ToString());
do Log.Verbose("Process " + process.Key + " contains " + executableFile + " ? : " + process.Key.Contains(executableFile).ToString());
if (process.Value.Path.Contains(executablePath) || process.Key.Contains(executableFile))
{ {
// Handle process running by some launcher by checking their executable path and name //BringProcess();
var processes = GetProcess(); return true;
foreach (var process in processes) }
{
string executableFile = executablePath.Contains('\\') ? executablePath.Substring(executablePath.LastIndexOf('\\') + 1) : executablePath;
Log.Verbose("Process " + process.Value.Path + " contains " + executablePath + " ? : " + process.Value.Path.Contains(executablePath).ToString());
Log.Verbose("Process " + process.Key + " contains " + executableFile + " ? : " + process.Key.Contains(executableFile).ToString());
if (process.Value.Path.Contains(executablePath) || process.Key.Contains(executableFile))
{
int pid = process.Value.Pid;
Log.Verbose($"Launcher opened child process ({runningProcessId}->{pid}), using new process as target");
runningProcessId = pid;
isLauncherProcess = true;
//bring the "real" launched process
BringProcess();
return true;
}
}
// Handle the last chance if process was not found due to slow running like Farming Simulator 2022 or Halo MCC
secondCheck = !secondCheck;
if (secondCheck)
{
Log.Debug("Process has not been found. Last chance to find it !");
Thread.Sleep(Settings.Default.Seconds * 5000);
}
} while (secondCheck);
} }
}
// Handle the last chance if process was not found due to slow running like Farming Simulator 2022 or Halo MCC
secondCheck = !secondCheck;
if (secondCheck)
{
Log.Debug("Process has not been found. Last chance to find it !");
Thread.Sleep(Settings.Default.Seconds * 5000);
}
} while (secondCheck);
return false; return false;
} }

@ -13,33 +13,41 @@
mc:Ignorable="d" mc:Ignorable="d"
Title="UWPHook" Height="600" Width="800" Icon="/Resources/hook2.ico" Loaded="Window_Loaded"> Title="UWPHook" Height="600" Width="800" Icon="/Resources/hook2.ico" Loaded="Window_Loaded">
<Grid x:Name="grid"> <Grid x:Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="28*"/> <RowDefinition Height="80"/>
<RowDefinition Height="144*"/> <RowDefinition Height="144*"/>
<RowDefinition Height="19*"/> <RowDefinition Height="50"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<materialDesign:ColorZone Padding="16" materialDesign:ShadowAssist.ShadowDepth="Depth2" Mode="PrimaryMid" Height="80"> <!-- HEADER -->
<Label x:Name="label1" Content="Welcome to UWPHook, the easier way to add UWP apps and XGP games and apps to Steam!" HorizontalAlignment="Left" Margin="172,-14,0,0" VerticalAlignment="Top" Foreground="#DDFFFFFF"/> <materialDesign:ColorZone Padding="16" materialDesign:ShadowAssist.ShadowDepth="Depth2" Mode="PrimaryMid" Height="80" Grid.ColumnSpan="3">
<Label x:Name="label_header" Content="Welcome to UWPHook, the easier way to add UWP apps and XGP games and apps to Steam!" HorizontalAlignment="Left" Margin="172,-14,0,0" VerticalAlignment="Top" Foreground="#DDFFFFFF"/>
</materialDesign:ColorZone> </materialDesign:ColorZone>
<Image x:Name="image" HorizontalAlignment="Left" Width="178" Height="80" VerticalAlignment="Top" Source="Resources/WhiteTransparent.png" Stretch="UniformToFill" ToolTip="Welcome to UWPHook, add your UWP apps and games to Steam!"/> <Image x:Name="applicationLogo" HorizontalAlignment="Left" Width="178" Height="80" VerticalAlignment="Top" Source="Resources/WhiteTransparent.png" Stretch="UniformToFill" ToolTip="Welcome to UWPHook, add your UWP apps and games to Steam!"/>
<Button x:Name="settingsButton" Click="SettingsButton_Click" Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}" <!-- FLOATING BUTTONS -->
Margin="0,6,10,0" HorizontalAlignment="Right" <Button x:Name="settingsButton" Click="SettingsButton_Click" Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}" HorizontalAlignment="Center" ToolTip="Settings/About" VerticalAlignment="Center" Grid.Column="2">
ToolTip="Settings/About" VerticalAlignment="Top">
<materialDesign:PackIcon Kind="Settings" Height="24" Width="24" /> <materialDesign:PackIcon Kind="Settings" Height="24" Width="24" />
</Button> </Button>
<Button Click="LoadButton_Click" Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}" <Button Click="LoadButton_Click" Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}" ToolTip="Load installed UWP Apps" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Column="1" Grid.RowSpan="1">
Margin="0,51,10,0" HorizontalAlignment="Right"
ToolTip="Load installed UWP Apps" VerticalAlignment="Top" Grid.RowSpan="2">
<materialDesign:PackIcon Kind="Reload" Height="24" Width="24" /> <materialDesign:PackIcon Kind="Reload" Height="24" Width="24" />
</Button> </Button>
<Grid Margin="10" Grid.Row="1"> <!-- LIST -->
<DataGrid x:Name="listGames" Margin="0,25,0,0" CanUserSortColumns="True" CanUserAddRows="False" <DataGrid x:Name="listGames" CanUserAddRows="False" materialDesign:DataGridAssist.CellPadding="4 2 2 2" materialDesign:DataGridAssist.ColumnHeaderPadding="4 2 2 2" Grid.Row="1" Grid.ColumnSpan="3" Margin="10"/>
materialDesign:DataGridAssist.CellPadding="4 2 2 2" materialDesign:DataGridAssist.ColumnHeaderPadding="4 2 2 2"/> <ProgressBar Visibility="Hidden" x:Name="progressBar" Grid.Row="1" IsIndeterminate="True" Grid.ColumnSpan="3" Margin="10"/>
<Label x:Name="label" Content="Press 'Load installed apps' to get a list of installed titles." HorizontalAlignment="Left" Margin="0,-10,0,0" VerticalAlignment="Top"/> <!-- FOOTER -->
<Grid Grid.Row="2" Grid.ColumnSpan="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="30*"/>
<ColumnDefinition Width="250"/>
</Grid.ColumnDefinitions>
<Label Content="Search:" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBox x:Name="textBox" Height="25" TextWrapping="Wrap" VerticalAlignment="Center" MinWidth="200" TextChanged="textBox_TextChanged" Grid.Column="1" Cursor="Arrow" HorizontalAlignment="Left" />
<Button Content="Export selected apps to Steam" Click="ExportButton_Click" HorizontalAlignment="Right" Margin="0,0,10,10" Grid.Row="0" VerticalAlignment="Bottom" Width="227" Grid.Column="2"/>
</Grid> </Grid>
<Button Content="Export selected apps to Steam" Click="ExportButton_Click" HorizontalAlignment="Right" Margin="0,0,10,10" Grid.Row="2" VerticalAlignment="Bottom" Width="227"/>
<ProgressBar Visibility="Collapsed" x:Name="progressBar" Margin="10,215,10,174" Grid.Row="1" IsIndeterminate="True" />
<Label Content="Filter:" HorizontalAlignment="Left" Margin="5,16,0,0" Grid.Row="2" VerticalAlignment="Top"/>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="25" Margin="50,17,0,0" Grid.Row="2" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="271" TextChanged="textBox_TextChanged"/>
</Grid> </Grid>
</Window> </Window>

@ -16,6 +16,9 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using UWPHook.Properties; using UWPHook.Properties;
using UWPHook.SteamGridDb; using UWPHook.SteamGridDb;
using VDFParser; using VDFParser;
@ -380,7 +383,7 @@ namespace UWPHook
foreach (var app in selected_apps) foreach (var app in selected_apps)
{ {
app.Icon = app.widestSquareIcon(); //app.Icon = Image.FromFile(app.widestSquareIcon());
if (downloadGridImages) if (downloadGridImages)
{ {
@ -535,7 +538,7 @@ namespace UWPHook
string icons_path = path + @"\Briano\UWPHook\icons\"; string icons_path = path + @"\Briano\UWPHook\icons\";
// If we do not have an specific icon to copy, copy app.icon, if we do, copy the specified icon // If we do not have an specific icon to copy, copy app.icon, if we do, copy the specified icon
string icon_to_copy = String.IsNullOrEmpty(forcedIcon) ? app.Icon : forcedIcon; string icon_to_copy = String.IsNullOrEmpty(forcedIcon) ? app.IconPath : forcedIcon;
if (!Directory.Exists(icons_path)) if (!Directory.Exists(icons_path))
@ -554,7 +557,7 @@ namespace UWPHook
// but this app is now prone to #90 unfortunately, if we return String.empty, Steam will default // but this app is now prone to #90 unfortunately, if we return String.empty, Steam will default
// to UWPHook's icon // to UWPHook's icon
Log.Warning("File could not be copied: " + icon_to_copy); Log.Warning("File could not be copied: " + icon_to_copy);
dest_file = app.Icon; dest_file = app.IconPath;
} }
return dest_file; return dest_file;
@ -666,7 +669,6 @@ namespace UWPHook
bwrLoad.RunWorkerCompleted += Bwr_RunWorkerCompleted; bwrLoad.RunWorkerCompleted += Bwr_RunWorkerCompleted;
grid.IsEnabled = false; grid.IsEnabled = false;
label.Content = "Loading your installed apps";
progressBar.Visibility = Visibility.Visible; progressBar.Visibility = Visibility.Visible;
Apps.Entries = new System.Collections.ObjectModel.ObservableCollection<AppEntry>(); Apps.Entries = new System.Collections.ObjectModel.ObservableCollection<AppEntry>();
@ -682,13 +684,30 @@ namespace UWPHook
private void Bwr_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) private void Bwr_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{ {
listGames.ItemsSource = Apps.Entries; listGames.ItemsSource = Apps.Entries;
listGames.Columns[0].IsReadOnly = false;
listGames.Columns[2].IsReadOnly = true; DataGridTemplateColumn templateColumn = new DataGridTemplateColumn
listGames.Columns[3].IsReadOnly = true; {
CanUserResize = false,
CanUserSort = false,
CanUserReorder = false
};
DataTemplate cellTemplate = new DataTemplate();
FrameworkElementFactory factory = new FrameworkElementFactory(typeof(System.Windows.Controls.Image));
factory.SetBinding(System.Windows.Controls.Image.SourceProperty, new Binding("Icon"));
factory.SetValue(System.Windows.Controls.Image.WidthProperty, 24.00);
factory.SetValue(System.Windows.Controls.Image.HeightProperty, 24.00);
cellTemplate.VisualTree = factory;
templateColumn.CellTemplate = cellTemplate;
listGames.Columns[1] = templateColumn;
listGames.Columns[3].Visibility = Visibility.Hidden;
listGames.Columns[4].Visibility = Visibility.Hidden;
listGames.Columns[5].Visibility = Visibility.Hidden;
grid.IsEnabled = true; grid.IsEnabled = true;
progressBar.Visibility = Visibility.Collapsed; progressBar.Visibility = Visibility.Collapsed;
label.Content = "Installed Apps";
} }
/// <summary> /// <summary>
@ -730,9 +749,56 @@ namespace UWPHook
{ {
//We get the default square tile to find where the app stores it's icons, then we resolve which one is the widest //We get the default square tile to find where the app stores it's icons, then we resolve which one is the widest
string logosPath = Path.GetDirectoryName(values[1]); string logosPath = Path.GetDirectoryName(values[1]);
BitmapImage appLogo = null;
List<string> images = new List<string>();
System.Drawing.Size size = new System.Drawing.Size(0, 0);
try
{
images.AddRange(Directory.GetFiles(logosPath, "*.png"));
}
catch(System.Exception ex)
{
Log.Error(ex.Message);
continue;
}
if (images.Count > 0) {
System.Drawing.Image currentImage = null;
foreach (string image in images)
{
try
{
currentImage = System.Drawing.Image.FromFile(image);
}
catch (System.Exception ex)
{
Log.Error(ex.Message);
}
if (currentImage != null)
{
//UWP apps usually store live tile images inside the same directory
//Let's check if the image is square for use as icon on Steam and pick the largest one
if (currentImage.Width == currentImage.Height && (size.Height == 0 || (currentImage.Size.Height < size.Height)))
{
size = currentImage.Size;
appLogo = new BitmapImage();
appLogo.BeginInit();
appLogo.CacheOption = BitmapCacheOption.OnLoad;
appLogo.UriSource = new Uri(image);
appLogo.EndInit();
}
}
}
}
appLogo.Freeze();
Application.Current.Dispatcher.BeginInvoke((Action)delegate () Application.Current.Dispatcher.BeginInvoke((Action)delegate ()
{ {
Apps.Entries.Add(new AppEntry() { Name = values[0], Executable = values[3], IconPath = logosPath, Aumid = values[2], Selected = false }); Apps.Entries.Add(new AppEntry() { Name = values[0], Icon = appLogo, Executable = values[3], IconPath = logosPath, Aumid = values[2], Selected = false });
}); });
} }
} }

Loading…
Cancel
Save