2020-05-16 11:16:46 +00:00
using HeliosPlus.GameLibraries ;
2020-05-17 09:19:55 +00:00
using HeliosPlus.Resources ;
2020-05-16 11:16:46 +00:00
using HeliosPlus.Shared ;
using Newtonsoft.Json ;
using System ;
using System.Collections.Generic ;
using System.Drawing ;
2020-06-07 08:48:45 +00:00
using System.Drawing.Drawing2D ;
2020-05-16 11:16:46 +00:00
using System.Drawing.IconLib ;
using System.Drawing.Imaging ;
2020-06-07 08:48:45 +00:00
using TsudaKageyu ;
2020-05-16 11:16:46 +00:00
using System.Globalization ;
using System.IO ;
using System.Linq ;
2020-05-17 09:19:55 +00:00
using System.Runtime.InteropServices ;
using System.ServiceModel.Dispatcher ;
2020-05-16 11:16:46 +00:00
using System.Text ;
using System.Threading.Tasks ;
2020-05-17 09:19:55 +00:00
using System.Windows.Forms ;
2020-06-13 09:06:42 +00:00
using NvAPIWrapper.Native.Display.Structures ;
2020-06-15 09:57:46 +00:00
using System.Text.RegularExpressions ;
2020-07-21 07:50:41 +00:00
using IWshRuntimeLibrary ;
2020-07-23 06:31:00 +00:00
using System.Diagnostics ;
using System.Threading ;
using HeliosPlus.InterProcess ;
using HeliosPlus.UIForms ;
2020-10-18 08:17:21 +00:00
using ComponentFactory.Krypton.Toolkit ;
2020-10-19 08:50:42 +00:00
using MintPlayer.IconUtils ;
using System.Windows.Media.Imaging ;
2020-05-16 11:16:46 +00:00
namespace HeliosPlus
{
2020-05-17 09:19:55 +00:00
public enum ShortcutPermanence
{
Permanent ,
Temporary ,
}
public enum ShortcutCategory
{
Application ,
Game ,
2020-05-31 10:09:43 +00:00
NoGame ,
2020-05-17 09:19:55 +00:00
}
2020-10-11 05:11:08 +00:00
public struct StartProgram
{
public int Priority ;
public bool Enabled ;
public string Executable ;
public string Arguments ;
public bool ExecutableArgumentsRequired ;
public bool CloseOnFinish ;
}
2020-10-18 08:17:21 +00:00
public struct Executable
{
public string DifferentExecutableToMonitor ;
public string ExecutableNameAndPath ;
public uint ExecutableTimeout ;
public string ExecutableArguments ;
public bool ExecutableArgumentsRequired ;
public bool ProcessNameToMonitorUsesExecutable ;
}
public struct GameStruct
{
public Game GameToPlay ;
public uint StartTimeout ;
public string GameArguments ;
public bool GameArgumentsRequired ;
}
2020-06-07 08:48:45 +00:00
public class ShortcutItem
2020-05-16 11:16:46 +00:00
{
2020-06-01 10:25:52 +00:00
2020-07-23 23:06:33 +00:00
//private static List<ShortcutItem> _allSavedShortcuts = new List<ShortcutItem>();
//private MultiIcon _shortcutIcon, _originalIcon = null;
//private string _savedShortcutIconCacheFilename = "";
2020-10-18 08:17:21 +00:00
private string _profileUuid = "" ;
private ProfileItem _profileToUse ;
2020-07-23 23:06:33 +00:00
private string _uuid = "" ;
2020-06-15 09:57:46 +00:00
private string _name = "" ;
2020-10-18 08:17:21 +00:00
private ShortcutCategory _category = ShortcutCategory . NoGame ;
private string _differentExecutableToMonitor ;
private string _executableNameAndPath = "" ;
private string _executableArguments ;
private bool _executableArgumentsRequired ;
private bool _processNameToMonitorUsesExecutable ;
private uint _gameAppId ;
private string _gameName ;
private SupportedGameLibrary _gameLibrary ;
private uint _startTimeout ;
private string _gameArguments ;
private bool _gameArgumentsRequired ;
private ShortcutPermanence _permanence ;
private bool _autoName ;
private bool _isPossible ;
private List < StartProgram > _startPrograms ;
2020-10-18 10:04:08 +00:00
[JsonIgnore]
2020-10-18 08:17:21 +00:00
public string _originalIconPath ;
2020-10-19 08:50:42 +00:00
private Bitmap _shortcutBitmap , _originalLargeBitmap , _originalSmallBitmap ;
2020-10-18 10:04:08 +00:00
[JsonIgnore]
public string _savedShortcutIconCacheFilename ;
2020-10-18 08:17:21 +00:00
2020-05-16 11:16:46 +00:00
2020-06-07 08:48:45 +00:00
public ShortcutItem ( )
2020-05-17 09:19:55 +00:00
{
2020-10-18 08:17:21 +00:00
// Create a new UUID for the shortcut if one wasn't created already
if ( String . IsNullOrWhiteSpace ( _uuid ) )
_uuid = Guid . NewGuid ( ) . ToString ( "D" ) ;
// Autocreate a name for the shortcut if AutoName is on
// (and if we have a profile to use)
if ( AutoName & & _profileToUse is ProfileItem )
{
// If Autoname is on, and then lets autoname it!
// That populates all the right things
AutoSuggestShortcutName ( ) ;
}
}
public ShortcutItem (
string name ,
ProfileItem profile ,
uint gameAppId ,
string gameName ,
SupportedGameLibrary gameLibrary ,
uint gameTimeout ,
string gameArguments ,
bool gameArgumentsRequired ,
ShortcutPermanence permanence ,
string originalIconPath ,
List < StartProgram > startPrograms = null ,
bool autoName = true ,
string uuid = ""
) : this ( )
{
2020-10-18 10:04:08 +00:00
if ( ! String . IsNullOrWhiteSpace ( uuid ) )
_uuid = uuid ;
2020-10-18 08:17:21 +00:00
_name = name ;
_profileToUse = profile ;
_category = ShortcutCategory . Game ;
_profileToUse = profile ;
_gameAppId = gameAppId ;
_gameName = gameName ;
_gameLibrary = gameLibrary ;
_startTimeout = gameTimeout ;
_gameArguments = gameArguments ;
_gameArgumentsRequired = gameArgumentsRequired ;
_permanence = permanence ;
_autoName = autoName ;
_startPrograms = startPrograms ;
_originalIconPath = originalIconPath ;
// Now we need to find and populate the profileUuid
_profileUuid = profile . UUID ;
2020-10-19 08:50:42 +00:00
// We create the OriginalLargeBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap ( _originalIconPath ) ;
_originalSmallBitmap = ToSmallBitmap ( _originalIconPath ) ;
2020-10-18 10:04:08 +00:00
// We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile)
if ( _profileToUse is ProfileItem )
2020-10-19 08:50:42 +00:00
_shortcutBitmap = ToBitmapOverlay ( _originalLargeBitmap , _profileToUse . ProfileTightestBitmap , 256 , 256 ) ;
2020-10-18 10:04:08 +00:00
2020-05-17 09:19:55 +00:00
}
2020-10-18 08:17:21 +00:00
public ShortcutItem ( string name , ProfileItem profile , GameStruct game , ShortcutPermanence permanence , string originalIconPath ,
List < StartProgram > startPrograms = null , bool autoName = true , string uuid = "" ) : this ( )
2020-05-16 11:16:46 +00:00
{
2020-10-18 10:04:08 +00:00
// Create a new UUID for the shortcut if one wasn't created already
if ( ! String . IsNullOrWhiteSpace ( uuid ) )
_uuid = uuid ;
2020-10-18 08:17:21 +00:00
_name = name ;
_profileToUse = profile ;
_category = ShortcutCategory . Game ;
_gameAppId = game . GameToPlay . Id ;
_gameName = game . GameToPlay . Name ;
_gameLibrary = game . GameToPlay . GameLibrary ;
_startTimeout = game . StartTimeout ;
_gameArguments = game . GameArguments ;
_gameArgumentsRequired = game . GameArgumentsRequired ;
_permanence = permanence ;
_autoName = autoName ;
_startPrograms = startPrograms ;
_originalIconPath = originalIconPath ;
// Now we need to find and populate the profileUuid
_profileUuid = profile . UUID ;
2020-10-18 10:04:08 +00:00
// We create the OriginalBitmap from the IconPath
2020-10-19 08:50:42 +00:00
_originalLargeBitmap = ToLargeBitmap ( _originalIconPath ) ;
2020-10-18 10:04:08 +00:00
// We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile)
if ( _profileToUse is ProfileItem )
2020-10-19 08:50:42 +00:00
_shortcutBitmap = ToBitmapOverlay ( _originalLargeBitmap , _profileToUse . ProfileTightestBitmap , 256 , 256 ) ;
2020-10-18 08:17:21 +00:00
}
public ShortcutItem ( string name , string profileUuid , GameStruct game , ShortcutPermanence permanence , string originalIconPath ,
List < StartProgram > startPrograms = null , bool autoName = true , string uuid = "" ) : this ( )
{
2020-10-18 10:04:08 +00:00
if ( ! String . IsNullOrWhiteSpace ( uuid ) )
_uuid = uuid ;
2020-10-18 08:17:21 +00:00
_name = name ;
_profileUuid = profileUuid ;
_category = ShortcutCategory . Game ;
_gameAppId = game . GameToPlay . Id ;
_gameName = game . GameToPlay . Name ;
_gameLibrary = game . GameToPlay . GameLibrary ;
_startTimeout = game . StartTimeout ;
_gameArguments = game . GameArguments ;
_gameArgumentsRequired = game . GameArgumentsRequired ;
_gameArgumentsRequired = false ;
_permanence = permanence ;
_autoName = autoName ;
_startPrograms = startPrograms ;
_originalIconPath = originalIconPath ;
// Now we need to find and populate the profileToUse
foreach ( ProfileItem profileToTest in ProfileRepository . AllProfiles )
{
if ( profileToTest . UUID . Equals ( _profileUuid , StringComparison . InvariantCultureIgnoreCase ) )
{
_profileToUse = profileToTest ;
break ;
}
}
if ( _profileToUse = = null )
{
throw new Exception ( $"Trying to create a ShortcutItem and cannot find a loaded profile with UUID {uuid}." ) ;
}
2020-10-18 10:04:08 +00:00
// We create the OriginalBitmap from the IconPath
2020-10-19 08:50:42 +00:00
_originalLargeBitmap = ToLargeBitmap ( _originalIconPath ) ;
2020-10-18 10:04:08 +00:00
// We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile)
if ( _profileToUse is ProfileItem )
2020-10-19 08:50:42 +00:00
_shortcutBitmap = ToBitmapOverlay ( _originalLargeBitmap , _profileToUse . ProfileTightestBitmap , 256 , 256 ) ;
2020-10-18 08:17:21 +00:00
}
public ShortcutItem (
string name ,
ProfileItem profile ,
string differentExecutableToMonitor ,
string executableNameAndPath ,
uint executableTimeout ,
string executableArguments ,
bool executableArgumentsRequired ,
bool processNameToMonitorUsesExecutable ,
ShortcutPermanence permanence ,
string originalIconPath ,
List < StartProgram > startPrograms = null ,
bool autoName = true ,
string uuid = ""
) : this ( )
{
2020-10-18 10:04:08 +00:00
if ( ! String . IsNullOrWhiteSpace ( uuid ) )
_uuid = uuid ;
2020-10-18 08:17:21 +00:00
_name = name ;
_profileToUse = profile ;
_category = ShortcutCategory . Application ;
_differentExecutableToMonitor = differentExecutableToMonitor ;
_executableNameAndPath = executableNameAndPath ;
_startTimeout = executableTimeout ;
_executableArguments = executableArguments ;
_executableArgumentsRequired = executableArgumentsRequired ;
_processNameToMonitorUsesExecutable = processNameToMonitorUsesExecutable ;
_permanence = permanence ;
_autoName = autoName ;
_startPrograms = startPrograms ;
_originalIconPath = originalIconPath ;
// Now we need to find and populate the profileUuid
_profileUuid = profile . UUID ;
2020-10-18 10:04:08 +00:00
// We create the OriginalBitmap from the IconPath
2020-10-19 08:50:42 +00:00
_originalLargeBitmap = ToLargeBitmap ( _originalIconPath ) ;
2020-10-18 10:04:08 +00:00
// We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile)
2020-10-19 09:58:23 +00:00
//if (_profileToUse is ProfileItem)
// _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
_shortcutBitmap = ToBitmapOverlay ( _originalLargeBitmap , _profileToUse . ProfileTightestBitmap , 256 , 256 ) ;
2020-10-18 10:04:08 +00:00
2020-10-18 08:17:21 +00:00
}
public ShortcutItem ( string name , ProfileItem profile , Executable executable , ShortcutPermanence permanence , string originalIconPath ,
List < StartProgram > startPrograms = null , bool autoName = true , string uuid = "" ) : this ( )
{
2020-10-18 10:04:08 +00:00
if ( ! String . IsNullOrWhiteSpace ( uuid ) )
_uuid = uuid ;
2020-10-18 08:17:21 +00:00
_name = name ;
_profileToUse = profile ;
_category = ShortcutCategory . Application ;
_differentExecutableToMonitor = executable . DifferentExecutableToMonitor ;
_executableNameAndPath = executable . ExecutableNameAndPath ;
_startTimeout = executable . ExecutableTimeout ;
_executableArguments = executable . ExecutableArguments ;
_executableArgumentsRequired = executable . ExecutableArgumentsRequired ;
_processNameToMonitorUsesExecutable = executable . ProcessNameToMonitorUsesExecutable ;
_permanence = permanence ;
_autoName = autoName ;
_startPrograms = startPrograms ;
_originalIconPath = originalIconPath ;
// Now we need to find and populate the profileUuid
_profileUuid = profile . UUID ;
2020-10-18 10:04:08 +00:00
// We create the OriginalBitmap from the IconPath
2020-10-19 08:50:42 +00:00
_originalLargeBitmap = ToLargeBitmap ( _originalIconPath ) ;
2020-10-18 10:04:08 +00:00
// We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile)
2020-10-19 09:58:23 +00:00
//if (_profileToUse is ProfileItem)
// _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
_shortcutBitmap = ToBitmapOverlay ( _originalLargeBitmap , _profileToUse . ProfileTightestBitmap , 256 , 256 ) ;
2020-10-18 08:17:21 +00:00
}
public ShortcutItem ( string name , string profileUuid , Executable executable , ShortcutPermanence permanence , string originalIconPath ,
List < StartProgram > startPrograms = null , bool autoName = true , string uuid = "" ) : this ( )
{
2020-10-18 10:04:08 +00:00
if ( ! String . IsNullOrWhiteSpace ( uuid ) )
_uuid = uuid ;
2020-10-18 08:17:21 +00:00
_name = name ;
_profileUuid = profileUuid ;
_category = ShortcutCategory . Application ;
_differentExecutableToMonitor = executable . DifferentExecutableToMonitor ;
_executableNameAndPath = executable . ExecutableNameAndPath ;
_startTimeout = executable . ExecutableTimeout ;
_executableArguments = executable . ExecutableArguments ;
_executableArgumentsRequired = executable . ExecutableArgumentsRequired ;
_processNameToMonitorUsesExecutable = executable . ProcessNameToMonitorUsesExecutable ;
_permanence = permanence ;
_autoName = autoName ;
_startPrograms = startPrograms ;
_originalIconPath = originalIconPath ;
// Now we need to find and populate the profileToUse
foreach ( ProfileItem profileToTest in ProfileRepository . AllProfiles )
{
if ( profileToTest . UUID . Equals ( _profileUuid , StringComparison . InvariantCultureIgnoreCase ) )
{
_profileToUse = profileToTest ;
break ;
}
}
if ( _profileToUse = = null )
{
throw new Exception ( $"Trying to create a ShortcutItem and cannot find a loaded profile with UUID {uuid}." ) ;
}
2020-10-18 10:04:08 +00:00
// We create the OriginalBitmap from the IconPath
2020-10-19 09:58:23 +00:00
if ( _originalIconPath . EndsWith ( ".ico" ) )
{
Icon icoIcon = new Icon ( _originalIconPath , 256 , 256 ) ;
//_originalBitmap = ExtractVistaIcon(biggestIcon);
_originalLargeBitmap = icoIcon . ToBitmap ( ) ;
icoIcon . Dispose ( ) ;
}
else
{
_originalLargeBitmap = ToLargeBitmap ( _originalIconPath ) ;
}
2020-10-19 08:50:42 +00:00
_originalLargeBitmap = ToLargeBitmap ( _originalIconPath ) ;
2020-10-18 10:04:08 +00:00
// We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile)
2020-10-19 09:58:23 +00:00
//if (_profileToUse is ProfileItem)
// _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
_shortcutBitmap = ToBitmapOverlay ( _originalLargeBitmap , _profileToUse . ProfileTightestBitmap , 256 , 256 ) ;
2020-05-16 11:16:46 +00:00
}
2020-10-18 08:17:21 +00:00
2020-07-23 23:06:33 +00:00
public static Version Version
{
get = > new Version ( 1 , 0 ) ;
}
2020-05-16 11:16:46 +00:00
2020-06-15 09:57:46 +00:00
public string UUID
2020-06-01 10:25:52 +00:00
{
get
{
2020-06-15 09:57:46 +00:00
return _uuid ;
2020-06-01 10:25:52 +00:00
}
set
{
2020-08-18 22:16:04 +00:00
string uuidV4Regex = @"[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}" ;
2020-06-15 09:57:46 +00:00
Match match = Regex . Match ( value , uuidV4Regex , RegexOptions . IgnoreCase ) ;
if ( match . Success )
_uuid = value ;
2020-06-01 10:25:52 +00:00
}
}
2020-06-15 09:57:46 +00:00
public string Name
{
get
{
return _name ;
}
set
{
_name = value ;
}
}
2020-10-18 08:17:21 +00:00
public bool AutoName
{
get
{
return _autoName ;
}
set
{
_autoName = value ;
}
}
2020-06-15 09:57:46 +00:00
2020-05-16 11:16:46 +00:00
2020-05-17 09:19:55 +00:00
[JsonIgnore]
2020-06-07 08:48:45 +00:00
public ProfileItem ProfileToUse {
get
{
return _profileToUse ;
}
set
{
if ( value is ProfileItem )
{
_profileToUse = value ;
2020-06-15 09:57:46 +00:00
_profileUuid = _profileToUse . UUID ;
2020-10-18 08:17:21 +00:00
// We should try to set the Profile
2020-06-15 09:57:46 +00:00
// And we rename the shortcut if the AutoName is on
if ( AutoName )
AutoSuggestShortcutName ( ) ;
2020-06-07 08:48:45 +00:00
}
}
}
2020-05-16 11:16:46 +00:00
2020-06-15 09:57:46 +00:00
public string ProfileUUID {
2020-05-17 09:19:55 +00:00
get
{
2020-06-15 09:57:46 +00:00
return _profileUuid ;
2020-05-19 09:41:26 +00:00
}
set
{
2020-06-15 09:57:46 +00:00
_profileUuid = value ;
2020-06-07 08:48:45 +00:00
// We try to find and set the ProfileTouse
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem profileToTest in ProfileRepository . AllProfiles )
2020-06-07 08:48:45 +00:00
{
2020-07-23 23:06:33 +00:00
if ( profileToTest . UUID . Equals ( _profileUuid , StringComparison . InvariantCultureIgnoreCase ) )
2020-06-07 08:48:45 +00:00
_profileToUse = profileToTest ;
}
2020-05-19 09:41:26 +00:00
}
2020-05-17 09:19:55 +00:00
}
2020-10-18 08:17:21 +00:00
public ShortcutPermanence Permanence
{
get
{
return _permanence ;
}
2020-05-17 09:19:55 +00:00
2020-10-18 08:17:21 +00:00
set
{
_permanence = value ;
}
}
2020-05-17 09:19:55 +00:00
2020-10-18 08:17:21 +00:00
public ShortcutCategory Category
{
get
{
return _category ;
}
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
set
{
_category = value ;
}
}
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
public string DifferentExecutableToMonitor
{
get
{
return _differentExecutableToMonitor ;
}
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
set
{
_differentExecutableToMonitor = value ;
}
}
public string ExecutableNameAndPath
{
get
{
return _executableNameAndPath ;
}
set
{
_executableNameAndPath = value ;
// If the executableNameandPath is set then we also want to update the originalIconPath
// so it's the path to the application. This will kick of the icon grabbing processes
2020-10-18 10:04:08 +00:00
if ( Category . Equals ( ShortcutCategory . Application ) )
_originalIconPath = value ;
2020-10-18 08:17:21 +00:00
}
}
public string ExecutableArguments
{
get
{
return _executableArguments ;
}
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
set
{
_executableArguments = value ;
}
}
2020-05-17 09:19:55 +00:00
2020-10-18 08:17:21 +00:00
public bool ExecutableArgumentsRequired
{
get
{
return _executableArgumentsRequired ;
}
2020-05-17 09:19:55 +00:00
2020-10-18 08:17:21 +00:00
set
{
_executableArgumentsRequired = value ;
}
}
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
public bool ProcessNameToMonitorUsesExecutable
{
get
{
return _processNameToMonitorUsesExecutable ;
}
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
set
{
_processNameToMonitorUsesExecutable = value ;
}
}
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
public uint GameAppId
{
get
{
return _gameAppId ;
}
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
set
{
_gameAppId = value ;
}
}
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
public string GameName
{
get
{
return _gameName ;
}
2020-05-17 09:19:55 +00:00
2020-10-18 08:17:21 +00:00
set
{
_gameName = value ;
}
}
2020-10-11 05:11:08 +00:00
2020-10-18 08:17:21 +00:00
public SupportedGameLibrary GameLibrary
{
2020-06-07 08:48:45 +00:00
get
{
2020-10-18 08:17:21 +00:00
return _gameLibrary ;
}
2020-10-18 08:02:00 +00:00
2020-10-18 08:17:21 +00:00
set
{
_gameLibrary = value ;
}
}
public uint StartTimeout
{
get
{
return _startTimeout ;
2020-06-07 08:48:45 +00:00
}
set
{
2020-10-18 08:17:21 +00:00
_startTimeout = value ;
}
}
2020-10-13 09:32:41 +00:00
2020-10-18 08:17:21 +00:00
public string GameArguments
{
get
{
return _gameArguments ;
}
2020-06-07 08:48:45 +00:00
2020-10-18 08:17:21 +00:00
set
{
_gameArguments = value ;
}
}
2020-10-18 08:02:00 +00:00
2020-10-18 08:17:21 +00:00
public bool GameArgumentsRequired
{
get
{
return _gameArgumentsRequired ;
}
set
{
_gameArgumentsRequired = value ;
2020-06-07 08:48:45 +00:00
}
}
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
public List < StartProgram > StartPrograms
2020-05-16 11:16:46 +00:00
{
get
{
2020-10-18 08:17:21 +00:00
return _startPrograms ;
}
2020-06-07 08:48:45 +00:00
2020-10-18 08:17:21 +00:00
set
{
_startPrograms = value ;
}
}
2020-10-13 09:32:41 +00:00
2020-10-18 08:17:21 +00:00
public string OriginalIconPath {
get
{
return _originalIconPath ;
2020-05-16 11:16:46 +00:00
}
set
{
2020-10-18 08:17:21 +00:00
_originalIconPath = value ;
// And we do the same for the OriginalBitmap
2020-10-19 09:58:23 +00:00
//_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
2020-05-16 11:16:46 +00:00
}
}
2020-06-15 09:57:46 +00:00
[JsonConverter(typeof(CustomBitmapConverter))]
2020-10-19 08:50:42 +00:00
public Bitmap OriginalLargeBitmap
2020-05-16 11:16:46 +00:00
{
get
{
2020-10-19 08:50:42 +00:00
return _originalLargeBitmap ;
2020-10-18 08:17:21 +00:00
}
2020-05-19 09:41:26 +00:00
2020-10-18 08:17:21 +00:00
set
{
2020-10-19 08:50:42 +00:00
_originalLargeBitmap = value ;
2020-05-16 11:16:46 +00:00
2020-10-18 08:17:21 +00:00
// And we do the same for the Bitmap overlay, but only if the ProfileToUse is set
2020-10-19 09:58:23 +00:00
//if (_profileToUse is ProfileItem)
// _shortcutBitmap = ToBitmapOverlay(_originalLargeBitmap, _profileToUse.ProfileTightestBitmap, 256, 256);
2020-10-18 08:02:00 +00:00
2020-10-18 08:17:21 +00:00
}
}
[JsonConverter(typeof(CustomBitmapConverter))]
public Bitmap ShortcutBitmap
{
get
{
return _shortcutBitmap ;
2020-05-16 11:16:46 +00:00
}
set
{
2020-10-18 08:17:21 +00:00
_shortcutBitmap = value ;
2020-05-16 11:16:46 +00:00
}
}
2020-10-18 10:04:08 +00:00
public string SavedShortcutIconCacheFilename
{
get
{
return _savedShortcutIconCacheFilename ;
}
set
{
_savedShortcutIconCacheFilename = value ;
}
}
2020-05-16 11:16:46 +00:00
[JsonIgnore]
public bool IsPossible
{
2020-05-19 09:41:26 +00:00
get
{
return _isPossible ;
}
set
{
_isPossible = value ;
2020-06-01 10:25:52 +00:00
}
2020-05-16 11:16:46 +00:00
}
2020-06-15 09:57:46 +00:00
public bool CopyTo ( ShortcutItem shortcut , bool overwriteUUID = false )
2020-06-01 10:25:52 +00:00
{
2020-06-07 08:48:45 +00:00
if ( ! ( shortcut is ShortcutItem ) )
2020-06-01 10:25:52 +00:00
return false ;
2020-06-15 09:57:46 +00:00
if ( overwriteUUID )
shortcut . UUID = UUID ;
2020-06-01 10:25:52 +00:00
// Copy all the shortcut data over to the other Shortcut
shortcut . Name = Name ;
shortcut . ProfileToUse = ProfileToUse ;
2020-06-15 09:57:46 +00:00
shortcut . ProfileUUID = ProfileUUID ;
2020-06-01 10:25:52 +00:00
shortcut . Permanence = Permanence ;
shortcut . Category = Category ;
shortcut . DifferentExecutableToMonitor = DifferentExecutableToMonitor ;
shortcut . ExecutableNameAndPath = ExecutableNameAndPath ;
shortcut . ExecutableArguments = ExecutableArguments ;
shortcut . ExecutableArgumentsRequired = ExecutableArgumentsRequired ;
shortcut . ProcessNameToMonitorUsesExecutable = ProcessNameToMonitorUsesExecutable ;
shortcut . GameAppId = GameAppId ;
shortcut . GameName = GameName ;
shortcut . GameLibrary = GameLibrary ;
2020-10-18 08:17:21 +00:00
shortcut . StartTimeout = StartTimeout ;
2020-06-01 10:25:52 +00:00
shortcut . GameArguments = GameArguments ;
shortcut . GameArgumentsRequired = GameArgumentsRequired ;
shortcut . OriginalIconPath = OriginalIconPath ;
2020-10-19 08:50:42 +00:00
shortcut . OriginalLargeBitmap = OriginalLargeBitmap ;
2020-06-01 10:25:52 +00:00
shortcut . ShortcutBitmap = ShortcutBitmap ;
shortcut . SavedShortcutIconCacheFilename = SavedShortcutIconCacheFilename ;
shortcut . IsPossible = IsPossible ;
2020-10-11 05:21:06 +00:00
shortcut . StartPrograms = StartPrograms ;
2020-06-01 10:25:52 +00:00
return true ;
}
2020-10-18 10:04:08 +00:00
public void SaveShortcutIconToCache ( )
{
// Only add this set of options if the shortcut is to an standalone application
if ( _category = = ShortcutCategory . Application )
{
// Work out the name of the shortcut we'll save.
_savedShortcutIconCacheFilename = Path . Combine ( Program . AppShortcutPath , String . Concat ( @"executable-" , _profileToUse . UUID , "-" , Path . GetFileNameWithoutExtension ( _executableNameAndPath ) , @".ico" ) ) ;
}
else
{
// Work out the name of the shortcut we'll save.
_savedShortcutIconCacheFilename = Path . Combine ( Program . AppShortcutPath , String . Concat ( _gameLibrary . ToString ( ) . ToLower ( CultureInfo . InvariantCulture ) , @"-" , _profileToUse . UUID , "-" , _gameAppId . ToString ( ) , @".ico" ) ) ;
}
MultiIcon shortcutIcon ;
try
{
//shortcutIcon = new ProfileIcon(shortcut.ProfileToUse).ToIconOverlay(shortcut.OriginalIconPath);
shortcutIcon = ToIconOverlay ( ) ;
shortcutIcon . Save ( _savedShortcutIconCacheFilename , MultiIconFormat . ICO ) ;
}
catch ( Exception ex )
{
Console . WriteLine ( $"ShortcutRepository/SaveShortcutIconToCache exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
// If we fail to create an icon based on the original executable or game
// Then we use the standard HeliosPlus profile one.
shortcutIcon = _profileToUse . ProfileIcon . ToIcon ( ) ;
shortcutIcon . Save ( _savedShortcutIconCacheFilename , MultiIconFormat . ICO ) ;
}
}
2020-10-19 08:50:42 +00:00
/ * public static Bitmap ExtractVistaIcon ( Icon icoIcon )
2020-05-16 11:16:46 +00:00
{
Bitmap bmpPngExtracted = null ;
try
{
byte [ ] srcBuf = null ;
using ( System . IO . MemoryStream stream = new System . IO . MemoryStream ( ) )
{ icoIcon . Save ( stream ) ; srcBuf = stream . ToArray ( ) ; }
const int SizeICONDIR = 6 ;
const int SizeICONDIRENTRY = 16 ;
int iCount = BitConverter . ToInt16 ( srcBuf , 4 ) ;
for ( int iIndex = 0 ; iIndex < iCount ; iIndex + + )
{
int iWidth = srcBuf [ SizeICONDIR + SizeICONDIRENTRY * iIndex ] ;
int iHeight = srcBuf [ SizeICONDIR + SizeICONDIRENTRY * iIndex + 1 ] ;
int iBitCount = BitConverter . ToInt16 ( srcBuf , SizeICONDIR + SizeICONDIRENTRY * iIndex + 6 ) ;
if ( iWidth = = 0 & & iHeight = = 0 & & iBitCount = = 32 )
{
int iImageSize = BitConverter . ToInt32 ( srcBuf , SizeICONDIR + SizeICONDIRENTRY * iIndex + 8 ) ;
int iImageOffset = BitConverter . ToInt32 ( srcBuf , SizeICONDIR + SizeICONDIRENTRY * iIndex + 12 ) ;
System . IO . MemoryStream destStream = new System . IO . MemoryStream ( ) ;
System . IO . BinaryWriter writer = new System . IO . BinaryWriter ( destStream ) ;
writer . Write ( srcBuf , iImageOffset , iImageSize ) ;
destStream . Seek ( 0 , System . IO . SeekOrigin . Begin ) ;
bmpPngExtracted = new Bitmap ( destStream ) ; // This is PNG! :)
break ;
}
}
}
2020-07-15 08:11:38 +00:00
catch ( Exception ex )
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"ShortcutItem/ExtractVisataIcon exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-07-15 08:11:38 +00:00
return null ;
}
2020-05-16 11:16:46 +00:00
return bmpPngExtracted ;
2020-10-19 08:50:42 +00:00
} * /
2020-05-16 11:16:46 +00:00
2020-06-07 08:48:45 +00:00
/ * public Bitmap ToBitmap ( int width = 256 , int height = 256 , PixelFormat format = PixelFormat . Format32bppArgb )
{
var bitmap = new Bitmap ( width , height , format ) ;
bitmap . MakeTransparent ( ) ;
using ( var g = Graphics . FromImage ( bitmap ) )
{
g . SmoothingMode = SmoothingMode . HighQuality ;
g . DrawImage ( g , width , height ) ;
}
return bitmap ;
} * /
2020-10-19 08:50:42 +00:00
private const string Shell32 = "shell32.dll" ;
/ * private Bitmap ToBitmapFromExe ( string fileNameAndPath )
2020-06-07 08:48:45 +00:00
{
2020-06-13 09:06:42 +00:00
if ( String . IsNullOrWhiteSpace ( fileNameAndPath ) )
return null ;
2020-10-19 08:50:42 +00:00
* //*IconActions ia = new IconActions();
int index = 0 ;
var sb = new StringBuilder ( fileNameAndPath , 500 ) ;
IconReference iconReference = new IconReference ( sb . ToString ( ) , index ) ;
var largeIcons = new IntPtr [ 1 ] ;
var smallIcons = new IntPtr [ 1 ] ;
ia . ExtractIcon ( iconReference . FilePath , iconReference . IconIndex , largeIcons , smallIcons , 1 ) ;
System . Windows .
BitmapSource bitmapSource ;
try
{
bitmapSource = Imaging . CreateBitmapSourceFromHIcon ( largeIcons [ 0 ] , Int32Rect . Empty , BitmapSizeOptions . FromEmptyOptions ( ) ) ;
}
catch
{
return null ;
}
ia . DestroyIconAtHandle ( largeIcons [ 0 ] ) ;
ia . DestroyIconAtHandle ( smallIcons [ 0 ] ) ;
return bitmapSource ;
* //*
//IconFromFile iconFromFile = new IconFromFile();
Bitmap bm = IconFromFile . GetLargeBitmapFromFile ( fileNameAndPath , true , true ) ;
return bm ;
//var icons = MintPlayer.IconUtils.IconExtractor.Split(fileNameAndPath);
* //*var folder = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(fileNameAndPath), "Split");
if ( ! System . IO . Directory . Exists ( folder ) ) System . IO . Directory . CreateDirectory ( folder ) ;
var index = 1 ;
foreach ( var icon in icons )
{
var filename = System . IO . Path . Combine ( folder , "icon_" + ( index + + ) . ToString ( ) + ".ico" ) ;
using ( var fs = new System . IO . FileStream ( filename , System . IO . FileMode . Create , System . IO . FileAccess . ReadWrite ) )
{
icon . Save ( fs ) ;
}
}
* //*
Icon ExeIcon = ExtractIcon . ExtractIconFromExecutable ( fileNameAndPath ) ;
FileStream fs = new FileStream ( fileNameAndPath , FileMode . Open , FileAccess . Read , FileShare . Read ) ;
MultiIcon mi = new MultiIcon ( ) ;
mi . Load ( fs ) ;
int count = mi . Count ;
TsudaKageyu . IconExtractor ie = new TsudaKageyu . IconExtractor ( fileNameAndPath ) ;
Icon [ ] allIcons = ie . GetAllIcons ( ) ;
Icon biggestIcon = allIcons . OrderByDescending ( item = > item . Size ) . First ( ) ;
//_originalBitmap = ExtractVistaIcon(biggestIcon);
Bitmap bitmapToReturn = IconUtil . ToBitmap ( biggestIcon ) ;
if ( bitmapToReturn = = null )
bitmapToReturn = biggestIcon . ToBitmap ( ) ;
// Only gets the 32x32 icon!
//Icon exeIcon = IconUtils.ExtractIcon.ExtractIconFromExecutable(fileNameAndPath);
//Bitmap bitmapToReturn = exeIcon.ToBitmap();
//exeIcon.Dispose();
2020-06-07 08:48:45 +00:00
return bitmapToReturn ;
2020-10-19 08:50:42 +00:00
} * /
2020-06-07 08:48:45 +00:00
2020-10-19 08:50:42 +00:00
/ * public static BitmapSource ConvertBitmap ( Bitmap source )
{
return System . Windows . Interop . Imaging . CreateBitmapSourceFromHBitmap (
source . GetHbitmap ( ) ,
IntPtr . Zero ,
Int32Rect . Empty ,
BitmapSizeOptions . FromEmptyOptions ( ) ) ;
} * /
/ * public static Bitmap BitmapFromSource ( BitmapSource bitmapsource )
{
Bitmap bitmap ;
using ( var outStream = new MemoryStream ( ) )
{
BitmapEncoder enc = new BmpBitmapEncoder ( ) ;
enc . Frames . Add ( BitmapFrame . Create ( bitmapsource ) ) ;
enc . Save ( outStream ) ;
bitmap = new Bitmap ( outStream ) ;
}
return bitmap ;
} * /
2020-10-19 09:58:23 +00:00
/ *
public Bitmap ToBitmapFromIcon ( string fileNameAndPath )
2020-06-07 08:48:45 +00:00
{
2020-06-13 09:06:42 +00:00
if ( String . IsNullOrWhiteSpace ( fileNameAndPath ) )
return null ;
2020-06-07 08:48:45 +00:00
Icon icoIcon = new Icon ( fileNameAndPath , 256 , 256 ) ;
//_originalBitmap = ExtractVistaIcon(biggestIcon);
Bitmap bitmapToReturn = icoIcon . ToBitmap ( ) ;
icoIcon . Dispose ( ) ;
return bitmapToReturn ;
2020-10-19 08:50:42 +00:00
} * /
2020-10-19 09:58:23 +00:00
public static Bitmap ToLargeBitmap ( string fileNameAndPath )
2020-10-19 08:50:42 +00:00
{
if ( String . IsNullOrWhiteSpace ( fileNameAndPath ) )
return null ;
2020-10-19 09:58:23 +00:00
Bitmap bm = null
; if ( fileNameAndPath . EndsWith ( ".ico" ) )
{
Icon icoIcon = new Icon ( fileNameAndPath , 256 , 256 ) ;
bm = icoIcon . ToBitmap ( ) ;
icoIcon . Dispose ( ) ;
}
else
{
bm = IconFromFile . GetLargeBitmapFromFile ( fileNameAndPath , true , true ) ;
}
2020-10-19 08:50:42 +00:00
return bm ;
2020-06-07 08:48:45 +00:00
}
2020-10-19 09:58:23 +00:00
public static Bitmap ToSmallBitmap ( string fileNameAndPath )
2020-06-13 09:06:42 +00:00
{
if ( String . IsNullOrWhiteSpace ( fileNameAndPath ) )
return null ;
2020-06-07 08:48:45 +00:00
2020-10-19 09:58:23 +00:00
Bitmap bm = null ;
if ( fileNameAndPath . EndsWith ( ".ico" ) )
{
Icon icoIcon = new Icon ( fileNameAndPath , 128 , 128 ) ;
bm = icoIcon . ToBitmap ( ) ;
icoIcon . Dispose ( ) ;
}
else
{
bm = IconFromFile . GetSmallBitmapFromFile ( fileNameAndPath , false , true , false ) ;
}
2020-10-19 08:50:42 +00:00
return bm ;
2020-06-13 09:06:42 +00:00
}
2020-10-19 08:50:42 +00:00
2020-06-13 09:06:42 +00:00
public Bitmap ToBitmapOverlay ( Bitmap originalBitmap , Bitmap overlayBitmap , int width , int height , PixelFormat format = PixelFormat . Format32bppArgb )
2020-06-07 08:48:45 +00:00
{
if ( ! ( width is int ) | | width < = 0 )
return null ;
if ( ! ( height is int ) | | height < = 0 )
return null ;
2020-06-13 09:06:42 +00:00
// Figure out sizes and positions
Size targetSize = new Size ( width , height ) ;
Size originalBitmapCurrentSize = new Size ( originalBitmap . Width , originalBitmap . Height ) ;
Size overlaylBitmapCurrentSize = new Size ( overlayBitmap . Width , overlayBitmap . Height ) ;
// Make a new empty bitmap of the wanted size
var combinedBitmap = new Bitmap ( targetSize . Width , targetSize . Height , format ) ;
2020-06-07 08:48:45 +00:00
combinedBitmap . MakeTransparent ( ) ;
using ( var g = Graphics . FromImage ( combinedBitmap ) )
{
g . SmoothingMode = SmoothingMode . None ;
g . InterpolationMode = InterpolationMode . NearestNeighbor ;
g . PixelOffsetMode = PixelOffsetMode . HighQuality ;
g . CompositingQuality = CompositingQuality . AssumeLinear ;
2020-06-13 09:06:42 +00:00
// Resize the originalBitmap if needed then draw it
Size originalBitmapNewSize = ResizeDrawing . FitWithin ( originalBitmapCurrentSize , targetSize ) ;
Point originalBitmapNewLocation = ResizeDrawing . AlignCenter ( originalBitmapNewSize , targetSize ) ;
g . DrawImage ( originalBitmap , originalBitmapNewLocation . X , originalBitmapNewLocation . Y , originalBitmapNewSize . Width , originalBitmapNewSize . Height ) ;
2020-06-07 08:48:45 +00:00
2020-06-13 09:06:42 +00:00
// Resize the overlayBitmap if needed then draw it in the bottom-right corner
Size overlayBitmapMaxSize = ResizeDrawing . FitWithin ( overlaylBitmapCurrentSize , targetSize ) ;
Size overlayBitmapNewSize = ResizeDrawing . MakeSmaller ( overlayBitmapMaxSize , 70 ) ;
Point overlayBitmapNewLocation = ResizeDrawing . AlignBottomRight ( overlayBitmapNewSize , targetSize ) ;
2020-06-07 08:48:45 +00:00
2020-06-13 09:06:42 +00:00
g . DrawImage ( overlayBitmap , overlayBitmapNewLocation . X , overlayBitmapNewLocation . Y , overlayBitmapNewSize . Width , overlayBitmapNewSize . Height ) ;
2020-06-07 08:48:45 +00:00
}
return combinedBitmap ;
}
2020-10-19 08:50:42 +00:00
/ * public MultiIcon ToIcon ( )
2020-06-07 08:48:45 +00:00
{
var iconSizes = new [ ]
{
new Size ( 256 , 256 ) ,
new Size ( 64 , 64 ) ,
new Size ( 48 , 48 ) ,
new Size ( 32 , 32 ) ,
new Size ( 24 , 24 ) ,
new Size ( 16 , 16 )
} ;
var multiIcon = new MultiIcon ( ) ;
var icon = multiIcon . Add ( "Icon1" ) ;
foreach ( var size in iconSizes )
{
Bitmap bitmap = new Bitmap ( size . Width , size . Height ) ;
using ( var g = Graphics . FromImage ( bitmap ) )
{
g . SmoothingMode = SmoothingMode . None ;
g . InterpolationMode = InterpolationMode . NearestNeighbor ;
g . PixelOffsetMode = PixelOffsetMode . HighQuality ;
g . CompositingQuality = CompositingQuality . AssumeLinear ;
2020-10-19 08:50:42 +00:00
g . DrawImage ( _originalLargeBitmap , new Rectangle ( 0 , 0 , size . Width , size . Height ) ) ;
2020-06-07 08:48:45 +00:00
}
icon . Add ( bitmap ) ;
if ( size . Width > = 256 & & size . Height > = 256 )
{
icon [ icon . Count - 1 ] . IconImageFormat = IconImageFormat . PNG ;
}
bitmap . Dispose ( ) ;
}
multiIcon . SelectedIndex = 0 ;
return multiIcon ;
2020-10-19 08:50:42 +00:00
} * /
2020-06-07 08:48:45 +00:00
public MultiIcon ToIconOverlay ( )
{
var iconSizes = new [ ]
{
new Size ( 256 , 256 ) ,
new Size ( 64 , 64 ) ,
new Size ( 48 , 48 ) ,
new Size ( 32 , 32 ) ,
new Size ( 24 , 24 ) ,
new Size ( 16 , 16 )
} ;
var multiIcon = new MultiIcon ( ) ;
var icon = multiIcon . Add ( "Icon1" ) ;
foreach ( var size in iconSizes )
{
2020-10-19 08:50:42 +00:00
Bitmap bitmapOverlay = ToBitmapOverlay ( _originalLargeBitmap , ProfileToUse . ProfileTightestBitmap , size . Width , size . Height ) ;
2020-06-07 08:48:45 +00:00
icon . Add ( bitmapOverlay ) ;
if ( size . Width > = 256 & & size . Height > = 256 )
{
icon [ icon . Count - 1 ] . IconImageFormat = IconImageFormat . PNG ;
}
bitmapOverlay . Dispose ( ) ;
}
multiIcon . SelectedIndex = 0 ;
return multiIcon ;
}
2020-05-16 11:16:46 +00:00
2020-10-19 08:50:42 +00:00
/ * internal static class ExtractIcon
{
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true, CharSet = CharSet.Unicode)]
//[SuppressUnmanagedCodeSecurity]
internal delegate bool ENUMRESNAMEPROC ( IntPtr hModule , IntPtr lpszType , IntPtr lpszName , IntPtr lParam ) ;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibraryEx ( string lpFileName , IntPtr hFile , uint dwFlags ) ;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr FindResource ( IntPtr hModule , IntPtr lpName , IntPtr lpType ) ;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadResource ( IntPtr hModule , IntPtr hResInfo ) ;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LockResource ( IntPtr hResData ) ;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SizeofResource ( IntPtr hModule , IntPtr hResInfo ) ;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
//[SuppressUnmanagedCodeSecurity]
public static extern bool EnumResourceNames ( IntPtr hModule , IntPtr lpszType , ENUMRESNAMEPROC lpEnumFunc , IntPtr lParam ) ;
private const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002 ;
private readonly static IntPtr RT_ICON = ( IntPtr ) 3 ;
private readonly static IntPtr RT_GROUP_ICON = ( IntPtr ) 14 ;
public static Icon ExtractIconFromExecutable ( string path )
{
IntPtr hModule = LoadLibraryEx ( path , IntPtr . Zero , LOAD_LIBRARY_AS_DATAFILE ) ;
var tmpData = new List < byte [ ] > ( ) ;
ENUMRESNAMEPROC callback = ( h , t , name , l ) = >
{
var dir = GetDataFromResource ( hModule , RT_GROUP_ICON , name ) ;
// Calculate the size of an entire .icon file.
int count = BitConverter . ToUInt16 ( dir , 4 ) ; // GRPICONDIR.idCount
int len = 6 + 16 * count ; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY) * count
for ( int i = 0 ; i < count ; + + i )
len + = BitConverter . ToInt32 ( dir , 6 + 14 * i + 8 ) ; // GRPICONDIRENTRY.dwBytesInRes
using ( var dst = new BinaryWriter ( new MemoryStream ( len ) ) )
{
// Copy GRPICONDIR to ICONDIR.
dst . Write ( dir , 0 , 6 ) ;
int picOffset = 6 + 16 * count ; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY) * count
for ( int i = 0 ; i < count ; + + i )
{
// Load the picture.
ushort id = BitConverter . ToUInt16 ( dir , 6 + 14 * i + 12 ) ; // GRPICONDIRENTRY.nID
var pic = GetDataFromResource ( hModule , RT_ICON , ( IntPtr ) id ) ;
// Copy GRPICONDIRENTRY to ICONDIRENTRY.
dst . Seek ( 6 + 16 * i , 0 ) ;
dst . Write ( dir , 6 + 14 * i , 8 ) ; // First 8bytes are identical.
dst . Write ( pic . Length ) ; // ICONDIRENTRY.dwBytesInRes
dst . Write ( picOffset ) ; // ICONDIRENTRY.dwImageOffset
// Copy a picture.
dst . Seek ( picOffset , 0 ) ;
dst . Write ( pic , 0 , pic . Length ) ;
picOffset + = pic . Length ;
}
tmpData . Add ( ( ( MemoryStream ) dst . BaseStream ) . ToArray ( ) ) ;
}
return true ;
} ;
EnumResourceNames ( hModule , RT_GROUP_ICON , callback , IntPtr . Zero ) ;
byte [ ] [ ] iconData = tmpData . ToArray ( ) ;
using ( var ms = new MemoryStream ( iconData [ 0 ] ) )
{
return new Icon ( ms ) ;
}
}
private static byte [ ] GetDataFromResource ( IntPtr hModule , IntPtr type , IntPtr name )
{
// Load the binary data from the specified resource.
IntPtr hResInfo = FindResource ( hModule , name , type ) ;
IntPtr hResData = LoadResource ( hModule , hResInfo ) ;
IntPtr pResData = LockResource ( hResData ) ;
uint size = SizeofResource ( hModule , hResInfo ) ;
byte [ ] buf = new byte [ size ] ;
Marshal . Copy ( pResData , buf , 0 , buf . Length ) ;
return buf ;
}
}
* /
2020-07-21 11:40:33 +00:00
public ( bool , string ) IsValid ( )
{
// Do some validation checks to make sure the shortcut is sensible
// And that we have enough to try and action within the shortcut
// (in other words check everything in the shortcut is still valid)
// Does the profile we want to Use still exist?
// Is the profile still valid right now? i.e. are all the screens available?
if ( ! ProfileToUse . IsPossible )
{
return ( false , string . Format ( "The profile '{0}' is not valid right now and cannot be used." , ProfileToUse . Name ) ) ;
}
// Is the main application still installed?
if ( Category . Equals ( ShortcutCategory . Application ) )
{
// We need to check if the Application still exists
if ( ! System . IO . File . Exists ( ExecutableNameAndPath ) )
{
return ( false , string . Format ( "The application executable '{0}' does not exist, or cannot be accessed by HeliosPlus." , ExecutableNameAndPath ) ) ;
}
} else if ( Category . Equals ( ShortcutCategory . Game ) )
{
// If the game is a Steam Game we check for that
if ( GameLibrary . Equals ( SupportedGameLibrary . Steam ) )
{
// First check if Steam is installed
// Check if Steam is installed and error if it isn't
if ( ! SteamLibrary . IsSteamInstalled )
{
return ( false , Language . Steam_executable_file_not_found ) ;
}
// We need to look up details about the game
if ( ! SteamLibrary . ContainsSteamGame ( GameAppId ) )
{
return ( false , string . Format ( "The Steam Game with AppID '{0}' is not installed on this computer." , GameAppId ) ) ;
}
}
// If the game is a Uplay Game we check for that
/ * else if ( GameLibrary . Equals ( SupportedGameLibrary . Uplay ) )
{
// We need to look up details about the game
if ( ! UplayGame . IsInstalled ( GameAppId ) )
{
return ( false , string . Format ( "The Uplay Game with AppID '{0}' is not installed on this computer." , GameAppId ) ) ;
}
} * /
}
// Do all the specified pre-start apps still exist?
return ( true , "Shortcut is valid" ) ;
}
2020-05-17 09:19:55 +00:00
// ReSharper disable once FunctionComplexityOverflow
// ReSharper disable once CyclomaticComplexity
public bool CreateShortcut ( string shortcutFileName )
2020-05-16 11:16:46 +00:00
{
2020-05-17 09:19:55 +00:00
string programName = Path . GetFileNameWithoutExtension ( ExecutableNameAndPath ) ;
string shortcutDescription = string . Empty ;
string shortcutIconFileName = string . Empty ;
var shortcutArgs = new List < string >
{
// Add the SwitchProfile command as the first argument to start to switch to another profile
2020-10-11 08:12:52 +00:00
$"{HeliosStartupAction.RunShortcut}" ,
2020-07-21 11:40:33 +00:00
$"\" { UUID } \ ""
2020-05-17 09:19:55 +00:00
} ;
// Only add the rest of the options if the permanence is temporary
if ( Permanence = = ShortcutPermanence . Temporary )
2020-05-16 11:16:46 +00:00
{
2020-05-17 09:19:55 +00:00
// Only add this set of options if the shortcut is to an standalone application
if ( Category = = ShortcutCategory . Application )
{
// Prepare text for the shortcut description field
2020-07-21 07:50:41 +00:00
shortcutDescription = string . Format ( Language . Execute_application_with_profile , programName , ProfileToUse . Name ) ;
2020-05-17 09:19:55 +00:00
}
// Only add the rest of the options if the temporary switch radio button is set
// and if the game launching radio button is set
else if ( Permanence = = ShortcutPermanence . Temporary )
{
// Prepare text for the shortcut description field
2020-07-21 07:50:41 +00:00
shortcutDescription = string . Format ( Language . Execute_application_with_profile , GameName , ProfileToUse . Name ) ;
2020-05-17 09:19:55 +00:00
}
}
// Only add the rest of the options if the permanent switch radio button is set
else
{
// Prepare text for the shortcut description field
2020-07-21 07:50:41 +00:00
shortcutDescription = string . Format ( Language . Switching_display_profile_to_profile , ProfileToUse . Name ) ;
2020-05-16 11:16:46 +00:00
}
2020-05-17 09:19:55 +00:00
// Now we are ready to create a shortcut based on the filename the user gave us
shortcutFileName = Path . ChangeExtension ( shortcutFileName , @"lnk" ) ;
2020-07-21 07:50:41 +00:00
// And we use the Icon from the shortcutIconCache
shortcutIconFileName = SavedShortcutIconCacheFilename ;
2020-05-17 09:19:55 +00:00
// If the user supplied a file
if ( shortcutFileName ! = null )
{
try
{
2020-07-21 07:50:41 +00:00
// Remove the old file if it exists to replace it
if ( System . IO . File . Exists ( shortcutFileName ) )
2020-05-17 09:19:55 +00:00
{
2020-07-21 07:50:41 +00:00
System . IO . File . Delete ( shortcutFileName ) ;
2020-05-17 09:19:55 +00:00
}
// Actually create the shortcut!
2020-07-21 07:50:41 +00:00
//var wshShellType = Type.GetTypeFromCLSID(new Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8"));
//dynamic wshShell = Activator.CreateInstance(wshShellType);
2020-05-17 09:19:55 +00:00
2020-07-21 07:50:41 +00:00
WshShell shell = new WshShell ( ) ;
IWshShortcut shortcut = ( IWshShortcut ) shell . CreateShortcut ( shortcutFileName ) ;
2020-05-17 09:19:55 +00:00
2020-07-21 07:50:41 +00:00
shortcut . TargetPath = Application . ExecutablePath ;
shortcut . Arguments = string . Join ( " " , shortcutArgs ) ;
shortcut . Description = shortcutDescription ;
shortcut . WorkingDirectory = Path . GetDirectoryName ( Application . ExecutablePath ) ? ?
string . Empty ;
2020-05-17 09:19:55 +00:00
2020-07-21 07:50:41 +00:00
shortcut . IconLocation = shortcutIconFileName ;
shortcut . Save ( ) ;
2020-05-17 09:19:55 +00:00
}
2020-07-15 08:11:38 +00:00
catch ( Exception ex )
2020-05-17 09:19:55 +00:00
{
2020-07-15 08:11:38 +00:00
Console . WriteLine ( $"ShortcutItem/CreateShortcut exception (deleting old shortcut)" ) ;
2020-05-17 09:19:55 +00:00
// Clean up a failed attempt
2020-07-21 07:50:41 +00:00
if ( System . IO . File . Exists ( shortcutFileName ) )
2020-05-17 09:19:55 +00:00
{
2020-07-21 07:50:41 +00:00
System . IO . File . Delete ( shortcutFileName ) ;
2020-05-17 09:19:55 +00:00
}
}
}
// Return a status on how it went
// true if it was a success or false if it was not
2020-07-21 07:50:41 +00:00
return shortcutFileName ! = null & & System . IO . File . Exists ( shortcutFileName ) ;
2020-05-16 11:16:46 +00:00
}
2020-05-17 09:19:55 +00:00
2020-07-23 06:31:00 +00:00
2020-06-15 09:57:46 +00:00
public void AutoSuggestShortcutName ( )
{
if ( AutoName & & _profileToUse is ProfileItem )
{
if ( Category . Equals ( ShortcutCategory . NoGame ) )
{
if ( Permanence . Equals ( ShortcutPermanence . Permanent ) )
_name = $"{_profileToUse.Name}" ;
else if ( Permanence . Equals ( ShortcutPermanence . Temporary ) )
_name = $"{_profileToUse.Name} (Temporary)" ;
}
else if ( Category . Equals ( ShortcutCategory . Game ) & & GameName . Length > 0 )
{
_name = $"{GameName} ({_profileToUse.Name})" ;
}
else if ( Category . Equals ( ShortcutCategory . Application ) & & ExecutableNameAndPath . Length > 0 )
{
string baseName = Path . GetFileNameWithoutExtension ( ExecutableNameAndPath ) ;
_name = $"{baseName} ({_profileToUse.Name})" ;
}
}
}
2020-05-16 11:16:46 +00:00
}
2020-10-19 08:50:42 +00:00
/ * internal class IconActions
{
// Constants
// =========
private const string Shell32 = "shell32.dll" ;
private const string User32 = "user32.dll" ;
// External Methods
// ================
[DllImport(Shell32, CharSet = CharSet.Auto)]
private static extern int PickIconDlg ( IntPtr hwndOwner , StringBuilder lpstrFile , int nMaxFile , ref int lpdwIconIndex ) ;
[DllImport(Shell32, CharSet = CharSet.Auto)]
private static extern uint ExtractIconEx ( string szFileName , int nIconIndex , IntPtr [ ] phiconLarge , IntPtr [ ] phiconSmall , uint nIcons ) ;
[DllImport(User32, CharSet = CharSet.Auto)]
private static extern bool DestroyIcon ( IntPtr handle ) ;
// Methods
// =======
public int PickIconDialog ( IntPtr hwndOwner , StringBuilder lpstrFile , int nMaxFile , ref int lpdwIconIndex )
{
return PickIconDlg ( hwndOwner , lpstrFile , nMaxFile , ref lpdwIconIndex ) ;
}
public uint ExtractIcon ( string szFileName , int nIconIndex , IntPtr [ ] phiconLarge , IntPtr [ ] phiconSmall , uint nIcons )
{
return ExtractIconEx ( szFileName , nIconIndex , phiconLarge , phiconSmall , nIcons ) ;
}
public bool DestroyIconAtHandle ( IntPtr handle )
{
return DestroyIcon ( handle ) ;
}
}
public class IconReference
{
// Constants
// =========
private const string comma = "," ;
// Variables
// =========
private static readonly Regex regex = new Regex ( @".+\,[0-9]+$" ) ;
// Properties
// ==========
/// <summary>
/// File path to the icon.
/// </summary>
public string FilePath { get ; private set ; }
/// <summary>
/// Index of the icon within the file.
/// </summary>
public int IconIndex { get ; private set ; }
// Constructors
// ============
/// <summary>
/// Constructor.
/// </summary>
/// <param name="reference">A reference for an icon within either an .ico, .exe, or .dll. Must be a valid file location followed by a comma and then an int.</param>
/// <exception cref="RegexMatchTimeoutException">Ignore.</exception>
public IconReference ( string reference )
{
if ( ! regex . IsMatch ( reference ) )
{
throw new ArgumentException ( "[reference] must be a valid file location followed by a comma and then an int" ) ;
}
string [ ] split = reference . Split ( ',' ) ;
string index = split [ split . Length - 1 ] ;
string filePath = reference . Substring ( 0 , reference . Length - index . Length - 1 ) ;
Setup ( filePath , index ) ;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="filePath">A valid file location for an .ico, .exe, or .dll.</param>
/// <param name="index">The index of the icon wanted within the file.</param>
public IconReference ( string filePath , string index )
{
Setup ( filePath , index ) ;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="filePath">A valid file location for an .ico, .exe, or .dll.</param>
/// <param name="index">The index of the icon wanted within the file.</param>
public IconReference ( string filePath , int index )
{
Setup ( filePath , index ) ;
}
/// <summary>
/// Returns the FileName and the IconIndex separated by a comma
/// </summary>
/// <returns>Returns the FileName and the IconIndex separated by a comma</returns>
public override string ToString ( )
{
return ( FilePath ? ? string . Empty ) + comma + ( IconIndex . ToString ( ) ? ? string . Empty ) ;
}
private void Setup ( string filepath , string index )
{
if ( ! int . TryParse ( index , out int iconIndex ) )
{
throw new ArgumentException ( "Parameter [index] needs to be castable to an integer" ) ;
}
Setup ( filepath , iconIndex ) ;
}
private void Setup ( string filepath , int index )
{
if ( index < 0 )
{
throw new ArgumentException ( "Parameter [index] needs to be greater than or equal to zero" ) ;
}
FilePath = filepath ;
IconIndex = index ;
}
} * /
2020-05-16 11:16:46 +00:00
#region JsonConverterBitmap
internal class CustomBitmapConverter : JsonConverter
{
public override bool CanConvert ( Type objectType )
{
return true ;
}
//convert from byte to bitmap (deserialize)
public override object ReadJson ( JsonReader reader , Type objectType , object existingValue , JsonSerializer serializer )
{
string image = ( string ) reader . Value ;
byte [ ] byteBuffer = Convert . FromBase64String ( image ) ;
MemoryStream memoryStream = new MemoryStream ( byteBuffer ) ;
memoryStream . Position = 0 ;
return ( Bitmap ) Bitmap . FromStream ( memoryStream ) ;
}
//convert bitmap to byte (serialize)
public override void WriteJson ( JsonWriter writer , object value , JsonSerializer serializer )
{
Bitmap bitmap = ( Bitmap ) value ;
ImageConverter converter = new ImageConverter ( ) ;
writer . WriteValue ( ( byte [ ] ) converter . ConvertTo ( bitmap , typeof ( byte [ ] ) ) ) ;
}
public static System . Drawing . Imaging . ImageFormat GetImageFormat ( Bitmap bitmap )
{
ImageFormat img = bitmap . RawFormat ;
if ( img . Equals ( System . Drawing . Imaging . ImageFormat . Jpeg ) )
return System . Drawing . Imaging . ImageFormat . Jpeg ;
if ( img . Equals ( System . Drawing . Imaging . ImageFormat . Bmp ) )
return System . Drawing . Imaging . ImageFormat . Bmp ;
if ( img . Equals ( System . Drawing . Imaging . ImageFormat . Png ) )
return System . Drawing . Imaging . ImageFormat . Png ;
if ( img . Equals ( System . Drawing . Imaging . ImageFormat . Emf ) )
return System . Drawing . Imaging . ImageFormat . Emf ;
if ( img . Equals ( System . Drawing . Imaging . ImageFormat . Exif ) )
return System . Drawing . Imaging . ImageFormat . Exif ;
if ( img . Equals ( System . Drawing . Imaging . ImageFormat . Gif ) )
return System . Drawing . Imaging . ImageFormat . Gif ;
if ( img . Equals ( System . Drawing . Imaging . ImageFormat . Icon ) )
return System . Drawing . Imaging . ImageFormat . Icon ;
if ( img . Equals ( System . Drawing . Imaging . ImageFormat . MemoryBmp ) )
return System . Drawing . Imaging . ImageFormat . MemoryBmp ;
if ( img . Equals ( System . Drawing . Imaging . ImageFormat . Tiff ) )
return System . Drawing . Imaging . ImageFormat . Tiff ;
else
return System . Drawing . Imaging . ImageFormat . Wmf ;
}
}
#endregion
}