Merge branch 'release-0.2.1' into main

This commit is contained in:
Terry MacDonald 2020-12-28 21:54:19 +13:00
commit db418b09d9
104 changed files with 18819 additions and 4364 deletions

1
.gitignore vendored
View File

@ -250,3 +250,4 @@ HeliosDisplayManagement.Setup/HeliosDisplayManagement.Setup/*
/vs_community__1091181154.1584848614.exe
/MigrationBackup
/Notes
/DisplayMagician/Resources/settings.png

File diff suppressed because it is too large Load Diff

View File

@ -1,293 +0,0 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace DisplayMagician.Shared
{
/// <summary>
/// Represents a Restart Manager session. The Restart Manager enables all but the critical system services to be shut
/// down and restarted with aim of eliminate or reduce the number of system restarts that are required to complete an
/// installation or update.
/// </summary>
/// <seealso cref="System.IDisposable" />
public class RestartManagerSession : IDisposable
{
public delegate void WriteStatusCallback(uint percentageCompleted);
/// <summary>
/// Specifies the type of modification that is applied to restart or shutdown actions.
/// </summary>
public enum FilterAction : uint
{
/// <summary>
/// Prevents the restart of the specified application or service.
/// </summary>
RmNoRestart = 1,
/// <summary>
/// Prevents the shut down and restart of the specified application or service.
/// </summary>
RmNoShutdown = 2
}
[Flags]
public enum ShutdownType : uint
{
/// <summary>
/// Default behavior
/// </summary>
Normal = 0,
/// <summary>
/// Force unresponsive applications and services to shut down after the timeout period. An application that does not
/// respond to a shutdown request is forced to shut down within 30 seconds. A service that does not respond to a
/// shutdown request is forced to shut down after 20 seconds.
/// </summary>
ForceShutdown = 0x1,
/// <summary>
/// Shut down applications if and only if all the applications have been registered for restart using the
/// RegisterApplicationRestart function. If any processes or services cannot be restarted, then no processes or
/// services are shut down.
/// </summary>
ShutdownOnlyRegistered = 0x10
}
public RestartManagerSession()
{
SessionKey = Guid.NewGuid().ToString();
var errorCode = StartSession(out var sessionHandle, 0, SessionKey);
if (errorCode != 0)
{
throw new Win32Exception(errorCode);
}
Handle = sessionHandle;
}
public RestartManagerSession(string sessionKey)
{
SessionKey = sessionKey;
var errorCode = JoinSession(out var sessionHandle, SessionKey);
if (errorCode != 0)
{
throw new Win32Exception(errorCode);
}
Handle = sessionHandle;
}
private IntPtr Handle { get; }
public string SessionKey { get; }
/// <inheritdoc />
public void Dispose()
{
ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}
[DllImport("rstrtmgr", EntryPoint = "RmAddFilter", CharSet = CharSet.Auto)]
// ReSharper disable once TooManyArguments
private static extern int AddFilter(
IntPtr sessionHandle,
string fileName,
UniqueProcess application,
string serviceName,
FilterAction filterAction);
[DllImport("rstrtmgr", EntryPoint = "RmAddFilter", CharSet = CharSet.Auto)]
// ReSharper disable once TooManyArguments
private static extern int AddFilter(
IntPtr sessionHandle,
string fileName,
IntPtr application,
string serviceName,
FilterAction filterAction);
[DllImport("rstrtmgr", EntryPoint = "RmEndSession")]
private static extern int EndSession(IntPtr sessionHandle);
[DllImport("rstrtmgr", EntryPoint = "RmJoinSession", CharSet = CharSet.Auto)]
private static extern int JoinSession(out IntPtr sessionHandle, string strSessionKey);
[DllImport("rstrtmgr", EntryPoint = "RmRegisterResources", CharSet = CharSet.Auto)]
// ReSharper disable once TooManyArguments
private static extern int RegisterResources(
IntPtr sessionHandle,
uint numberOfFiles,
string[] fileNames,
uint numberOfApplications,
UniqueProcess[] applications,
uint numberOfServices,
string[] serviceNames);
[DllImport("rstrtmgr", EntryPoint = "RmRestart")]
private static extern int Restart(IntPtr sessionHandle, int restartFlags, WriteStatusCallback statusCallback);
[DllImport("rstrtmgr", EntryPoint = "RmShutdown")]
private static extern int Shutdown(
IntPtr sessionHandle,
ShutdownType actionFlags,
WriteStatusCallback statusCallback);
[DllImport("rstrtmgr", EntryPoint = "RmStartSession", CharSet = CharSet.Auto)]
private static extern int StartSession(out IntPtr sessionHandle, int sessionFlags, string strSessionKey);
public void FilterProcess(Process process, FilterAction action)
{
var errorCode = AddFilter(Handle, null, UniqueProcess.FromProcess(process), null, action);
if (errorCode != 0)
{
throw new Win32Exception(errorCode);
}
}
public void FilterProcessFile(FileInfo file, FilterAction action)
{
var errorCode = AddFilter(Handle, file.FullName, IntPtr.Zero, null, action);
if (errorCode != 0)
{
throw new Win32Exception(errorCode);
}
}
public void FilterService(string serviceName, FilterAction action)
{
var errorCode = AddFilter(Handle, null, IntPtr.Zero, serviceName, action);
if (errorCode != 0)
{
throw new Win32Exception(errorCode);
}
}
public void RegisterProcess(params Process[] processes)
{
var errorCode = RegisterResources(Handle,
0, new string[0],
(uint) processes.Length, processes.Select(UniqueProcess.FromProcess).ToArray(),
0, new string[0]);
if (errorCode != 0)
{
throw new Win32Exception(errorCode);
}
}
public void RegisterProcessFile(params FileInfo[] files)
{
var errorCode = RegisterResources(Handle,
(uint) files.Length, files.Select(f => f.FullName).ToArray(),
0, new UniqueProcess[0],
0, new string[0]);
if (errorCode != 0)
{
throw new Win32Exception(errorCode);
}
}
public void RegisterService(params string[] serviceNames)
{
var errorCode = RegisterResources(Handle,
0, new string[0],
0, new UniqueProcess[0],
(uint) serviceNames.Length, serviceNames);
if (errorCode != 0)
{
throw new Win32Exception(errorCode);
}
}
public void Restart(WriteStatusCallback statusCallback)
{
var errorCode = Restart(Handle, 0, statusCallback);
if (errorCode != 0)
{
throw new Win32Exception(errorCode);
}
}
public void Restart()
{
Restart(null);
}
public void Shutdown(ShutdownType shutdownType, WriteStatusCallback statusCallback)
{
var errorCode = Shutdown(Handle, shutdownType, statusCallback);
if (errorCode != 0)
{
throw new Win32Exception(errorCode);
}
}
public void Shutdown(ShutdownType shutdownType)
{
Shutdown(shutdownType, null);
}
private void ReleaseUnmanagedResources()
{
try
{
EndSession(Handle);
}
catch (Exception)
{
// ignored
}
}
/// <inheritdoc />
~RestartManagerSession()
{
ReleaseUnmanagedResources();
}
[StructLayout(LayoutKind.Sequential)]
private struct FileTime
{
private uint LowDateTime;
private uint HighDateTime;
public static FileTime FromDateTime(DateTime dateTime)
{
var ticks = dateTime.ToFileTime();
return new FileTime
{
HighDateTime = (uint) (ticks >> 32),
LowDateTime = (uint) (ticks & uint.MaxValue)
};
}
}
[StructLayout(LayoutKind.Sequential)]
private struct UniqueProcess
{
private int ProcessId;
private FileTime ProcessStartTime;
public static UniqueProcess FromProcess(Process process)
{
return new UniqueProcess
{
ProcessId = process.Id,
ProcessStartTime = FileTime.FromDateTime(process.StartTime)
};
}
}
}
}

View File

@ -1,75 +0,0 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace DisplayMagician.Shared
{
public static class ShellHelper
{
private static readonly uint NotifyMessage_SettingChange = 0x001A;
private static readonly uint NotifyMessage_ThemeChanged = 0x031A;
private static readonly uint ShellChange_AllEvents = 0x7FFFFFFF;
private static readonly uint ShellChange_FlushFlag = 0x1000;
private static readonly uint ShellChange_NotifyRecursiveFlag = 0x10000;
private static readonly UIntPtr WindowHandleBroadcast = (UIntPtr) 0xffff;
public static Process GetShellProcess()
{
try
{
var shellWindowHandle = GetShellWindow();
if (shellWindowHandle != IntPtr.Zero)
{
GetWindowThreadProcessId(shellWindowHandle, out var shellPid);
if (shellPid > 0)
{
return Process.GetProcessById((int) shellPid);
}
}
}
catch (Exception)
{
// ignored
}
return null;
}
public static async Task IntrigueShellToWriteSettings()
{
try
{
SendNotifyMessage(WindowHandleBroadcast, NotifyMessage_SettingChange, (UIntPtr) 0, "Policy");
SendNotifyMessage(WindowHandleBroadcast, NotifyMessage_ThemeChanged, (UIntPtr) 0, null);
ShellChangeNotify(ShellChange_AllEvents, ShellChange_FlushFlag | ShellChange_NotifyRecursiveFlag,
IntPtr.Zero, IntPtr.Zero);
}
catch (Exception)
{
// ignored
}
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
}
[DllImport("user32")]
private static extern IntPtr GetShellWindow();
[DllImport("user32", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr windowHandle, out uint processId);
[DllImport("user32", EntryPoint = "SendNotifyMessage", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool SendNotifyMessage(
UIntPtr windowHandle,
uint messageId,
UIntPtr wParam,
string lParam);
[DllImport("shell32", EntryPoint = "SHChangeNotify", SetLastError = true)]
private static extern int ShellChangeNotify(uint eventId, uint flags, IntPtr item1, IntPtr item2);
}
}

View File

@ -1,103 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Win32;
namespace DisplayMagician.Shared
{
public class TaskBarSettings
{
private const string AdvancedSettingsAddress =
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced";
public Tuple<string, int>[] Options { get; set; }
public TaskBarStuckRectangle SingleMonitorStuckRectangle { get; set; }
public static TaskBarSettings GetCurrent()
{
var taskBarOptions = new List<Tuple<string, int>>();
// Get stored integer Taskbar options from the User Registry
try
{
using (var key = Registry.CurrentUser.OpenSubKey(
AdvancedSettingsAddress,
RegistryKeyPermissionCheck.ReadSubTree))
{
if (key != null)
{
foreach (var valueName in key.GetValueNames())
{
try
{
if (!string.IsNullOrWhiteSpace(valueName) && valueName.ToLower().Contains("taskbar"))
{
var value = key.GetValue(valueName, null,
RegistryValueOptions.DoNotExpandEnvironmentNames);
if (value != null && value is int intValue)
{
taskBarOptions.Add(new Tuple<string, int>(valueName, intValue));
}
}
}
catch (Exception)
{
// ignored
}
}
}
}
}
catch (Exception)
{
// ignored
}
if (taskBarOptions.Count == 0)
{
return null;
}
return new TaskBarSettings
{
Options = taskBarOptions.ToArray(),
SingleMonitorStuckRectangle = TaskBarStuckRectangle.GetCurrent()
};
}
public bool Apply()
{
if (SingleMonitorStuckRectangle == null ||
Options.Length == 0)
{
throw new InvalidOperationException();
}
using (var optionsKey = Registry.CurrentUser.OpenSubKey(
AdvancedSettingsAddress,
RegistryKeyPermissionCheck.ReadWriteSubTree))
{
if (optionsKey == null)
{
return false;
}
// Write
foreach (var option in Options)
{
try
{
optionsKey.SetValue(option.Item1, option.Item2);
}
catch (Exception)
{
// ignored
}
}
}
return true;
}
}
}

View File

@ -1,358 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using WindowsDisplayAPI.DisplayConfig;
using Microsoft.Win32;
using Newtonsoft.Json;
namespace DisplayMagician.Shared
{
public class TaskBarStuckRectangle
{
public enum TaskBarEdge : uint
{
Left = 0,
Top = 1,
Right = 2,
Bottom = 3
}
[Flags]
public enum TaskBarOptions : uint
{
None = 0,
AutoHide = 1 << 0,
KeepOnTop = 1 << 1,
UseSmallIcons = 1 << 2,
HideClock = 1 << 3,
HideVolume = 1 << 4,
HideNetwork = 1 << 5,
HidePower = 1 << 6,
WindowPreview = 1 << 7,
Unknown1 = 1 << 8,
Unknown2 = 1 << 9,
HideActionCenter = 1 << 10,
Unknown3 = 1 << 11,
HideLocation = 1 << 12,
HideLanguageBar = 1 << 13
}
private const string MainDisplayAddress =
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects{0:D}";
private const string MultiDisplayAddress =
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MMStuckRects{0:D}";
private static readonly Dictionary<int, byte[]> Headers = new Dictionary<int, byte[]>
{
{2, new byte[] {0x28, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}},
{3, new byte[] {0x30, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF}}
};
public TaskBarStuckRectangle(int version, string devicePath) : this(version)
{
DevicePath = devicePath;
}
public TaskBarStuckRectangle(int version)
{
if (!Headers.ContainsKey(version))
{
throw new ArgumentException(@"Invalid version number specified.", nameof(version));
}
Version = version;
DevicePath = null;
Binary = new byte[Headers[Version][0]];
Array.Copy(Headers[Version], 0, Binary, 0, Headers[Version].Length);
DPI = 96;
Rows = 1;
Location = Rectangle.Empty;
MinSize = Size.Empty;
Edge = TaskBarEdge.Bottom;
Options = TaskBarOptions.KeepOnTop;
}
public TaskBarStuckRectangle()
{
}
public byte[] Binary { get; set; }
public string DevicePath { get; set; }
[JsonIgnore]
public uint DPI
{
get
{
if (Binary.Length < 44)
{
return 0;
}
return BitConverter.ToUInt32(Binary, 40);
}
set
{
if (Binary.Length < 44)
{
return;
}
var bytes = BitConverter.GetBytes(value);
Array.Copy(bytes, 0, Binary, 40, 4);
}
}
[JsonIgnore]
public TaskBarEdge Edge
{
get
{
if (Binary.Length < 16)
{
return TaskBarEdge.Bottom;
}
return (TaskBarEdge) BitConverter.ToUInt32(Binary, 12);
}
set
{
if (Binary.Length < 16)
{
return;
}
var bytes = BitConverter.GetBytes((uint) value);
Array.Copy(bytes, 0, Binary, 12, 4);
}
}
[JsonIgnore]
public Rectangle Location
{
get
{
if (Binary.Length < 40)
{
return Rectangle.Empty;
}
var left = BitConverter.ToInt32(Binary, 24);
var top = BitConverter.ToInt32(Binary, 28);
var right = BitConverter.ToInt32(Binary, 32);
var bottom = BitConverter.ToInt32(Binary, 36);
return Rectangle.FromLTRB(left, top, right, bottom);
}
set
{
if (Binary.Length < 40)
{
return;
}
var bytes = BitConverter.GetBytes(value.Left);
Array.Copy(bytes, 0, Binary, 24, 4);
bytes = BitConverter.GetBytes(value.Top);
Array.Copy(bytes, 0, Binary, 28, 4);
bytes = BitConverter.GetBytes(value.Right);
Array.Copy(bytes, 0, Binary, 32, 4);
bytes = BitConverter.GetBytes(value.Bottom);
Array.Copy(bytes, 0, Binary, 36, 4);
}
}
[JsonIgnore]
public Size MinSize
{
get
{
if (Binary.Length < 24)
{
return Size.Empty;
}
var width = BitConverter.ToInt32(Binary, 16);
var height = BitConverter.ToInt32(Binary, 20);
return new Size(width, height);
}
set
{
if (Binary.Length < 24)
{
return;
}
var bytes = BitConverter.GetBytes(value.Width);
Array.Copy(bytes, 0, Binary, 16, 4);
bytes = BitConverter.GetBytes(value.Height);
Array.Copy(bytes, 0, Binary, 20, 4);
}
}
[JsonIgnore]
public TaskBarOptions Options
{
get
{
if (Binary.Length < 12)
{
return 0;
}
return (TaskBarOptions) BitConverter.ToUInt32(Binary, 8);
}
set
{
if (Binary.Length < 12)
{
return;
}
var bytes = BitConverter.GetBytes((uint) value);
Array.Copy(bytes, 0, Binary, 8, 4);
}
}
[JsonIgnore]
public uint Rows
{
get
{
if (Binary.Length < 48)
{
return 1;
}
return BitConverter.ToUInt32(Binary, 44);
}
set
{
if (Binary.Length < 48)
{
return;
}
var bytes = BitConverter.GetBytes(value);
Array.Copy(bytes, 0, Binary, 44, 4);
}
}
public int Version { get; set; }
public static TaskBarStuckRectangle GetCurrent()
{
return GetCurrent((string) null);
}
public static TaskBarStuckRectangle GetCurrent(PathDisplayTarget pathTargetInfo)
{
var devicePath = pathTargetInfo?.DevicePath;
var index = devicePath?.IndexOf("{", StringComparison.InvariantCultureIgnoreCase);
if (index > 0)
{
devicePath = devicePath.Substring(0, index.Value).TrimEnd('#');
}
index = devicePath?.IndexOf("#", StringComparison.InvariantCultureIgnoreCase);
if (index > 0)
{
devicePath = devicePath.Substring(index.Value).TrimStart('#');
}
return GetCurrent(devicePath);
}
public static TaskBarStuckRectangle GetCurrent(string devicePath)
{
var stuckRectanglesVersion = 0;
byte[] stuckRectanglesBinary = null;
// Try to extract the latest version of StuckRectangles available on the User Registry
foreach (var version in Headers.Keys)
{
try
{
var address = devicePath != null
? string.Format(MultiDisplayAddress, version)
: string.Format(MainDisplayAddress, version);
using (var key = Registry.CurrentUser.OpenSubKey(
address,
RegistryKeyPermissionCheck.ReadSubTree))
{
var settings = key?.GetValue(devicePath ?? "Settings") as byte[];
if (settings?.Length > 0)
{
stuckRectanglesBinary = settings;
stuckRectanglesVersion = version;
}
}
}
catch (Exception)
{
// ignored
}
}
if (stuckRectanglesVersion == 0 || stuckRectanglesBinary == null)
{
return null;
}
return new TaskBarStuckRectangle
{
DevicePath = devicePath,
Binary = stuckRectanglesBinary,
Version = stuckRectanglesVersion
};
}
public bool Apply()
{
if (Binary == null ||
Binary.Length == 0 ||
Version <= 0)
{
throw new InvalidOperationException();
}
var address = DevicePath != null
? string.Format(MultiDisplayAddress, Version)
: string.Format(MainDisplayAddress, Version);
using (var stuckRectanglesKey = Registry.CurrentUser.OpenSubKey(
address,
RegistryKeyPermissionCheck.ReadWriteSubTree))
{
if (stuckRectanglesKey == null)
{
return false;
}
try
{
stuckRectanglesKey.SetValue(DevicePath ?? "Settings", Binary);
}
catch (Exception)
{
// ignored
}
}
return true;
}
}
}

View File

@ -1,127 +0,0 @@
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.IO;
using System;
using SharpShell.Attributes;
using SharpShell.SharpContextMenu;
using SharpShell.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Win32;
namespace DisplayMagician.ShellExtension
{
[ComVisible(true)]
[COMServerAssociation(AssociationType.DesktopBackground)]
[Guid("346e3285-43ca-45bc-8b33-1d4cdfe32e00")]
public class HeliosDesktopMenuExtension : SharpContextMenu
{
// Other constants that are useful
internal static Version _version = new Version(1, 0, 0);
internal static string AlternateAppHomePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "DisplayMagician");
internal static string AppDataPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DisplayMagician");
private static string AppProfileStoragePath = System.IO.Path.Combine(AppDataPath, $"Profiles");
private static string _profileStorageJsonFileName = System.IO.Path.Combine(AppProfileStoragePath, $"DisplayProfiles_{_version.ToString(2)}.json");
internal static string registryDisplayMagician = @"SOFTWARE\DisplayMagician";
string DisplayMagicianFullname = "";
string DisplayMagicianInstallDir = "";
Process DisplayMagicianProcess = null;
public HeliosDesktopMenuExtension()
{ }
protected override bool CanShowMenu()
{
//Logging.Log($"Starting CanShowMenu");
// Only show this menu if DisplayMagician is installed
DisplayMagicianInstallDir = "";
try
{
RegistryKey DisplayMagicianKey = Registry.LocalMachine.OpenSubKey(registryDisplayMagician, RegistryKeyPermissionCheck.ReadSubTree);
DisplayMagicianInstallDir = DisplayMagicianKey.GetValue("InstallDir", AlternateAppHomePath).ToString();
}
catch (Exception)
{
DisplayMagicianInstallDir = AlternateAppHomePath;
}
DisplayMagicianFullname = Path.Combine(DisplayMagicianInstallDir, "DisplayMagician.exe");
//Logging.Log($"DisplayMagician is installed in {DisplayMagicianFullname}");
if (File.Exists(DisplayMagicianFullname))
{
//Logging.Log($"CanShowMenu is returning true (can show menu)");
return true;
}
else
{
//Logging.Log($"CanShowMenu is returning false (cannot show menu)");
return false;
}
}
protected override ContextMenuStrip CreateMenu()
{
//Logging.Log($"Starting CreateMenu");
var explorerMenuStrip = new ContextMenuStrip();
if (File.Exists(DisplayMagicianFullname))
{
var extensionMenu = new ToolStripMenuItem("DisplayMagician: Change display profiles...", Properties.Resources.DisplayMagicianMenuImage);
explorerMenuStrip.Items.Add(extensionMenu);
Dictionary<string, string> profiles = new Dictionary<string, string>();
if (File.Exists(_profileStorageJsonFileName))
{
MatchCollection mc;
string uuid = "";
string profileName = "";
foreach (string aLine in File.ReadLines(_profileStorageJsonFileName, Encoding.Unicode))
{
string lineToProcess = aLine;
if (lineToProcess.StartsWith(" \"UUID\""))
{
mc = Regex.Matches(lineToProcess, " \"UUID\": \"(.*)\"");
uuid = mc[0].Groups[1].ToString();
}
else if (lineToProcess.StartsWith(" \"Name\""))
{
mc = Regex.Matches(lineToProcess, " \"Name\": \"(.*)\"");
profileName = mc[0].Groups[1].ToString();
if (!uuid.Equals(""))
profiles.Add(profileName, uuid);
}
}
}
if (profiles.Count > 0)
{
foreach (KeyValuePair<string, string> pair in profiles.OrderBy(key => key.Key))
{
extensionMenu.DropDownItems.Add(new ToolStripMenuItem(pair.Key, null,
(sender, args) =>
{
Logging.Log(DisplayMagicianFullname + $" ChangeProfile \"{pair.Value}\"");
DisplayMagicianProcess = Process.Start(DisplayMagicianFullname,$"ChangeProfile \"{pair.Value}\"");
Logging.Log(DisplayMagicianProcess.ToString());
}
));
}
}
}
return explorerMenuStrip;
}
}
}

View File

@ -4,51 +4,102 @@ VisualStudioVersion = 16.0.30002.166
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DisplayMagician", "DisplayMagician\DisplayMagician.csproj", "{608D941A-B431-400C-A91D-C6F971C29577}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DisplayMagician.ShellExtension", "DisplayMagician.ShellExtension\DisplayMagician.ShellExtension.csproj", "{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DisplayMagicianShellExtension", "DisplayMagicianShellExtension\DisplayMagicianShellExtension.csproj", "{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DisplayMagician.Shared", "DisplayMagician.Shared\DisplayMagician.Shared.csproj", "{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DisplayMagicianShared", "DisplayMagicianShared\DisplayMagicianShared.csproj", "{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DisplayMagician.LogReporter", "DisplayMagician.LogReporter\DisplayMagician.LogReporter.csproj", "{76DF2BCF-911B-4820-B63E-8F3468DB5E79}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DisplayMagicianLogReporter", "DisplayMagicianLogReporter\DisplayMagicianLogReporter.csproj", "{76DF2BCF-911B-4820-B63E-8F3468DB5E79}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DisplayMagician.Tests", "DisplayMagician.Tests\DisplayMagician.Tests.csproj", "{D7AFD3CC-53BF-4991-ABFE-638A3F355310}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DisplayMagicianTests", "DisplayMagicianTests\DisplayMagicianTests.csproj", "{D7AFD3CC-53BF-4991-ABFE-638A3F355310}"
ProjectSection(ProjectDependencies) = postProject
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68} = {55D4FF65-EDC7-48EF-933E-B6E7F3809B68}
{76DF2BCF-911B-4820-B63E-8F3468DB5E79} = {76DF2BCF-911B-4820-B63E-8F3468DB5E79}
EndProjectSection
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "DisplayMagician.Setup", "DisplayMagician.Setup\HeliosPlus.Setup.vdproj", "{2DC67145-6BCC-4BAB-AE6C-EDAEC25B87DA}"
ProjectSection(ProjectDependencies) = postProject
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68} = {55D4FF65-EDC7-48EF-933E-B6E7F3809B68}
EndProjectSection
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "DisplayMagicianSetup", "DisplayMagicianSetup\DisplayMagicianSetup.wixproj", "{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AnyCPU = Debug|AnyCPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|AnyCPU = Release|AnyCPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{608D941A-B431-400C-A91D-C6F971C29577}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Debug|AnyCPU.Build.0 = Debug|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Debug|x64.ActiveCfg = Debug|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Debug|x64.Build.0 = Debug|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Debug|x86.ActiveCfg = Debug|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Debug|x86.Build.0 = Debug|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Release|AnyCPU.ActiveCfg = Release|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Release|AnyCPU.Build.0 = Release|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Release|x64.ActiveCfg = Release|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Release|x64.Build.0 = Release|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Release|x86.ActiveCfg = Release|Any CPU
{608D941A-B431-400C-A91D-C6F971C29577}.Release|x86.Build.0 = Release|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Debug|AnyCPU.Build.0 = Debug|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Debug|x64.ActiveCfg = Debug|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Debug|x64.Build.0 = Debug|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Debug|x86.ActiveCfg = Debug|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Debug|x86.Build.0 = Debug|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Release|AnyCPU.ActiveCfg = Release|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Release|AnyCPU.Build.0 = Release|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Release|x64.ActiveCfg = Release|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Release|x64.Build.0 = Release|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Release|x86.ActiveCfg = Release|Any CPU
{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}.Release|x86.Build.0 = Release|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Debug|AnyCPU.Build.0 = Debug|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Debug|x64.ActiveCfg = Debug|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Debug|x64.Build.0 = Debug|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Debug|x86.ActiveCfg = Debug|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Debug|x86.Build.0 = Debug|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Release|AnyCPU.ActiveCfg = Release|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Release|AnyCPU.Build.0 = Release|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Release|x64.ActiveCfg = Release|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Release|x64.Build.0 = Release|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Release|x86.ActiveCfg = Release|Any CPU
{1CACDA43-01C7-4CD4-BF6E-9421A29510FC}.Release|x86.Build.0 = Release|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Debug|AnyCPU.Build.0 = Debug|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Debug|x64.ActiveCfg = Debug|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Debug|x64.Build.0 = Debug|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Debug|x86.ActiveCfg = Debug|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Debug|x86.Build.0 = Debug|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Release|AnyCPU.ActiveCfg = Release|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Release|AnyCPU.Build.0 = Release|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Release|x64.ActiveCfg = Release|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Release|x64.Build.0 = Release|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Release|x86.ActiveCfg = Release|Any CPU
{76DF2BCF-911B-4820-B63E-8F3468DB5E79}.Release|x86.Build.0 = Release|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Debug|AnyCPU.Build.0 = Debug|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Debug|x64.ActiveCfg = Debug|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Debug|x64.Build.0 = Debug|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Debug|x86.ActiveCfg = Debug|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Debug|x86.Build.0 = Debug|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Release|AnyCPU.ActiveCfg = Release|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Release|AnyCPU.Build.0 = Release|Any CPU
{2DC67145-6BCC-4BAB-AE6C-EDAEC25B87DA}.Debug|AnyCPU.ActiveCfg = Debug
{2DC67145-6BCC-4BAB-AE6C-EDAEC25B87DA}.Release|AnyCPU.ActiveCfg = Release
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Release|x64.ActiveCfg = Release|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Release|x64.Build.0 = Release|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Release|x86.ActiveCfg = Release|Any CPU
{D7AFD3CC-53BF-4991-ABFE-638A3F355310}.Release|x86.Build.0 = Release|Any CPU
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Debug|AnyCPU.ActiveCfg = Debug|x64
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Debug|AnyCPU.Build.0 = Debug|x64
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Debug|x64.ActiveCfg = Debug|x64
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Debug|x64.Build.0 = Debug|x64
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Debug|x86.ActiveCfg = Debug|x86
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Debug|x86.Build.0 = Debug|x86
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Release|AnyCPU.ActiveCfg = Release|x64
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Release|AnyCPU.Build.0 = Release|x64
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Release|x64.ActiveCfg = Release|x64
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Release|x64.Build.0 = Release|x64
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Release|x86.ActiveCfg = Release|x86
{DFD22D4D-F2E4-4BA4-B32A-7A990A35BA08}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
//using Microsoft.Toolkit.Uwp.Notifications;
using DesktopNotifications;
using static DesktopNotifications.NotificationActivator;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Threading;
using Microsoft.QueryStringDotNET;
using System.Windows.Forms;
using DisplayMagician.UIForms;
namespace DisplayMagician
{
// The GUID must be unique to your app. Create a new GUID if copying this code.
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(INotificationActivationCallback))]
[Guid("56F14154-6339-4B94-8B82-80F78D5BCEAF"), ComVisible(true)]
public class DesktopNotificationActivator : NotificationActivator
{
public override void OnActivated(string arguments, NotificationUserInput userInput, string appUserModelId)
{
// Invoke the code we're running on the UI Thread to avoid
// cross thread exceptions
Program.AppMainForm.Invoke((MethodInvoker)delegate
{
// This code is running on the main UI thread!
// Parse the query string (using NuGet package QueryString.NET)
QueryString args = QueryString.Parse(arguments);
foreach (QueryStringParameter myArg in args)
{
if (myArg.Name.Equals("action",StringComparison.OrdinalIgnoreCase))
{
// See what action is being requested
switch (args["action"].ToLowerInvariant())
{
// Open the image
case "open":
// Open the Main DisplayMagician Window
//OpenWindowIfNeeded();
Program.AppMainForm.openApplicationWindow();
break;
// Background: Quick reply to the conversation
case "exit":
// Exit the application (overriding the close restriction)
Program.AppMainForm.exitApplication();
break;
case "stop":
MessageBox.Show("User just asked DisplayMagician to stop monitoring the game");
/*// Get the response the user typed
string msg = userInput["tbReply"];
// And send this message
SendMessage(msg);
// If there's no windows open, exit the app
if (App.Current.Windows.Count == 0)
{
Application.Current.Shutdown();
}*/
break;
default:
break;
}
}
}
});
}
private void OpenWindowIfNeeded()
{
// Make sure we have a window open (in case user clicked toast while app closed)
if (Program.AppMainForm == null)
{
Program.AppMainForm = new MainForm();
}
// Activate the window, bringing it to focus
Program.AppMainForm.openApplicationWindow();
//Program.AppMainForm.openApplicationWindow();
//Program.AppMainForm.Activate();
// And make sure to maximize the window too, in case it was currently minimized
//Program.AppMainForm.WindowState = FormWindowState.Normal;
}
}
}

View File

@ -0,0 +1,510 @@
// ******************************************************************
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
// ******************************************************************
/*
* License for the RegisterActivator portion of code from FrecherxDachs
The MIT License (MIT)
Copyright (c) 2020 Michael Dietrich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
* */
using Microsoft.Win32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using Windows.UI.Notifications;
using static DesktopNotifications.NotificationActivator;
namespace DesktopNotifications
{
public class DesktopNotificationManagerCompat
{
public const string TOAST_ACTIVATED_LAUNCH_ARG = "-ToastActivated";
private static bool _registeredAumidAndComServer;
private static string _aumid;
private static bool _registeredActivator;
/// <summary>
/// If you're not using MSIX or sparse packages, you must call this method to register your AUMID with the Compat library and to
/// register your COM CLSID and EXE in LocalServer32 registry. Feel free to call this regardless, and we will no-op if running
/// under Desktop Bridge. Call this upon application startup, before calling any other APIs.
/// </summary>
/// <param name="aumid">An AUMID that uniquely identifies your application.</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
public static void RegisterAumidAndComServer<T>(string aumid)
where T : NotificationActivator
{
if (string.IsNullOrWhiteSpace(aumid))
{
throw new ArgumentException("You must provide an AUMID.", nameof(aumid));
}
// If running as Desktop Bridge
if (DesktopBridgeHelpers.IsRunningAsUwp())
{
// Clear the AUMID since Desktop Bridge doesn't use it, and then we're done.
// Desktop Bridge apps are registered with platform through their manifest.
// Their LocalServer32 key is also registered through their manifest.
_aumid = null;
_registeredAumidAndComServer = true;
return;
}
_aumid = aumid;
String exePath = Process.GetCurrentProcess().MainModule.FileName;
RegisterComServer<T>(exePath);
_registeredAumidAndComServer = true;
}
private static void RegisterComServer<T>(String exePath)
where T : NotificationActivator
{
// We register the EXE to start up when the notification is activated
string regString = String.Format("SOFTWARE\\Classes\\CLSID\\{{{0}}}", typeof(T).GUID);
using (var key = Registry.CurrentUser.CreateSubKey(regString))
{
// Include a flag so we know this was a toast activation and should wait for COM to process
// We also wrap EXE path in quotes for extra security
key.SetValue("LocalServer32", '"' + exePath + '"' + " " + TOAST_ACTIVATED_LAUNCH_ARG);
}
if (IsElevated)
{
// For elevated apps, we need to ensure they'll activate in existing running process by adding
// some values in local machine
using (var key = Registry.LocalMachine.CreateSubKey(regString))
{
// Same as above, except also including AppId to link to our AppId entry below
key.SetValue("LocalServer32", '"' + exePath + '"' + " " + TOAST_ACTIVATED_LAUNCH_ARG);
key.SetValue("AppId", "{" + typeof(T).GUID + "}");
}
// This tells COM to match any client, so Action Center will activate our elevated process.
// More info: https://docs.microsoft.com/windows/win32/com/runas
using (var key = Registry.LocalMachine.CreateSubKey(String.Format("SOFTWARE\\Classes\\AppID\\{{{0}}}", typeof(T).GUID)))
{
key.SetValue("RunAs", "Interactive User");
}
}
}
/// <summary>
/// Registers the activator type as a COM server client so that Windows can launch your activator.
/// </summary>
/// <typeparam name="T">Your implementation of NotificationActivator. Must have GUID and ComVisible attributes on class.</typeparam>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
public static void RegisterActivator<T>()
where T : NotificationActivator, new()
{
// Big thanks to FrecherxDachs for figuring out the following code which works in .NET Core 3: https://github.com/FrecherxDachs/UwpNotificationNetCoreTest
var uuid = typeof(T).GUID;
uint _cookie;
CoRegisterClassObject(uuid, new NotificationActivatorClassFactory<T>(), CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE, out _cookie);
_registeredActivator = true;
}
[ComImport]
[Guid("00000001-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IClassFactory
{
[PreserveSig]
int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject);
[PreserveSig]
int LockServer(bool fLock);
}
private const int CLASS_E_NOAGGREGATION = -2147221232;
private const int E_NOINTERFACE = -2147467262;
private const int CLSCTX_LOCAL_SERVER = 4;
private const int REGCLS_MULTIPLEUSE = 1;
private const int S_OK = 0;
private static readonly Guid IUnknownGuid = new Guid("00000000-0000-0000-C000-000000000046");
private class NotificationActivatorClassFactory<T> : IClassFactory where T : NotificationActivator, new()
{
public int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject)
{
ppvObject = IntPtr.Zero;
if (pUnkOuter != IntPtr.Zero)
Marshal.ThrowExceptionForHR(CLASS_E_NOAGGREGATION);
if (riid == typeof(T).GUID || riid == IUnknownGuid)
// Create the instance of the .NET object
ppvObject = Marshal.GetComInterfaceForObject(new T(),
typeof(INotificationActivationCallback));
else
// The object that ppvObject points to does not support the
// interface identified by riid.
Marshal.ThrowExceptionForHR(E_NOINTERFACE);
return S_OK;
}
public int LockServer(bool fLock)
{
return S_OK;
}
}
[DllImport("ole32.dll")]
private static extern int CoRegisterClassObject(
[MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnk,
uint dwClsContext,
uint flags,
out uint lpdwRegister);
/// <summary>
/// Creates a toast notifier. You must have called <see cref="RegisterActivator{T}"/> first (and also <see cref="RegisterAumidAndComServer(string)"/> if you're a classic Win32 app), or this will throw an exception.
/// </summary>
/// <returns></returns>
public static ToastNotifier CreateToastNotifier()
{
EnsureRegistered();
if (_aumid != null)
{
// Non-Desktop Bridge
return ToastNotificationManager.CreateToastNotifier(_aumid);
}
else
{
// Desktop Bridge
return ToastNotificationManager.CreateToastNotifier();
}
}
/// <summary>
/// Gets the <see cref="DesktopNotificationHistoryCompat"/> object. You must have called <see cref="RegisterActivator{T}"/> first (and also <see cref="RegisterAumidAndComServer(string)"/> if you're a classic Win32 app), or this will throw an exception.
/// </summary>
public static DesktopNotificationHistoryCompat History
{
get
{
EnsureRegistered();
return new DesktopNotificationHistoryCompat(_aumid);
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "RegisterAumidAndComServer")]
private static void EnsureRegistered()
{
// If not registered AUMID yet
if (!_registeredAumidAndComServer)
{
// Check if Desktop Bridge
if (DesktopBridgeHelpers.IsRunningAsUwp())
{
// Implicitly registered, all good!
_registeredAumidAndComServer = true;
}
else
{
// Otherwise, incorrect usage
throw new Exception("You must call RegisterAumidAndComServer first.");
}
}
// If not registered activator yet
if (!_registeredActivator)
{
// Incorrect usage
throw new Exception("You must call RegisterActivator first.");
}
}
/// <summary>
/// Gets a boolean representing whether http images can be used within toasts. This is true if running with package identity (MSIX or sparse package).
/// </summary>
public static bool CanUseHttpImages { get { return DesktopBridgeHelpers.IsRunningAsUwp(); } }
private static bool IsElevated
{
get
{
return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
}
}
/// <summary>
/// Code from https://github.com/qmatteoq/DesktopBridgeHelpers/edit/master/DesktopBridge.Helpers/Helpers.cs
/// </summary>
private class DesktopBridgeHelpers
{
const long APPMODEL_ERROR_NO_PACKAGE = 15700L;
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern int GetCurrentPackageFullName(ref int packageFullNameLength, StringBuilder packageFullName);
private static bool? _isRunningAsUwp;
public static bool IsRunningAsUwp()
{
if (_isRunningAsUwp == null)
{
if (IsWindows7OrLower)
{
_isRunningAsUwp = false;
}
else
{
int length = 0;
StringBuilder sb = new StringBuilder(0);
int result = GetCurrentPackageFullName(ref length, sb);
sb = new StringBuilder(length);
result = GetCurrentPackageFullName(ref length, sb);
_isRunningAsUwp = result != APPMODEL_ERROR_NO_PACKAGE;
}
}
return _isRunningAsUwp.Value;
}
private static bool IsWindows7OrLower
{
get
{
int versionMajor = Environment.OSVersion.Version.Major;
int versionMinor = Environment.OSVersion.Version.Minor;
double version = versionMajor + (double)versionMinor / 10;
return version <= 6.1;
}
}
}
}
/// <summary>
/// Manages the toast notifications for an app including the ability the clear all toast history and removing individual toasts.
/// </summary>
public sealed class DesktopNotificationHistoryCompat
{
private string _aumid;
private ToastNotificationHistory _history;
/// <summary>
/// Do not call this. Instead, call <see cref="DesktopNotificationManagerCompat.History"/> to obtain an instance.
/// </summary>
/// <param name="aumid"></param>
internal DesktopNotificationHistoryCompat(string aumid)
{
_aumid = aumid;
_history = ToastNotificationManager.History;
}
/// <summary>
/// Removes all notifications sent by this app from action center.
/// </summary>
public void Clear()
{
if (_aumid != null)
{
_history.Clear(_aumid);
}
else
{
_history.Clear();
}
}
/// <summary>
/// Gets all notifications sent by this app that are currently still in Action Center.
/// </summary>
/// <returns>A collection of toasts.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public IReadOnlyList<ToastNotification> GetHistory()
{
return _aumid != null ? _history.GetHistory(_aumid) : _history.GetHistory();
}
/// <summary>
/// Removes an individual toast, with the specified tag label, from action center.
/// </summary>
/// <param name="tag">The tag label of the toast notification to be removed.</param>
public void Remove(string tag)
{
if (_aumid != null)
{
_history.Remove(tag, string.Empty, _aumid);
}
else
{
_history.Remove(tag);
}
}
/// <summary>
/// Removes a toast notification from the action using the notification's tag and group labels.
/// </summary>
/// <param name="tag">The tag label of the toast notification to be removed.</param>
/// <param name="group">The group label of the toast notification to be removed.</param>
public void Remove(string tag, string group)
{
if (_aumid != null)
{
_history.Remove(tag, group, _aumid);
}
else
{
_history.Remove(tag, group);
}
}
/// <summary>
/// Removes a group of toast notifications, identified by the specified group label, from action center.
/// </summary>
/// <param name="group">The group label of the toast notifications to be removed.</param>
public void RemoveGroup(string group)
{
if (_aumid != null)
{
_history.RemoveGroup(group, _aumid);
}
else
{
_history.RemoveGroup(group);
}
}
}
/// <summary>
/// Apps must implement this activator to handle notification activation.
/// </summary>
public abstract class NotificationActivator : NotificationActivator.INotificationActivationCallback
{
public void Activate(string appUserModelId, string invokedArgs, NOTIFICATION_USER_INPUT_DATA[] data, uint dataCount)
{
OnActivated(invokedArgs, new NotificationUserInput(data), appUserModelId);
}
/// <summary>
/// This method will be called when the user clicks on a foreground or background activation on a toast. Parent app must implement this method.
/// </summary>
/// <param name="arguments">The arguments from the original notification. This is either the launch argument if the user clicked the body of your toast, or the arguments from a button on your toast.</param>
/// <param name="userInput">Text and selection values that the user entered in your toast.</param>
/// <param name="appUserModelId">Your AUMID.</param>
public abstract void OnActivated(string arguments, NotificationUserInput userInput, string appUserModelId);
// These are the new APIs for Windows 10
#region NewAPIs
[StructLayout(LayoutKind.Sequential), Serializable]
public struct NOTIFICATION_USER_INPUT_DATA
{
[MarshalAs(UnmanagedType.LPWStr)]
public string Key;
[MarshalAs(UnmanagedType.LPWStr)]
public string Value;
}
[ComImport,
Guid("53E31837-6600-4A81-9395-75CFFE746F94"), ComVisible(true),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface INotificationActivationCallback
{
void Activate(
[In, MarshalAs(UnmanagedType.LPWStr)]
string appUserModelId,
[In, MarshalAs(UnmanagedType.LPWStr)]
string invokedArgs,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]
NOTIFICATION_USER_INPUT_DATA[] data,
[In, MarshalAs(UnmanagedType.U4)]
uint dataCount);
}
#endregion
}
/// <summary>
/// Text and selection values that the user entered on your notification. The Key is the ID of the input, and the Value is what the user entered.
/// </summary>
public class NotificationUserInput : IReadOnlyDictionary<string, string>
{
private NotificationActivator.NOTIFICATION_USER_INPUT_DATA[] _data;
internal NotificationUserInput(NotificationActivator.NOTIFICATION_USER_INPUT_DATA[] data)
{
_data = data;
}
public string this[string key] => _data.First(i => i.Key == key).Value;
public IEnumerable<string> Keys => _data.Select(i => i.Key);
public IEnumerable<string> Values => _data.Select(i => i.Value);
public int Count => _data.Length;
public bool ContainsKey(string key)
{
return _data.Any(i => i.Key == key);
}
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
return _data.Select(i => new KeyValuePair<string, string>(i.Key, i.Value)).GetEnumerator();
}
public bool TryGetValue(string key, out string value)
{
foreach (var item in _data)
{
if (item.Key == key)
{
value = item.Value;
return true;
}
}
value = null;
return false;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@ -35,7 +35,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Debug\</OutputPath>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
@ -51,7 +51,8 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<RunCodeAnalysis>true</RunCodeAnalysis>
<RunCodeAnalysis>false</RunCodeAnalysis>
<CodeAnalysisRuleSet>BasicCorrectnessRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Resources\DisplayMagician.ico</ApplicationIcon>
@ -78,6 +79,7 @@
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.XML" />
@ -86,7 +88,10 @@
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="DesktopNotificationActivator.cs" />
<Compile Include="DesktopNotificationManagerCompat.cs" />
<Compile Include="GameLibraries\Game.cs" />
<Compile Include="GameLibraries\GameUtils.cs" />
<Compile Include="GameLibraries\SteamAppInfoParser\AppInfo.cs" />
<Compile Include="GameLibraries\SteamAppInfoParser\EUniverse.cs" />
<Compile Include="GameLibraries\SteamAppInfoParser\Package.cs" />
@ -95,6 +100,7 @@
<Compile Include="GameLibraries\UplayConfigurationParser\UplayConfigurationParser.cs" />
<Compile Include="GameLibraries\UplayLibrary.cs" />
<Compile Include="GameLibraries\SteamLibrary.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="IconFromFile.cs" />
<Compile Include="IconUtils.cs" />
<Compile Include="ProgressReporter.cs" />
@ -119,6 +125,12 @@
<Compile Include="UIForms\MaskedDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UIForms\SettingsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UIForms\SettingsForm.Designer.cs">
<DependentUpon>SettingsForm.cs</DependentUpon>
</Compile>
<Compile Include="UIForms\ShortcutAdaptor.cs" />
<Compile Include="UIForms\ProfileAdaptor.cs" />
<Compile Include="UIForms\MainForm.cs">
@ -175,6 +187,9 @@
<DependentUpon>MainForm.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="UIForms\SettingsForm.resx">
<DependentUpon>SettingsForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UIForms\ShortcutForm.resx">
<DependentUpon>ShortcutForm.cs</DependentUpon>
</EmbeddedResource>
@ -214,6 +229,9 @@
<PackageReference Include="AudioSwitcher.AudioApi.CoreAudio">
<Version>4.0.0-alpha5</Version>
</PackageReference>
<PackageReference Include="Autoupdater.NET.Official">
<Version>1.6.4</Version>
</PackageReference>
<PackageReference Include="CircularProgressBar">
<Version>2.8.0.16</Version>
</PackageReference>
@ -243,12 +261,21 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications">
<Version>6.1.1</Version>
</PackageReference>
<PackageReference Include="MintPlayer.IconUtils">
<Version>1.0.4</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
</PackageReference>
<PackageReference Include="NLog">
<Version>4.7.6</Version>
</PackageReference>
<PackageReference Include="QueryString.NET">
<Version>1.0.0</Version>
</PackageReference>
<PackageReference Include="ValveKeyValue">
<Version>0.3.1.152</Version>
</PackageReference>
@ -276,9 +303,9 @@
<Content Include="Resources\redarrows.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DisplayMagician.Shared\DisplayMagician.Shared.csproj">
<ProjectReference Include="..\DisplayMagicianShared\DisplayMagicianShared.csproj">
<Project>{1cacda43-01c7-4cd4-bf6e-9421a29510fc}</Project>
<Name>DisplayMagician.Shared</Name>
<Name>DisplayMagicianShared</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
@ -291,6 +318,15 @@
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="Shell32">
<Guid>{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -4,8 +4,8 @@ using System.Drawing;
using System.Linq;
using WindowsDisplayAPI;
using WindowsDisplayAPI.DisplayConfig;
using DisplayMagician.Shared;
using DisplayMagician.Shared.Topology;
using DisplayMagicianShared;
using DisplayMagicianShared.Topology;
namespace DisplayMagician
{
@ -15,7 +15,7 @@ namespace DisplayMagician
{
Name = display.DeviceName;
Path = display.DevicePath;
var index = Path.IndexOf("{", StringComparison.InvariantCultureIgnoreCase);
var index = Path.IndexOf("{", StringComparison.OrdinalIgnoreCase);
if (index > 0)
{

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management;
namespace DisplayMagician.GameLibraries
{
class GameUtils
{
public static string GetMainModuleFilepath(int processId)
{
string wmiQueryString = "SELECT ProcessId, ExecutablePath FROM Win32_Process WHERE ProcessId = " + processId;
using (var searcher = new ManagementObjectSearcher(wmiQueryString))
{
using (var results = searcher.Get())
{
ManagementObject mo = results.Cast<ManagementObject>().FirstOrDefault();
if (mo != null)
{
return (string)mo["ExecutablePath"];
}
}
}
return null;
}
}
}

View File

@ -3,39 +3,15 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using DisplayMagician.Resources;
using DisplayMagician.Shared;
//using HtmlAgilityPack;
using Microsoft.Win32;
using Newtonsoft.Json;
//using VdfParser;
//using Gameloop.Vdf;
using System.Collections.ObjectModel;
using ValveKeyValue;
using System.Security.Cryptography;
using System.ServiceModel.Configuration;
using DisplayMagician.GameLibraries.SteamAppInfoParser;
using TsudaKageyu;
using System.Drawing.IconLib;
using System.Drawing.IconLib.Exceptions;
using System.Diagnostics;
namespace DisplayMagician.GameLibraries
{
public class SteamGame : Game
{
/*private static string SteamLibrary.SteamExe;
private static string SteamLibrary.SteamPath;
private static string _steamConfigVdfFile;
private static string _registrySteamKey = @"SOFTWARE\\Valve\\Steam";
private static string _registryAppsKey = $@"{_registrySteamKey}\\Apps";*/
private string _gameRegistryKey;
private uint _steamGameId;
private string _steamGameName;
@ -46,15 +22,6 @@ namespace DisplayMagician.GameLibraries
private string _steamGameIconPath;
private static List<SteamGame> _allInstalledSteamGames = null;
/*private struct SteamAppInfo
{
public uint GameID;
public string GameName;
public List<string> GameExes;
public string GameInstallDir;
public string GameSteamIconPath;
}*/
static SteamGame()
{
ServicePointManager.ServerCertificateValidationCallback +=
@ -104,49 +71,35 @@ namespace DisplayMagician.GameLibraries
public override string Directory
{
get => _steamGameExePath;
set => _steamGameExePath = value;
get => _steamGameDir;
set => _steamGameDir = value;
}
public override bool IsRunning
{
get
{
/*try
int numGameProcesses = 0;
List<Process> gameProcesses = Process.GetProcessesByName(_steamGameProcessName).ToList();
foreach (Process gameProcess in gameProcesses)
{
using (
var key = Registry.CurrentUser.OpenSubKey(_gameRegistryKey, RegistryKeyPermissionCheck.ReadSubTree))
try
{
if ((int)key?.GetValue(@"Running", 0) == 1)
if (gameProcess.MainModule.FileName.StartsWith(_steamGameExePath))
numGameProcesses++;
}
catch (Exception ex)
{
if (GameUtils.GetMainModuleFilepath(gameProcess.Id).StartsWith(_steamGameExePath))
numGameProcesses++;
}
}
if (numGameProcesses > 0)
return true;
}
else
return false;
}
}
catch (SecurityException ex)
{
Console.WriteLine($"SteamGame/IsRunning securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
if (ex.Source != null)
Console.WriteLine("SecurityException source: {0} - Message: {1}", ex.Source, ex.Message);
throw;
}
catch (IOException ex)
{
// Extract some information from this exception, and then
// throw it to the parent method.
Console.WriteLine($"SteamGame/IsRunning ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
if (ex.Source != null)
Console.WriteLine("IOException source: {0} - Message: {1}", ex.Source, ex.Message);
throw;
}*/
bool isRunning = Process.GetProcessesByName(_steamGameProcessName)
.FirstOrDefault(p => p.MainModule.FileName
.StartsWith(ExePath,StringComparison.OrdinalIgnoreCase)) != default(Process);
return isRunning;
}
}
public override bool IsUpdating
{
@ -183,7 +136,8 @@ namespace DisplayMagician.GameLibraries
}
}
public bool CopyTo(SteamGame steamGame)
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
public bool CopyInto(SteamGame steamGame)
{
if (!(steamGame is SteamGame))
return false;
@ -193,6 +147,7 @@ namespace DisplayMagician.GameLibraries
steamGame.Id = Id;
steamGame.Name = Name;
steamGame.ExePath = ExePath;
steamGame.Directory = Directory;
return true;
}

View File

@ -131,7 +131,7 @@ namespace DisplayMagician.GameLibraries
{
// We update the existing Shortcut with the data over
SteamGame steamGameToUpdate = GetSteamGame(steamGame.Id.ToString());
steamGame.CopyTo(steamGameToUpdate);
steamGame.CopyInto(steamGameToUpdate);
}
else
{
@ -190,6 +190,7 @@ namespace DisplayMagician.GameLibraries
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
public static bool ContainsSteamGame(SteamGame steamGame)
{
if (!(steamGame is SteamGame))

View File

@ -3,39 +3,13 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using DisplayMagician.Resources;
using DisplayMagician.Shared;
//using HtmlAgilityPack;
using Microsoft.Win32;
using Newtonsoft.Json;
//using VdfParser;
//using Gameloop.Vdf;
using System.Collections.ObjectModel;
using ValveKeyValue;
using System.Security.Cryptography;
using System.ServiceModel.Configuration;
//using DisplayMagician.GameLibraries.UplayAppInfoParser;
using TsudaKageyu;
using System.Drawing.IconLib;
using System.Drawing.IconLib.Exceptions;
using System.Diagnostics;
namespace DisplayMagician.GameLibraries
{
public class UplayGame : Game
{
/*private static string UplayLibrary.UplayExe;
private static string UplayLibrary.UplayPath;
private static string _uplayConfigVdfFile;
private static string _registryUplayKey = @"SOFTWARE\\Valve\\Uplay";
private static string _registryAppsKey = $@"{_registryUplayKey}\\Apps";*/
private string _gameRegistryKey;
private uint _uplayGameId;
private string _uplayGameName;
@ -46,15 +20,6 @@ namespace DisplayMagician.GameLibraries
private string _uplayGameIconPath;
private static List<UplayGame> _allInstalledUplayGames = null;
/*private struct UplayAppInfo
{
public uint GameID;
public string GameName;
public List<string> GameExes;
public string GameInstallDir;
public string GameUplayIconPath;
}*/
static UplayGame()
{
ServicePointManager.ServerCertificateValidationCallback +=
@ -107,49 +72,35 @@ namespace DisplayMagician.GameLibraries
public override string Directory
{
get => _uplayGameExePath;
set => _uplayGameExePath = value;
get => _uplayGameDir;
set => _uplayGameDir = value;
}
public override bool IsRunning
{
get
{
/*try
int numGameProcesses = 0;
List<Process> gameProcesses = Process.GetProcessesByName(_uplayGameProcessName).ToList();
foreach (Process gameProcess in gameProcesses)
{
using (
var key = Registry.CurrentUser.OpenSubKey(_gameRegistryKey, RegistryKeyPermissionCheck.ReadSubTree))
try
{
if ((int)key?.GetValue(@"Running", 0) == 1)
if (gameProcess.MainModule.FileName.StartsWith(_uplayGameExePath))
numGameProcesses++;
}
catch (Exception ex)
{
if (GameUtils.GetMainModuleFilepath(gameProcess.Id).StartsWith(_uplayGameExePath))
numGameProcesses++;
}
}
if (numGameProcesses > 0)
return true;
}
else
return false;
}
}
catch (SecurityException ex)
{
Console.WriteLine($"UplayGame/IsRunning securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
if (ex.Source != null)
Console.WriteLine("SecurityException source: {0} - Message: {1}", ex.Source, ex.Message);
throw;
}
catch (IOException ex)
{
// Extract some information from this exception, and then
// throw it to the parent method.
Console.WriteLine($"UplayGame/IsRunning ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
if (ex.Source != null)
Console.WriteLine("IOException source: {0} - Message: {1}", ex.Source, ex.Message);
throw;
}*/
bool isRunning = Process.GetProcessesByName(_uplayGameProcessName)
.FirstOrDefault(p => p.MainModule.FileName
.StartsWith(ExePath, StringComparison.OrdinalIgnoreCase)) != default(Process);
return isRunning;
}
}
/*public override bool IsUpdating
{
@ -186,6 +137,7 @@ namespace DisplayMagician.GameLibraries
}
}*/
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
public bool CopyTo(UplayGame uplayGame)
{
if (!(uplayGame is UplayGame))
@ -196,6 +148,7 @@ namespace DisplayMagician.GameLibraries
uplayGame.Id = Id;
uplayGame.Name = Name;
uplayGame.ExePath = ExePath;
uplayGame.Directory = Directory;
return true;
}

View File

@ -173,6 +173,7 @@ namespace DisplayMagician.GameLibraries
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
public static bool ContainsUplayGame(UplayGame uplayGame)
{
if (!(uplayGame is UplayGame))
@ -300,7 +301,7 @@ namespace DisplayMagician.GameLibraries
// Go through every record and attempt to parse it
foreach (string uplayEntry in uplayConfigFile) {
// Skip any Uplay entry records that don't start with 'version:'
if (!uplayEntry.StartsWith("version:",StringComparison.InvariantCultureIgnoreCase))
if (!uplayEntry.StartsWith("version:",StringComparison.OrdinalIgnoreCase))
continue;
//Split the record into entrylines
@ -398,7 +399,7 @@ namespace DisplayMagician.GameLibraries
if (gotGameFileName && gotGameId && gotGameIconPath && gotGameName)
break;
// This line contains the Game Name
if (uplayEntryLines[i].StartsWith(" name:", StringComparison.InvariantCultureIgnoreCase) && !gotGameName)
if (uplayEntryLines[i].StartsWith(" name:", StringComparison.OrdinalIgnoreCase) && !gotGameName)
{
mc = Regex.Matches(uplayEntryLines[i], @" name\: (.*)");
uplayGameAppInfo.GameName = mc[0].Groups[1].ToString();
@ -409,7 +410,7 @@ namespace DisplayMagician.GameLibraries
}
gotGameName = true;
}
else if (uplayEntryLines[i].StartsWith(" icon_image:", StringComparison.InvariantCultureIgnoreCase) && !gotGameIconPath)
else if (uplayEntryLines[i].StartsWith(" icon_image:", StringComparison.OrdinalIgnoreCase) && !gotGameIconPath)
{
mc = Regex.Matches(uplayEntryLines[i], @"icon_image: (.*)");
string iconImageFileName = mc[0].Groups[1].ToString();

Binary file not shown.

View File

@ -8,6 +8,9 @@ namespace DisplayMagician.InterProcess
{
internal class IPCClient : ClientBase<IService>, IService
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public IPCClient(Process process)
: base(
new ServiceEndpoint(
@ -71,9 +74,10 @@ namespace DisplayMagician.InterProcess
{
if (process.Id != thisProcess.Id)
{
IPCClient processChannel = null;
try
{
var processChannel = new IPCClient(process);
processChannel = new IPCClient(process);
if (processChannel.Status == status)
{
@ -82,6 +86,8 @@ namespace DisplayMagician.InterProcess
}
catch (Exception ex)
{
processChannel = null;
logger.Error(ex, $"IPCClient/QueryByStatus: Couldn't create an IPC Client");
Console.WriteLine($"IPCClient/QueryByStatus exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
// ignored
}

View File

@ -10,6 +10,8 @@ namespace DisplayMagician.InterProcess
{
private static ServiceHost _serviceHost;
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private IPCService()
{
Status = InstanceStatus.Busy;
@ -53,6 +55,7 @@ namespace DisplayMagician.InterProcess
}
catch (Exception ex)
{
logger.Error(ex, $"IPCService/StartService exception: Couldn't create an IPC Service");
Console.WriteLine($"IPCService/StartService exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
try
{
@ -60,6 +63,7 @@ namespace DisplayMagician.InterProcess
}
catch (Exception ex2)
{
logger.Error(ex, $"IPCService/StartService exception: Couldn't close an IPC Service after error creating it");
Console.WriteLine($"IPCService/StartService exception 2: {ex2.Message}: {ex2.InnerException}");
// ignored
}

View File

@ -1,25 +1,20 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using McMaster.Extensions.CommandLineUtils;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using DisplayMagician.InterProcess;
using DisplayMagician.Resources;
using DisplayMagician.GameLibraries;
using DisplayMagician.Shared;
using DisplayMagicianShared;
using DisplayMagician.UIForms;
using System.Net.NetworkInformation;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Diagnostics.Contracts;
using DesktopNotifications;
using System.Runtime.Serialization;
namespace DisplayMagician {
@ -32,18 +27,23 @@ namespace DisplayMagician {
internal static class Program
{
internal static string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DisplayMagician");
public static string AppStartupPath = Application.StartupPath;
public static string AppIconPath = Path.Combine(Program.AppDataPath, $"Icons");
public static string AppProfilePath = Path.Combine(Program.AppDataPath, $"Profiles");
public static string AppShortcutPath = Path.Combine(Program.AppDataPath, $"Shortcuts");
public static string AppLogPath = Path.Combine(Program.AppDataPath, $"Logs");
public static string AppDisplayMagicianIconFilename = Path.Combine(AppIconPath, @"DisplayMagician.ico");
public static string AppOriginIconFilename = Path.Combine(AppIconPath, @"Origin.ico");
public static string AppSteamIconFilename = Path.Combine(AppIconPath, @"Steam.ico");
public static string AppUplayIconFilename = Path.Combine(AppIconPath, @"Uplay.ico");
public static string AppEpicIconFilename = Path.Combine(AppIconPath, @"Epic.ico");
public static bool AppToastActivated = false;
public static bool WaitingForGameToExit = false;
public static ProgramSettings AppProgramSettings;
public static MainForm AppMainForm;
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
/// <summary>
/// The main entry point for the application.
@ -52,6 +52,72 @@ namespace DisplayMagician {
private static int Main(string[] args)
{
// This sets the Application User Model ID to "LittleBitBig.DisplayMagician" so that
// Windows 10 recognises the application, and allows features such as Toasts,
// taskbar pinning and similar.
// Register AUMID, COM server, and activator
DesktopNotificationManagerCompat.RegisterAumidAndComServer<DesktopNotificationActivator>(ShellUtils.AUMID);
DesktopNotificationManagerCompat.RegisterActivator<DesktopNotificationActivator>();
// Prepare NLog for logging
var config = new NLog.Config.LoggingConfiguration();
// Targets where to log to: File and Console
//string date = DateTime.Now.ToString("yyyyMMdd.HHmmss");
string AppLogFilename = Path.Combine(Program.AppLogPath, $"DisplayMagician.log");
// Create the Logging Dir if it doesn't exist so that it's avilable for all
// parts of the program to use
if (!Directory.Exists(AppLogPath))
{
try
{
Directory.CreateDirectory(AppLogPath);
}
catch (Exception ex)
{
Console.WriteLine($"Program/StartUpNormally exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
}
}
var logfile = new NLog.Targets.FileTarget("logfile") {
FileName = AppLogFilename
};
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
// Load the program settings
AppProgramSettings = ProgramSettings.LoadSettings();
// Rules for mapping loggers to targets
NLog.LogLevel logLevel = null;
switch (AppProgramSettings.LogLevel)
{
case "Trace":
logLevel = NLog.LogLevel.Trace;
break;
case "Info":
logLevel = NLog.LogLevel.Info;
break;
case "Warn":
logLevel = NLog.LogLevel.Warn;
break;
case "Error":
logLevel = NLog.LogLevel.Error;
break;
case "Debug":
logLevel = NLog.LogLevel.Debug;
break;
default:
logLevel = NLog.LogLevel.Warn;
break;
}
config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, logconsole);
config.AddRule(logLevel, NLog.LogLevel.Fatal, logfile);
// Apply config
NLog.LogManager.Configuration = config;
// Write the Application Name
Console.WriteLine($"{Application.ProductName} v{Application.ProductVersion}");
for (int i = 0; i <= Application.ProductName.Length + Application.ProductVersion .Length; i++)
@ -67,10 +133,12 @@ namespace DisplayMagician {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Load the program settings
AppProgramSettings = ProgramSettings.LoadSettings();
var app = new CommandLineApplication();
var app = new CommandLineApplication
{
AllowArgumentSeparator = true,
UnrecognizedArgumentHandling = UnrecognizedArgumentHandling.StopParsingAndCollect,
};
//app.Name = "HeliosDM+";
//app.Name = Assembly.GetEntryAssembly().GetName().Name;
@ -122,18 +190,49 @@ namespace DisplayMagician {
ApplyProfile(profileToUse);
return 0;
}
catch (Exception)
catch (Exception ex)
{
logger.Error(ex, $"Program/Main exception running ApplyProfile(profileToUse)");
return 1;
}
});
});
// This is the CreateProfile command
app.Command(DisplayMagicianStartupAction.CreateProfile.ToString(), (createProfileCmd) =>
{
//description and help text of the command.
createProfileCmd.Description = "Use this command to go directly to the create display profile screen.";
createProfileCmd.OnExecute(() =>
{
Console.WriteLine("Starting up and creating a new Display Profile...");
StartUpApplication(DisplayMagicianStartupAction.CreateProfile);
return 0;
});
});
app.OnExecute(() =>
{
// Add a workaround to handle the weird way that Windows tell us that DisplayMagician
// was started from a Notification Toast when closed (Windows 10)
// Due to the way that CommandLineUtils library works we need to handle this as
// 'Remaining Arguments'
if (app.RemainingArguments != null && app.RemainingArguments.Count > 0)
{
foreach (string myArg in app.RemainingArguments)
{
if (myArg.Equals("-ToastActivated"))
{
Program.AppToastActivated = true;
break;
}
}
}
Console.WriteLine("Starting Normally...");
StartUpNormally();
StartUpApplication();
return 0;
});
@ -147,6 +246,7 @@ namespace DisplayMagician {
}
catch (CommandParsingException ex)
{
logger.Error(ex, $"Program/Main exception parsing the Commands passed to the program");
Console.WriteLine("Didn't recognise the supplied commandline options: {0}", ex.Message);
}
catch (Exception ex)
@ -155,14 +255,21 @@ namespace DisplayMagician {
// You'll always want to catch this exception, otherwise it will generate a messy and confusing error for the end user.
// the message will usually be something like:
// "Unrecognized command or argument '<invalid-command>'"
logger.Error(ex, $"Program/Main general exception during app.Execute(args)");
Console.WriteLine($"Program/Main exception: Unable to execute application - {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
}
// Remove all the notifications we have set as they don't matter now!
DesktopNotificationManagerCompat.History.Clear();
// Shutdown NLog
NLog.LogManager.Shutdown();
// Exit with a 0 Errorlevel to indicate everything worked fine!
return 0;
}
private static void StartUpNormally()
private static void StartUpApplication(DisplayMagicianStartupAction startupAction = DisplayMagicianStartupAction.StartUpNormally)
{
@ -178,7 +285,6 @@ namespace DisplayMagician {
throw new Exception(Language.Can_not_open_a_named_pipe_for_Inter_process_communication);
}
// Create the Shortcut Icon Cache if it doesn't exist so that it's avilable for all the program
if (!Directory.Exists(AppIconPath))
{
@ -189,22 +295,7 @@ namespace DisplayMagician {
catch (Exception ex)
{
Console.WriteLine($"Program/StartUpNormally exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
// TODO
}
}
// Create the Shortcut Icon Cache if it doesn't exist so that it's avilable for all the program
if (!Directory.Exists(AppIconPath))
{
try
{
Directory.CreateDirectory(AppIconPath);
}
catch (Exception ex)
{
Console.WriteLine($"Program/StartUpNormally exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
// TODO
logger.Error(ex, $"Program/StartUpNormally exception while trying to create directory {AppIconPath}");
}
}
@ -253,14 +344,25 @@ namespace DisplayMagician {
catch (Exception ex)
{
Console.WriteLine($"Program/StartUpNormally exception 2: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
logger.Error(ex, $"Program/StartUpNormally exception create Icon files for future use in {AppIconPath}");
}
IPCService.GetInstance().Status = InstanceStatus.User;
Application.Run(new UIForms.MainForm());
// Run the program with normal startup
if (startupAction == DisplayMagicianStartupAction.StartUpNormally)
{
AppMainForm = new MainForm();
Application.Run(AppMainForm);
}
else if (startupAction == DisplayMagicianStartupAction.CreateProfile)
Application.Run(new DisplayProfileForm());
}
catch (Exception ex)
{
Console.WriteLine($"Program/StartUpNormally exception 3: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
logger.Error(ex, $"Program/StartUpNormally top level exception");
MessageBox.Show(
ex.Message,
Language.Fatal_Error,
@ -392,6 +494,7 @@ namespace DisplayMagician {
}
catch (AggregateException ae)
{
logger.Error(ae, $"Program/ApplyProfile exception during applyTopologyTask");
foreach (var e in ae.InnerExceptions)
{
// Handle the custom exception.
@ -422,6 +525,7 @@ namespace DisplayMagician {
}
catch (AggregateException ae)
{
logger.Error(ae, $"Program/ApplyProfile exception during applyPathInfoTask");
foreach (var e in ae.InnerExceptions)
{
// Handle the custom exception.
@ -499,6 +603,7 @@ namespace DisplayMagician {
}
catch (AggregateException ae)
{
logger.Error(ae, $"Program/LoadGamesInBackground exception during loadGamesTasks");
Console.WriteLine("Program/LoadGamesInBackground : Task exception!");
foreach (var e in ae.InnerExceptions)
{
@ -540,19 +645,40 @@ namespace DisplayMagician {
public class ApplyTopologyException : Exception
{
public ApplyTopologyException(String message) : base(message)
public ApplyTopologyException()
{ }
public ApplyTopologyException(string message) : base(message)
{ }
public ApplyTopologyException(string message, Exception innerException) : base(message, innerException)
{ }
public ApplyTopologyException(SerializationInfo info, StreamingContext context) : base(info, context)
{ }
}
public class ApplyPathInfoException : Exception
{
public ApplyPathInfoException(String message) : base(message)
public ApplyPathInfoException()
{ }
public ApplyPathInfoException(string message) : base(message)
{ }
public ApplyPathInfoException(string message, Exception innerException) : base(message, innerException)
{ }
public ApplyPathInfoException(SerializationInfo info, StreamingContext context) : base(info, context)
{ }
}
public class LoadingInstalledGamesException : Exception
{
public LoadingInstalledGamesException(String message) : base(message)
public LoadingInstalledGamesException()
{ }
public LoadingInstalledGamesException(string message) : base(message)
{ }
public LoadingInstalledGamesException(string message, Exception innerException) : base(message, innerException)
{ }
public LoadingInstalledGamesException(SerializationInfo info, StreamingContext context) : base(info, context)
{ }
}
}

View File

@ -5,9 +5,11 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NLog;
namespace DisplayMagician
{
public class ProgramSettings
{
#region Class Variables
@ -19,6 +21,7 @@ namespace DisplayMagician
#region Instance Variables
private bool _minimiseOnStart = false;
private string _logLevel = NLog.LogLevel.Warn.ToString();
#endregion
#region Class Properties
@ -38,6 +41,48 @@ namespace DisplayMagician
}
}
public string LogLevel
{
get
{
return _logLevel;
}
set
{
switch (value.ToLower())
{
case "trace":
_logLevel = NLog.LogLevel.Trace.ToString();
break;
case "debug":
_logLevel = NLog.LogLevel.Debug.ToString();
break;
case "info":
_logLevel = NLog.LogLevel.Info.ToString();
break;
case "warn":
_logLevel = NLog.LogLevel.Warn.ToString();
break;
case "error":
_logLevel = NLog.LogLevel.Error.ToString();
break;
case "fatal":
_logLevel = NLog.LogLevel.Fatal.ToString();
break;
default:
_logLevel = NLog.LogLevel.Warn.ToString();
break;
}
// Because a value has changed, we need to save the setting
// to remember it for later.
if (_programSettingsLoaded)
SaveSettings();
}
}
public static Version FileVersion
{
get => new Version(1, 0, 0);
@ -76,6 +121,11 @@ namespace DisplayMagician
}
}
}
else
{
programSettings = new ProgramSettings();
programSettings.SaveSettings();
}
// If there isn't any settings in the file then create a new ProgramSettings object
if (programSettings == null)

View File

@ -1,4 +1,5 @@
using System.Resources;
using System;
using System.Resources;
using System.Reflection;
using System.Runtime.InteropServices;
@ -9,9 +10,9 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("DisplayMagician")]
[assembly: AssemblyDescription("Automatically run your games with a different display profile and revert when finished.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("LittleBitBig")]
[assembly: AssemblyProduct("DisplayMagician")]
[assembly: AssemblyCopyright("Copyright © Terry MacDonald 2020-2021, Copyright © Soroush Falahati 2017-2020")]
[assembly: AssemblyCopyright("Copyright © Terry MacDonald 2020-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -19,11 +20,11 @@ using System.Runtime.InteropServices;
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
[assembly: ComVisible(true)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1cbf2d06-199b-4d40-a15d-34fb9ed526c7")]
[assembly: Guid("e4ceaf5e-ad01-4695-b179-31168eb74c48")]
// Version information for an assembly consists of the following four values:
//
@ -36,6 +37,8 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.9.*")]
[assembly: AssemblyFileVersion("0.9.9.0")]
[assembly: AssemblyVersion("0.2.1.*")]
[assembly: AssemblyFileVersion("0.2.1.0")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: CLSCompliant(true)]

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,13 @@
using AudioSwitcher.AudioApi.CoreAudio;
using DisplayMagician.GameLibraries;
using DisplayMagician.InterProcess;
using DisplayMagician.Resources;
using DisplayMagician.Shared;
using DisplayMagicianShared;
using Microsoft.Toolkit.Uwp.Notifications;
using Newtonsoft.Json;
using NvAPIWrapper.Mosaic;
using NvAPIWrapper.Native.Mosaic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing.IconLib;
using System.IO;
using System.Linq;
using System.Text;
@ -18,6 +15,8 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
namespace DisplayMagician
{
@ -33,6 +32,7 @@ namespace DisplayMagician
private static string _shortcutStorageJsonFileName = Path.Combine(AppShortcutStoragePath, $"Shortcuts_{Version.ToString(2)}.json");
private static string uuidV4Regex = @"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$";
private static CoreAudioController _audioController = null;
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
#endregion
#region Class Constructors
@ -52,7 +52,8 @@ namespace DisplayMagician
}
catch (Exception ex)
{
Console.WriteLine($"ShortcutItem/Instansiation exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
//Console.WriteLine($"ShortcutItem/Instansiation exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
logger.Error(ex, $"ShortcutRepository/Instansiation exception during class construction");
// ignored
}
@ -135,7 +136,7 @@ namespace DisplayMagician
return false;
// Remove the Shortcut Icons from the Cache
List<ShortcutItem> shortcutsToRemove = _allShortcuts.FindAll(item => item.UUID.Equals(shortcut.UUID, StringComparison.InvariantCultureIgnoreCase));
List<ShortcutItem> shortcutsToRemove = _allShortcuts.FindAll(item => item.UUID.Equals(shortcut.UUID, StringComparison.OrdinalIgnoreCase));
foreach (ShortcutItem shortcutToRemove in shortcutsToRemove)
{
try
@ -151,7 +152,7 @@ namespace DisplayMagician
}
// Remove the shortcut from the list.
int numRemoved = _allShortcuts.RemoveAll(item => item.UUID.Equals(shortcut.UUID, StringComparison.InvariantCultureIgnoreCase));
int numRemoved = _allShortcuts.RemoveAll(item => item.UUID.Equals(shortcut.UUID, StringComparison.OrdinalIgnoreCase));
if (numRemoved == 1)
{
@ -177,13 +178,13 @@ namespace DisplayMagician
Match match = Regex.Match(shortcutNameOrUuid, uuidV4Regex, RegexOptions.IgnoreCase);
if (match.Success)
{
shortcutsToRemove = _allShortcuts.FindAll(item => item.UUID.Equals(shortcutNameOrUuid, StringComparison.InvariantCultureIgnoreCase));
numRemoved = _allShortcuts.RemoveAll(item => item.UUID.Equals(shortcutNameOrUuid, StringComparison.InvariantCultureIgnoreCase));
shortcutsToRemove = _allShortcuts.FindAll(item => item.UUID.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase));
numRemoved = _allShortcuts.RemoveAll(item => item.UUID.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase));
}
else
{
shortcutsToRemove = _allShortcuts.FindAll(item => item.Name.Equals(shortcutNameOrUuid, StringComparison.InvariantCultureIgnoreCase));
numRemoved = _allShortcuts.RemoveAll(item => item.Name.Equals(shortcutNameOrUuid, StringComparison.InvariantCultureIgnoreCase));
shortcutsToRemove = _allShortcuts.FindAll(item => item.Name.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase));
numRemoved = _allShortcuts.RemoveAll(item => item.Name.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase));
}
// Remove the Shortcut Icons from the Cache
foreach (ShortcutItem shortcutToRemove in shortcutsToRemove)
@ -220,7 +221,7 @@ namespace DisplayMagician
foreach (ShortcutItem testShortcut in _allShortcuts)
{
if (testShortcut.UUID.Equals(shortcut.UUID,StringComparison.InvariantCultureIgnoreCase))
if (testShortcut.UUID.Equals(shortcut.UUID,StringComparison.OrdinalIgnoreCase))
return true;
}
@ -239,7 +240,7 @@ namespace DisplayMagician
{
foreach (ShortcutItem testShortcut in _allShortcuts)
{
if (testShortcut.UUID.Equals(shortcutNameOrUuid, StringComparison.InvariantCultureIgnoreCase))
if (testShortcut.UUID.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
return true;
}
@ -248,7 +249,7 @@ namespace DisplayMagician
{
foreach (ShortcutItem testShortcut in _allShortcuts)
{
if (testShortcut.Name.Equals(shortcutNameOrUuid, StringComparison.InvariantCultureIgnoreCase))
if (testShortcut.Name.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
return true;
}
@ -270,7 +271,7 @@ namespace DisplayMagician
{
foreach (ShortcutItem testShortcut in _allShortcuts)
{
if (testShortcut.UUID.Equals(shortcutNameOrUuid, StringComparison.InvariantCultureIgnoreCase))
if (testShortcut.UUID.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
return testShortcut;
}
@ -279,7 +280,7 @@ namespace DisplayMagician
{
foreach (ShortcutItem testShortcut in _allShortcuts)
{
if (testShortcut.Name.Equals(shortcutNameOrUuid, StringComparison.InvariantCultureIgnoreCase))
if (testShortcut.Name.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
return testShortcut;
}
@ -296,7 +297,7 @@ namespace DisplayMagician
foreach (ShortcutItem testShortcut in ShortcutRepository.AllShortcuts)
{
if (testShortcut.ProfileUUID.Equals(newProfile.UUID, StringComparison.InvariantCultureIgnoreCase) && testShortcut.AutoName)
if (testShortcut.ProfileUUID.Equals(newProfile.UUID, StringComparison.OrdinalIgnoreCase) && testShortcut.AutoName)
{
testShortcut.ProfileToUse = newProfile;
testShortcut.AutoSuggestShortcutName();
@ -417,6 +418,7 @@ namespace DisplayMagician
(bool valid, string reason) = shortcutToUse.IsValid();
if (!valid)
{
logger.Error($"ShortcutRepository/RunShortcut error. shortcutToUse isn't valid");
MessageBox.Show(
$"Unable to run the shortcut '{shortcutToUse.Name}': {reason}",
@"Cannot run the Shortcut",
@ -447,12 +449,17 @@ namespace DisplayMagician
if (!Program.ApplyProfile(shortcutToUse.ProfileToUse))
{
Console.WriteLine($"ERROR - Cannot apply '{shortcutToUse.ProfileToUse.Name}' Display Profile");
logger.Error($"ShortcutRepository/RunShortcut cannot apply '{shortcutToUse.ProfileToUse.Name}' Display Profile");
}
}
// record the old audio device
bool needToChangeAudio = false;
CoreAudioDevice rollbackAudioDevice = _audioController.DefaultPlaybackDevice;
double rollbackAudioVolume = _audioController.DefaultPlaybackDevice.Volume;
if (!rollbackAudioDevice.FullName.Equals(shortcutToUse.AudioDevice))
needToChangeAudio = true;
// Change Audio Device (if one specified)
if (shortcutToUse.ChangeAudioDevice)
@ -479,6 +486,38 @@ namespace DisplayMagician
}
}
// record the old microphone device
bool needToChangeCaptureDevice = false;
CoreAudioDevice rollbackCaptureDevice = _audioController.DefaultCaptureDevice;
double rollbackCaptureVolume = _audioController.DefaultCaptureDevice.Volume;
if (!rollbackCaptureDevice.FullName.Equals(shortcutToUse.CaptureDevice))
needToChangeCaptureDevice = true;
// Change capture Device (if one specified)
if (shortcutToUse.ChangeCaptureDevice)
{
IEnumerable<CoreAudioDevice> captureDevices = _audioController.GetCaptureDevices();
foreach (CoreAudioDevice captureDevice in captureDevices)
{
if (captureDevice.FullName.Equals(shortcutToUse.CaptureDevice))
{
// use the Audio Device
captureDevice.SetAsDefault();
if (shortcutToUse.SetCaptureVolume)
{
Task myTask = new Task(() =>
{
captureDevice.SetVolumeAsync(Convert.ToDouble(shortcutToUse.CaptureVolume));
});
myTask.Start();
myTask.Wait(2000);
}
}
}
}
// Set the IP Service status back to what it was
IPCService.GetInstance().Status = rollbackInstanceStatus;
@ -516,7 +555,7 @@ namespace DisplayMagician
// This means we need to save the state if the temporaryIcon
// is false.
// Conversely, if temporaryIcon is true, then we need
// to create a NotifyIncon as MainFOrm isn't running to create
// to create a NotifyIncon as MainForm isn't running to create
// one for us already!
if (notifyIcon == null)
temporaryNotifyIcon = true;
@ -531,7 +570,6 @@ namespace DisplayMagician
notifyIcon = new NotifyIcon
{
Icon = Properties.Resources.DisplayMagician,
//Text = string.Format("DisplayMagician: Waiting for the Game {} to exit...", steamGameToRun.Name),
Visible = true
};
Application.DoEvents();
@ -539,6 +577,7 @@ namespace DisplayMagician
catch (Exception ex)
{
Console.WriteLine($"ShortcutRepository/RunShortcut exception: Trying to {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
logger.Error(ex, $"ShortcutRepository/RunShortcut exception setting NotifyIcon");
// ignored
}
}
@ -555,6 +594,7 @@ namespace DisplayMagician
Application.DoEvents();
}
// Now start the main game, and wait if we have to
if (shortcutToUse.Category.Equals(ShortcutCategory.Application))
{
@ -565,82 +605,117 @@ namespace DisplayMagician
else
process = System.Diagnostics.Process.Start(shortcutToUse.ExecutableNameAndPath);
// Create a list of processes to monitor
List<Process> processesToMonitor = new List<Process>();
// Work out if we are monitoring another process other than the main executable
// Figure out what we want to look for
string processNameToLookFor;
if (shortcutToUse.ProcessNameToMonitorUsesExecutable)
{
// If we are monitoring the same executable we started, then lets do that
processesToMonitor.Add(process);
// If we are monitoring the same executable we started, then lets do get that name ready
processNameToLookFor = System.IO.Path.GetFileNameWithoutExtension(shortcutToUse.ExecutableNameAndPath);
}
else
{
// Now wait a little while for all the processes we want to monitor to start up
var ticks = 0;
while (ticks < shortcutToUse.StartTimeout * 1000)
// If we are monitoring a different executable, then lets do get that name ready instead
processNameToLookFor = System.IO.Path.GetFileNameWithoutExtension(shortcutToUse.DifferentExecutableToMonitor);
}
// Now look for the thing we're supposed to monitor
// and wait until it starts up
List<Process> processesToMonitor = new List<Process>();
for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500)
{
// Look for the processes with the ProcessName we want (which in Windows is the filename without the extension)
processesToMonitor = System.Diagnostics.Process.GetProcessesByName(Path.GetFileNameWithoutExtension(shortcutToUse.DifferentExecutableToMonitor)).ToList();
// Look for the processes with the ProcessName we sorted out earlier
processesToMonitor = Process.GetProcessesByName(processNameToLookFor).ToList();
// If we have found one or more processes then we should be good to go
// so let's break
if (processesToMonitor.Count > 0)
{
logger.Debug($"Found {processesToMonitor.Count} '{processNameToLookFor}' processes have started");
break;
}
// Let's wait a little while if we couldn't find
// any processes yet
Thread.Sleep(300);
ticks += 300;
Thread.Sleep(500);
}
// If we have reached the timeout and we cannot detect any
// of the alernative executables to monitor, then ignore that
// setting, and just monitor the process we just started instead
// make sure we have things to monitor and alert if not
if (processesToMonitor.Count == 0)
{
processesToMonitor.Add(process);
}
logger.Error($"No '{processNameToLookFor}' processes found before waiting timeout");
}
// Store the process to monitor for later
IPCService.GetInstance().HoldProcessId = processesToMonitor.FirstOrDefault()?.Id ?? 0;
IPCService.GetInstance().Status = InstanceStatus.OnHold;
int substringStart = shortcutToUse.ExecutableNameAndPath.Length - 42;
if (substringStart < 0)
substringStart = 0;
notifyIcon.Text = $"DisplayMagician: Running {shortcutToUse.ExecutableNameAndPath.Substring(substringStart)}...";
//Application.DoEvents();
// Add a status notification icon in the status area
string notificationText = $"DisplayMagician: Running {shortcutToUse.ExecutableNameAndPath}...";
if (notificationText.Length >= 64)
{
string thingToRun = shortcutToUse.ExecutableNameAndPath.Substring(0, 35);
notifyIcon.Text = $"DisplayMagician: Running {thingToRun}...";
}
Application.DoEvents();
// Wait for the monitored process to exit
// Now we want to tell the user we're running an application!
// Construct the Windows toast content
ToastContentBuilder tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=runningApplication", ToastActivationType.Foreground)
.AddText($"Running {processNameToLookFor}", hintMaxLines: 1)
.AddText($"Waiting for all {processNameToLookFor} windows to exit...");
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
ToastContent toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
var doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
// And create the toast notification
var toast = new ToastNotification(doc);
// Remove any other Notifications from us
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
// And then show this notification
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
// Wait an extra few seconds to give the application time to settle down
Thread.Sleep(2000);
// if we have things to monitor, then we should start to wait for them
Console.WriteLine($"Waiting for all {processNameToLookFor} windows to exit.");
logger.Debug($"ShortcutRepository/RunShortcut - waiting for application {processNameToLookFor} to exit.");
if (processesToMonitor.Count > 0)
{
logger.Debug($"{processesToMonitor.Count} '{processNameToLookFor}' processes are still running");
while (true)
{
int processExitCount = 0;
// Check each process to see if it's exited
foreach (var p in processesToMonitor)
{
try
{
if (p.HasExited)
{
processExitCount++;
}
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"ShortcutRepository/RunShortcut exception 2: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
processExitCount++;
}
}
processesToMonitor = Process.GetProcessesByName(processNameToLookFor).ToList();
// Make sure that all processes have exited
// then start the shutdown process
if (processExitCount == processesToMonitor.Count)
// If we have no more processes left then we're done!
if (processesToMonitor.Count == 0)
{
logger.Debug($"No more '{processNameToLookFor}' processes are still running");
break;
}
}
}
Console.WriteLine($"{processNameToLookFor} has exited.");
logger.Debug($"ShortcutRepository/RunShortcut - Application {processNameToLookFor} has exited.");
// Tell the user that the application has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopDetected", ToastActivationType.Foreground)
.AddText($"{processNameToLookFor} was closed", hintMaxLines: 1)
.AddText($"All {processNameToLookFor} processes were shutdown and changes were reverted.");
toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
// And create the toast notification
toast = new ToastNotification(doc);
// Remove any other Notifications from us
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
// And then show it
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
}
else if (shortcutToUse.Category.Equals(ShortcutCategory.Game))
@ -662,26 +737,28 @@ namespace DisplayMagician
{
address += "/" + shortcutToUse.GameArguments;
}
logger.Debug($"ShortcutRepository/RunShortcut Steam launch address is {address}");
// Start the URI Handler to run Steam
Console.WriteLine($"Starting Steam Game: {steamGameToRun.Name}");
var steamProcess = Process.Start(address);
// Wait for Steam game to update if needed
var ticks = 0;
while (ticks < shortcutToUse.StartTimeout * 1000)
for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500)
{
if (steamGameToRun.IsRunning)
{
break;
}
Thread.Sleep(300);
if (!steamGameToRun.IsUpdating)
{
ticks += 300;
if (steamGameToRun.IsRunning)
{
logger.Info($"Found the '{steamGameToRun.Name}' process has started");
break;
}
}
// Delay 500ms
Thread.Sleep(500);
}
// Store the Steam Process ID for later
@ -695,24 +772,59 @@ namespace DisplayMagician
notifyIcon.Text = $"DisplayMagician: Running {steamGameToRun.Name.Substring(0, 41)}...";
Application.DoEvents();
// Wait 300ms for the game process to spawn
Thread.Sleep(300);
// Now check it's actually started
if (steamGameToRun.IsRunning)
{
// Now we want to tell the user we're running a game!
// Construct the Windows toast content
ToastContentBuilder tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=runningSteamGame", ToastActivationType.Foreground)
.AddText($"Running {shortcutToUse.GameName}", hintMaxLines: 1)
.AddText($"Waiting for the Steam Game {shortcutToUse.GameName} to exit...");
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
ToastContent toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
var doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
// And create the toast notification
var toast = new ToastNotification(doc);
// Remove any other Notifications from us
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
// And then show this notification
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
// Wait 5 seconds for the game process to spawn
Thread.Sleep(5000);
// Wait for the game to exit
Console.WriteLine($"Waiting for {steamGameToRun.Name} to exit.");
logger.Debug($"ShortcutRepository/RunShortcut - waiting for Steam Game {steamGameToRun.Name} to exit.");
while (true)
{
if (!steamGameToRun.IsRunning)
{
logger.Debug($"ShortcutRepository/RunShortcut - Steam Game {steamGameToRun.Name} is no longer running (IsRunning is false).");
break;
}
Thread.Sleep(300);
}
Console.WriteLine($"{steamGameToRun.Name} has exited.");
}
logger.Debug($"ShortcutRepository/RunShortcut - Steam Game {steamGameToRun.Name} has exited.");
// Tell the user that the Steam Game has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopDetected", ToastActivationType.Foreground)
.AddText($"{shortcutToUse.GameName} was closed", hintMaxLines: 1)
.AddText($"{shortcutToUse.GameName} game was shutdown and changes were reverted.");
toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
// And create the toast notification
toast = new ToastNotification(doc);
// Remove any other Notifications from us
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
// And then show it
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
}
@ -720,15 +832,16 @@ namespace DisplayMagician
// If the game is a Uplay Game we check for that
else if (shortcutToUse.GameLibrary.Equals(SupportedGameLibrary.Uplay))
{
// We now need to get the SteamGame info
// We now need to get the Uplay Game info
UplayGame uplayGameToRun = UplayLibrary.GetUplayGame(shortcutToUse.GameAppId);
// If the GameAppID matches a Steam game, then lets run it
// If the GameAppID matches a Uplay game, then lets run it
if (uplayGameToRun is UplayGame)
{
// Prepare to start the steam game using the URI interface
// as used by Steam for it's own desktop shortcuts.
// Prepare to start the Uplay game using the URI interface
// as used by Uplay for it's own desktop shortcuts.
var address = $"uplay://launch/{uplayGameToRun.Id}";
logger.Debug($"ShortcutRepository/RunShortcut Uplay launch address is {address}");
if (shortcutToUse.GameArgumentsRequired)
{
address += "/" + shortcutToUse.GameArguments;
@ -738,50 +851,134 @@ namespace DisplayMagician
address += "/0";
}
// Now we want to tell the user we're starting upc.exe
// Construct the Windows toast content
ToastContentBuilder tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=startingUplay", ToastActivationType.Foreground)
.AddText($"Starting Uplay", hintMaxLines: 1)
.AddText($"Waiting for Uplay to start (and update if needed)...");
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
ToastContent toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
var doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
// And create the toast notification
var toast = new ToastNotification(doc);
// Remove any other Notifications from us
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
// And then show this notification
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
// Start the URI Handler to run Uplay
Console.WriteLine($"Starting Uplay Game: {uplayGameToRun.Name}");
var uplayProcess = Process.Start(address);
Process uplayStartProcess = Process.Start(address);
// Wait for Steam game to update if needed
var ticks = 0;
while (ticks < shortcutToUse.StartTimeout * 1000)
// Wait for Uplay to start
List<Process> uplayProcesses = null;
for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500)
{
if (uplayGameToRun.IsRunning)
// Look for the processes with the ProcessName we sorted out earlier
uplayProcesses = Process.GetProcessesByName("upc").ToList();
// If we have found one or more processes then we should be good to go
// so let's break
if (uplayProcesses.Count > 0)
{
logger.Debug($"Found {uplayProcesses.Count} 'upc' processes have started");
break;
}
Thread.Sleep(300);
// Let's wait a little while if we couldn't find
// any processes yet
Thread.Sleep(500);
}
// Store the Steam Process ID for later
IPCService.GetInstance().HoldProcessId = uplayProcess?.Id ?? 0;
// Delay 5secs
Thread.Sleep(5000);
// Now we know the Uplay app is running then
// we wait until the Uplay game is running (*allows for uplay update)
for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500)
{
if (uplayGameToRun.IsRunning)
{
logger.Debug($"Found the '{uplayGameToRun.Name}' process has started");
break;
}
// Delay 500ms
Thread.Sleep(500);
}
// Store the Uplay Process ID for later
IPCService.GetInstance().HoldProcessId = uplayStartProcess?.Id ?? 0;
IPCService.GetInstance().Status = InstanceStatus.OnHold;
// Add a status notification icon in the status area
notifyIcon.Text = $"DisplayMagician: Running {uplayGameToRun.Name.Substring(0,41)}...";
if (uplayGameToRun.Name.Length <= 41)
notifyIcon.Text = $"DisplayMagician: Running {uplayGameToRun.Name}...";
else
notifyIcon.Text = $"DisplayMagician: Running {uplayGameToRun.Name.Substring(0, 41)}...";
Application.DoEvents();
// Wait 300ms for the game process to spawn
Thread.Sleep(300);
// Now check it's actually started
if (uplayGameToRun.IsRunning)
{
// Now we want to tell the user we're running a game!
// Construct the Windows toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=runningUplayGame", ToastActivationType.Foreground)
.AddText($"Running {shortcutToUse.GameName}", hintMaxLines: 1)
.AddText($"Waiting for the Uplay Game {shortcutToUse.GameName} to exit...");
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
// And create the toast notification
toast = new ToastNotification(doc);
// Remove any other Notifications from us
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
// And then show this notification
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
// Wait 5 seconds for the game process to spawn
Thread.Sleep(5000);
// Wait for the game to exit
Console.WriteLine($"Waiting for {uplayGameToRun.Name} to exit.");
logger.Debug($"ShortcutRepository/RunShortcut - waiting for Uplay Game {uplayGameToRun.Name} to exit.");
while (true)
{
if (!uplayGameToRun.IsRunning)
{
logger.Debug($"ShortcutRepository/RunShortcut - Uplay Game {uplayGameToRun.Name} is no longer running (IsRunning is false).");
break;
}
Thread.Sleep(300);
}
Console.WriteLine($"{uplayGameToRun.Name} has exited.");
}
logger.Debug($"ShortcutRepository/RunShortcut - Uplay Game {uplayGameToRun.Name} has exited.");
// Tell the user that the Uplay Game has closed
// Construct the toast content
tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stopDetected", ToastActivationType.Foreground)
.AddText($"{shortcutToUse.GameName} was closed", hintMaxLines: 1)
.AddText($"{shortcutToUse.GameName} game was shutdown and changes were reverted.");
toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
// And create the toast notification
toast = new ToastNotification(doc);
// Remove any other Notifications from us
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
// And then show it
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
}
@ -811,6 +1008,30 @@ namespace DisplayMagician
Application.DoEvents();
}
// Only replace the notification if we're minimised
if (Program.AppProgramSettings.MinimiseOnStart)
{
// Remind the user that DisplayMagician is running the in background
// Construct the toast content
ToastContentBuilder tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=minimiseStart&action=open", ToastActivationType.Foreground)
.AddText("DisplayMagician is minimised", hintMaxLines: 1)
.AddButton("Open", ToastActivationType.Background, "notify=minimiseStart&action=open");
ToastContent toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
var doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
// And create the toast notification
var toast = new ToastNotification(doc);
toast.SuppressPopup = true;
// And then show it
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
}
// Stop the pre-started startPrograms that we'd started earlier
if (startProgramsToStop.Count > 0)
{
@ -831,15 +1052,26 @@ namespace DisplayMagician
}
processToStop.Close();
}
catch (Win32Exception ex) { }
catch (InvalidOperationException ex) { }
catch (AggregateException ae) { }
catch (Win32Exception ex) {
logger.Error(ex, $"RunShortcut - Couldn't access the wait status for a process we're trying to stop.");
}
catch (InvalidOperationException ex) {
logger.Error(ex, $"RunShortcut - Couldn't kill the process as there is no process associated with the Process object.");
}
catch (SystemException ex)
{
logger.Error(ex, $"RunShortcut - Couldn't WaitForExit the process as there is no process associated with the Process object (or cannot get the ID from the process handle).");
}
catch (AggregateException ae) {
logger.Error(ae, $"RunShortcut - Got an AggregateException.");
}
}
}
// Change Audio Device back (if one specified)
if (shortcutToUse.ChangeAudioDevice)
if (needToChangeAudio)
{
// use the Audio Device
rollbackAudioDevice.SetAsDefault();
@ -856,6 +1088,23 @@ namespace DisplayMagician
}
// Change Capture Device back (if one specified)
if (needToChangeCaptureDevice)
{
// use the Audio Device
rollbackCaptureDevice.SetAsDefault();
if (shortcutToUse.SetCaptureVolume)
{
Task myTask = new Task(() =>
{
rollbackCaptureDevice.SetVolumeAsync(Convert.ToDouble(rollbackCaptureVolume));
});
myTask.Start();
myTask.Wait(2000);
}
}
// Change back to the original profile only if it is different
if (needToChangeProfiles)
@ -884,5 +1133,4 @@ namespace DisplayMagician
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}

View File

@ -1,5 +1,5 @@
using DisplayMagician.Resources;
using DisplayMagician.Shared.UserControls;
using DisplayMagicianShared.UserControls;
namespace DisplayMagician.UIForms
{
@ -36,7 +36,6 @@ namespace DisplayMagician.UIForms
this.btn_apply = new System.Windows.Forms.Button();
this.btn_back = new System.Windows.Forms.Button();
this.btn_delete = new System.Windows.Forms.Button();
this.dv_profile = new DisplayMagician.Shared.UserControls.DisplayView();
this.menu_profiles = new System.Windows.Forms.ContextMenuStrip(this.components);
this.applyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
@ -54,6 +53,8 @@ namespace DisplayMagician.UIForms
this.lbl_profile_shown_subtitle = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.tt_selected = new System.Windows.Forms.ToolTip(this.components);
this.lbl_save_profile = new System.Windows.Forms.Label();
this.dv_profile = new DisplayMagicianShared.UserControls.DisplayView();
this.menu_profiles.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pb_down_arrow)).BeginInit();
this.SuspendLayout();
@ -107,22 +108,6 @@ namespace DisplayMagician.UIForms
this.btn_delete.UseVisualStyleBackColor = true;
this.btn_delete.Click += new System.EventHandler(this.Delete_Click);
//
// dv_profile
//
this.dv_profile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dv_profile.BackColor = System.Drawing.Color.DimGray;
this.dv_profile.Font = new System.Drawing.Font("Consolas", 50F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.dv_profile.ForeColor = System.Drawing.Color.MidnightBlue;
this.dv_profile.Location = new System.Drawing.Point(0, 63);
this.dv_profile.Margin = new System.Windows.Forms.Padding(18);
this.dv_profile.Name = "dv_profile";
this.dv_profile.PaddingX = 100;
this.dv_profile.PaddingY = 100;
this.dv_profile.Profile = null;
this.dv_profile.Size = new System.Drawing.Size(976, 517);
this.dv_profile.TabIndex = 4;
//
// menu_profiles
//
this.menu_profiles.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -281,6 +266,38 @@ namespace DisplayMagician.UIForms
this.label1.TabIndex = 23;
this.label1.Text = "Saved Profiles (These can be used to create shortcuts)";
//
// lbl_save_profile
//
this.lbl_save_profile.Anchor = System.Windows.Forms.AnchorStyles.None;
this.lbl_save_profile.BackColor = System.Drawing.Color.Brown;
this.lbl_save_profile.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lbl_save_profile.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
this.lbl_save_profile.ForeColor = System.Drawing.Color.White;
this.lbl_save_profile.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.lbl_save_profile.Location = new System.Drawing.Point(703, 80);
this.lbl_save_profile.Name = "lbl_save_profile";
this.lbl_save_profile.Size = new System.Drawing.Size(261, 102);
this.lbl_save_profile.TabIndex = 33;
this.lbl_save_profile.Text = "Setup your displays with Windows or NVIDIA Setup, then return to DisplayMagician " +
"and click \'Save As\' to save this Display Profile.";
this.lbl_save_profile.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// dv_profile
//
this.dv_profile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dv_profile.BackColor = System.Drawing.Color.DimGray;
this.dv_profile.Font = new System.Drawing.Font("Consolas", 50F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.dv_profile.ForeColor = System.Drawing.Color.MidnightBlue;
this.dv_profile.Location = new System.Drawing.Point(0, 63);
this.dv_profile.Margin = new System.Windows.Forms.Padding(18);
this.dv_profile.Name = "dv_profile";
this.dv_profile.PaddingX = 100;
this.dv_profile.PaddingY = 100;
this.dv_profile.Profile = null;
this.dv_profile.Size = new System.Drawing.Size(976, 517);
this.dv_profile.TabIndex = 4;
//
// DisplayProfileForm
//
this.AcceptButton = this.btn_apply;
@ -290,6 +307,7 @@ namespace DisplayMagician.UIForms
this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
this.CancelButton = this.btn_back;
this.ClientSize = new System.Drawing.Size(976, 812);
this.Controls.Add(this.lbl_save_profile);
this.Controls.Add(this.label1);
this.Controls.Add(this.lbl_profile_shown_subtitle);
this.Controls.Add(this.ilv_saved_profiles);
@ -342,6 +360,7 @@ namespace DisplayMagician.UIForms
private System.Windows.Forms.Label lbl_profile_shown_subtitle;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ToolTip tt_selected;
private System.Windows.Forms.Label lbl_save_profile;
}
}

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DisplayMagician.Resources;
using DisplayMagician.Shared;
using DisplayMagicianShared;
using Manina.Windows.Forms;
using System.Text.RegularExpressions;
using System.Diagnostics;
@ -182,6 +182,7 @@ namespace DisplayMagician.UIForms
// we already have the profile stored
_saveOrRenameMode = "rename";
btn_save_or_rename.Text = "Rename To";
lbl_save_profile.Visible = false;
if (!_selectedProfile.IsPossible)
{
lbl_profile_shown_subtitle.Text = "This Display Profile can't be used as not all Displays are connected.";
@ -208,12 +209,13 @@ namespace DisplayMagician.UIForms
btn_save_or_rename.Text = "Save As";
lbl_profile_shown_subtitle.Text = "The current Display configuration hasn't been saved as a Display Profile yet.";
btn_apply.Visible = false;
lbl_save_profile.Visible = true;
}
// Refresh the image list view
//RefreshImageListView(profile);
// And finally show the profile in the display view
// And finally refresh the profile in the display view
dv_profile.Profile = profile;
dv_profile.Refresh();

View File

@ -31,8 +31,11 @@
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.btn_settings = new System.Windows.Forms.Button();
this.lbl_create_profile = new System.Windows.Forms.Label();
this.btn_setup_display_profiles = new System.Windows.Forms.Button();
this.pb_display_profile = new System.Windows.Forms.PictureBox();
this.lbl_create_shortcut = new System.Windows.Forms.Label();
this.cb_minimise_notification_area = new System.Windows.Forms.CheckBox();
this.lbl_version = new System.Windows.Forms.Label();
this.btn_setup_game_shortcuts = new System.Windows.Forms.Button();
@ -68,11 +71,14 @@
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.btn_settings);
this.splitContainer1.Panel1.Controls.Add(this.lbl_create_profile);
this.splitContainer1.Panel1.Controls.Add(this.btn_setup_display_profiles);
this.splitContainer1.Panel1.Controls.Add(this.pb_display_profile);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.lbl_create_shortcut);
this.splitContainer1.Panel2.Controls.Add(this.cb_minimise_notification_area);
this.splitContainer1.Panel2.Controls.Add(this.lbl_version);
this.splitContainer1.Panel2.Controls.Add(this.btn_setup_game_shortcuts);
@ -80,6 +86,24 @@
this.splitContainer1.Panel2.Controls.Add(this.pb_game_shortcut);
this.splitContainer1.TabStop = false;
//
// btn_settings
//
resources.ApplyResources(this.btn_settings, "btn_settings");
this.btn_settings.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_settings.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_settings.ForeColor = System.Drawing.Color.White;
this.btn_settings.Name = "btn_settings";
this.btn_settings.UseVisualStyleBackColor = true;
this.btn_settings.Click += new System.EventHandler(this.btn_settings_Click);
//
// lbl_create_profile
//
resources.ApplyResources(this.lbl_create_profile, "lbl_create_profile");
this.lbl_create_profile.BackColor = System.Drawing.Color.Brown;
this.lbl_create_profile.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lbl_create_profile.ForeColor = System.Drawing.Color.White;
this.lbl_create_profile.Name = "lbl_create_profile";
//
// btn_setup_display_profiles
//
resources.ApplyResources(this.btn_setup_display_profiles, "btn_setup_display_profiles");
@ -97,6 +121,14 @@
this.pb_display_profile.TabStop = false;
this.pb_display_profile.Click += new System.EventHandler(this.pb_display_profile_Click);
//
// lbl_create_shortcut
//
resources.ApplyResources(this.lbl_create_shortcut, "lbl_create_shortcut");
this.lbl_create_shortcut.BackColor = System.Drawing.Color.Brown;
this.lbl_create_shortcut.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lbl_create_shortcut.ForeColor = System.Drawing.Color.White;
this.lbl_create_shortcut.Name = "lbl_create_shortcut";
//
// cb_minimise_notification_area
//
resources.ApplyResources(this.cb_minimise_notification_area, "cb_minimise_notification_area");
@ -230,8 +262,10 @@
this.Name = "MainForm";
this.ShowIcon = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Activated += new System.EventHandler(this.MainForm_Activated);
this.Load += new System.EventHandler(this.MainForm_Load);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.Panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
@ -266,5 +300,8 @@
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
private System.Windows.Forms.CheckBox cb_minimise_notification_area;
public System.Windows.Forms.NotifyIcon notifyIcon;
private System.Windows.Forms.Label lbl_create_profile;
private System.Windows.Forms.Label lbl_create_shortcut;
private System.Windows.Forms.Button btn_settings;
}
}

View File

@ -10,8 +10,18 @@ using System.Windows.Forms;
using DisplayMagician.GameLibraries;
using System.Threading;
using System.Reflection;
using DisplayMagician.Shared;
using DisplayMagicianShared;
using System.Runtime.InteropServices;
//using Microsoft.Toolkit.Uwp.Notifications;
using DesktopNotifications;
using Microsoft.QueryStringDotNET;
using Windows.UI.Notifications;
using System.IO;
using AutoUpdaterDotNET;
using Newtonsoft.Json;
using System.Net;
using Windows.Data.Xml.Dom;
using Microsoft.Toolkit.Uwp.Notifications;
namespace DisplayMagician.UIForms
{
@ -21,7 +31,9 @@ namespace DisplayMagician.UIForms
private bool allowVisible; // ContextMenu's Show command used
private bool allowClose; // ContextMenu's Exit command used
public MainForm()
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public MainForm(Form formToOpen = null)
{
InitializeComponent();
btn_setup_display_profiles.Parent = splitContainer1.Panel1;
@ -31,10 +43,6 @@ namespace DisplayMagician.UIForms
notifyIcon.ContextMenuStrip = mainContextMenuStrip;
RefreshNotifyIconMenus();
/*WaitingForm testform = new WaitingForm();
testform.Owner = this;
testform.Show();*/
if (Program.AppProgramSettings.MinimiseOnStart)
{
// Make the form minimised on start
@ -42,6 +50,29 @@ namespace DisplayMagician.UIForms
// Hide the application to notification area when the form is closed
allowClose = false;
cb_minimise_notification_area.Checked = true;
// Change the exit_button text to say 'Close'
btn_exit.Text = "&Close";
// Remind the user that DisplayMagician is running the in background
// Construct the toast content
ToastContentBuilder tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=minimiseStart&action=open", ToastActivationType.Foreground)
.AddText("DisplayMagician is minimised", hintMaxLines: 1)
.AddButton("Open", ToastActivationType.Background, "notify=minimiseStart&action=open");
ToastContent toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
var doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
// And create the toast notification
var toast = new ToastNotification(doc);
// Remove any other Notifications from us
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
// And then show it
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
}
else
{
@ -52,6 +83,17 @@ namespace DisplayMagician.UIForms
cb_minimise_notification_area.Checked = false;
}
// If we've been handed a Form of some kind, then open it straight away
if (formToOpen is DisplayProfileForm)
{
var displayProfileForm = new DisplayProfileForm();
displayProfileForm.ShowDialog(this);
}
else if (formToOpen is ShortcutLibraryForm)
{
var shortcutLibraryForm = new ShortcutLibraryForm();
shortcutLibraryForm.ShowDialog(this);
}
}
@ -77,6 +119,30 @@ namespace DisplayMagician.UIForms
private void btn_exit_Click(object sender, EventArgs e)
{
if (cb_minimise_notification_area.Checked)
{
// Tell the user that
// Construct the toast content
ToastContentBuilder tcBuilder = new ToastContentBuilder()
.AddToastActivationInfo("notify=stillRunning", ToastActivationType.Foreground)
.AddText("DisplayMagician is still running...", hintMaxLines: 1)
.AddText("DisplayMagician will wait in the background until you need it.")
.AddButton("Open DisplayMagician", ToastActivationType.Background, "notify=stillRunning&action=open")
.AddButton("Exit DisplayMagician", ToastActivationType.Background, "notify=stillRunning&action=exit");
ToastContent toastContent = tcBuilder.Content;
// Make sure to use Windows.Data.Xml.Dom
var doc = new XmlDocument();
doc.LoadXml(toastContent.GetContent());
// And create the toast notification
var toast = new ToastNotification(doc);
// Remove any other Notifications from us
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
// And then show it
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
}
Application.Exit();
}
@ -108,8 +174,37 @@ namespace DisplayMagician.UIForms
{
// Start loading the Steam Games just after the Main form opens
//SteamGame.GetAllInstalledGames();
EnableShortcutButtonIfProfiles();
//Run the AutoUpdater to see if there are any updates available.
AutoUpdater.CheckForUpdateEvent += AutoUpdaterOnCheckForUpdateEvent;
AutoUpdater.ParseUpdateInfoEvent += AutoUpdaterOnParseUpdateInfoEvent;
AutoUpdater.Start("http://displaymagician.littlebitbig.com/update/");
}
private void EnableShortcutButtonIfProfiles()
{
if (ProfileRepository.AllProfiles.Count > 0)
{
btn_setup_game_shortcuts.Visible = true;
pb_game_shortcut.Enabled = true;
lbl_create_profile.Visible = false;
if (ShortcutRepository.AllShortcuts.Count > 0)
lbl_create_shortcut.Visible = false;
else
lbl_create_shortcut.Visible = true;
}
else
{
btn_setup_game_shortcuts.Visible = false;
pb_game_shortcut.Enabled = false;
lbl_create_profile.Visible = true;
}
}
private void RefreshNotifyIconMenus()
{
// Clear all the profiles
@ -190,7 +285,7 @@ namespace DisplayMagician.UIForms
}
}
private void openApplicationWindowToolStripMenuItem_Click(object sender, EventArgs e)
public void openApplicationWindow()
{
allowVisible = true;
Restore();
@ -198,12 +293,22 @@ namespace DisplayMagician.UIForms
BringToFront();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
public void exitApplication()
{
allowClose = true;
Application.Exit();
}
private void openApplicationWindowToolStripMenuItem_Click(object sender, EventArgs e)
{
openApplicationWindow();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
exitApplication();
}
private void cb_minimise_notification_area_CheckedChanged(object sender, EventArgs e)
{
if (cb_minimise_notification_area.Checked)
@ -214,6 +319,8 @@ namespace DisplayMagician.UIForms
allowClose = false;
// Enable the MinimiseOnStart setting
Program.AppProgramSettings.MinimiseOnStart = true;
// Change the exit_button text to say 'Close'
btn_exit.Text = "&Close";
}
else
{
@ -223,6 +330,9 @@ namespace DisplayMagician.UIForms
allowClose = true;
// Disable the MinimiseOnStart setting
Program.AppProgramSettings.MinimiseOnStart = false;
// Change the exit_button text to say 'Exit'
btn_exit.Text = "&Exit";
}
}
@ -239,5 +349,115 @@ namespace DisplayMagician.UIForms
}
}
private void MainForm_Activated(object sender, EventArgs e)
{
EnableShortcutButtonIfProfiles();
}
private void AutoUpdaterOnParseUpdateInfoEvent(ParseUpdateInfoEventArgs args)
{
dynamic json = JsonConvert.DeserializeObject(args.RemoteData);
args.UpdateInfo = new UpdateInfoEventArgs
{
CurrentVersion = json.version,
ChangelogURL = json.changelog,
DownloadURL = json.url,
Mandatory = new Mandatory
{
Value = json.mandatory.value,
UpdateMode = json.mandatory.mode,
MinimumVersion = json.mandatory.minVersion
},
CheckSum = new CheckSum
{
Value = json.checksum.value,
HashingAlgorithm = json.checksum.hashingAlgorithm
}
};
}
private void AutoUpdaterOnCheckForUpdateEvent(UpdateInfoEventArgs args)
{
if (args.Error == null)
{
if (args.IsUpdateAvailable)
{
DialogResult dialogResult;
if (args.Mandatory.Value)
{
logger.Info($"MainForm/AutoUpdaterOnCheckForUpdateEvent - New version {args.CurrentVersion} available. Current version is {args.InstalledVersion}. Mandatory upgrade.");
dialogResult =
MessageBox.Show(
$@"There is new version {args.CurrentVersion} available. You are using version {args.InstalledVersion}. This is required update. Press Ok to begin updating the application.", @"Update Available",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
else
{
logger.Info($"MainForm/AutoUpdaterOnCheckForUpdateEvent - New version {args.CurrentVersion} available. Current version is {args.InstalledVersion}. Optional upgrade.");
dialogResult =
MessageBox.Show(
$@"There is new version {args.CurrentVersion} available. You are using version {
args.InstalledVersion
}. Do you want to update the application now?", @"Update Available",
MessageBoxButtons.YesNo,
MessageBoxIcon.Information);
}
// Uncomment the following line if you want to show standard update dialog instead.
// AutoUpdater.ShowUpdateForm(args);
if (dialogResult.Equals(DialogResult.Yes) || dialogResult.Equals(DialogResult.OK))
{
try
{
logger.Info($"MainForm/AutoUpdaterOnCheckForUpdateEvent - Downloading {args.InstalledVersion} update.");
if (AutoUpdater.DownloadUpdate(args))
{
logger.Info($"MainForm/AutoUpdaterOnCheckForUpdateEvent - Restarting to apply {args.InstalledVersion} update.");
Application.Exit();
}
}
catch (Exception ex)
{
logger.Warn(ex, $"MainForm/AutoUpdaterOnCheckForUpdateEvent - Exception during update download.");
MessageBox.Show(ex.Message, ex.GetType().ToString(), MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
}
else
{
if (args.Error is WebException)
{
logger.Warn(args.Error, $"MainForm/AutoUpdaterOnCheckForUpdateEvent - WebException - There was a problem reaching the update server.");
MessageBox.Show(
@"There is a problem reaching update server. Please check your internet connection and try again later.",
@"Update Check Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
logger.Warn(args.Error, $"MainForm/AutoUpdaterOnCheckForUpdateEvent - There was a problem performing the update: {args.Error.Message}");
MessageBox.Show(args.Error.Message,
args.Error.GetType().ToString(), MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
private void btn_settings_Click(object sender, EventArgs e)
{
var settingsForm = new SettingsForm();
settingsForm.ShowDialog(this);
ProgramSettings mySettings = Program.AppProgramSettings;
// if the MainForm settings are different to the changes made when
// tweaking the settings in the settings page, then align them
if (mySettings.MinimiseOnStart && !cb_minimise_notification_area.Checked)
cb_minimise_notification_area.Checked = true;
else if (!mySettings.MinimiseOnStart && cb_minimise_notification_area.Checked)
cb_minimise_notification_area.Checked = false;
}
}
}

View File

@ -132,6 +132,69 @@
<data name="splitContainer1.Orientation" type="System.Windows.Forms.Orientation, System.Windows.Forms">
<value>Horizontal</value>
</data>
<data name="btn_settings.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Right</value>
</data>
<data name="btn_settings.FlatStyle" type="System.Windows.Forms.FlatStyle, System.Windows.Forms">
<value>Flat</value>
</data>
<data name="btn_settings.Location" type="System.Drawing.Point, System.Drawing">
<value>700, 8</value>
</data>
<data name="btn_settings.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 23</value>
</data>
<data name="btn_settings.TabIndex" type="System.Int32, mscorlib">
<value>7</value>
</data>
<data name="btn_settings.Text" xml:space="preserve">
<value>Settings</value>
</data>
<data name="&gt;&gt;btn_settings.Name" xml:space="preserve">
<value>btn_settings</value>
</data>
<data name="&gt;&gt;btn_settings.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;btn_settings.Parent" xml:space="preserve">
<value>splitContainer1.Panel1</value>
</data>
<data name="&gt;&gt;btn_settings.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="lbl_create_profile.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value>
</data>
<data name="lbl_create_profile.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="lbl_create_profile.Font" type="System.Drawing.Font, System.Drawing">
<value>Microsoft Sans Serif, 12pt</value>
</data>
<data name="lbl_create_profile.Location" type="System.Drawing.Point, System.Drawing">
<value>190, 239</value>
</data>
<data name="lbl_create_profile.Size" type="System.Drawing.Size, System.Drawing">
<value>404, 22</value>
</data>
<data name="lbl_create_profile.TabIndex" type="System.Int32, mscorlib">
<value>6</value>
</data>
<data name="lbl_create_profile.Text" xml:space="preserve">
<value>You need to save at least one display profile to continue</value>
</data>
<data name="&gt;&gt;lbl_create_profile.Name" xml:space="preserve">
<value>lbl_create_profile</value>
</data>
<data name="&gt;&gt;lbl_create_profile.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;lbl_create_profile.Parent" xml:space="preserve">
<value>splitContainer1.Panel1</value>
</data>
<data name="&gt;&gt;lbl_create_profile.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="btn_setup_display_profiles.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value>
</data>
@ -142,7 +205,7 @@
<value>Microsoft Sans Serif, 21.75pt</value>
</data>
<data name="btn_setup_display_profiles.Location" type="System.Drawing.Point, System.Drawing">
<value>210, 168</value>
<value>210, 166</value>
</data>
<data name="btn_setup_display_profiles.Size" type="System.Drawing.Size, System.Drawing">
<value>360, 50</value>
@ -151,7 +214,7 @@
<value>1</value>
</data>
<data name="btn_setup_display_profiles.Text" xml:space="preserve">
<value>Setup Display &amp;Profiles</value>
<value>Display &amp;Profiles</value>
</data>
<data name="&gt;&gt;btn_setup_display_profiles.Name" xml:space="preserve">
<value>btn_setup_display_profiles</value>
@ -163,7 +226,7 @@
<value>splitContainer1.Panel1</value>
</data>
<data name="&gt;&gt;btn_setup_display_profiles.ZOrder" xml:space="preserve">
<value>0</value>
<value>2</value>
</data>
<data name="pb_display_profile.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
@ -10711,7 +10774,7 @@
<value>splitContainer1.Panel1</value>
</data>
<data name="&gt;&gt;pb_display_profile.ZOrder" xml:space="preserve">
<value>1</value>
<value>3</value>
</data>
<data name="&gt;&gt;splitContainer1.Panel1.Name" xml:space="preserve">
<value>splitContainer1.Panel1</value>
@ -10725,6 +10788,45 @@
<data name="&gt;&gt;splitContainer1.Panel1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="lbl_create_shortcut.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value>
</data>
<data name="lbl_create_shortcut.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="lbl_create_shortcut.Font" type="System.Drawing.Font, System.Drawing">
<value>Microsoft Sans Serif, 12pt</value>
</data>
<data name="lbl_create_shortcut.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="lbl_create_shortcut.Location" type="System.Drawing.Point, System.Drawing">
<value>241, 239</value>
</data>
<data name="lbl_create_shortcut.Size" type="System.Drawing.Size, System.Drawing">
<value>303, 22</value>
</data>
<data name="lbl_create_shortcut.TabIndex" type="System.Int32, mscorlib">
<value>7</value>
</data>
<data name="lbl_create_shortcut.Text" xml:space="preserve">
<value>You should click here to create a shortcut</value>
</data>
<data name="lbl_create_shortcut.Visible" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="&gt;&gt;lbl_create_shortcut.Name" xml:space="preserve">
<value>lbl_create_shortcut</value>
</data>
<data name="&gt;&gt;lbl_create_shortcut.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;lbl_create_shortcut.Parent" xml:space="preserve">
<value>splitContainer1.Panel2</value>
</data>
<data name="&gt;&gt;lbl_create_shortcut.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="cb_minimise_notification_area.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom</value>
</data>
@ -10738,7 +10840,7 @@
<value>NoControl</value>
</data>
<data name="cb_minimise_notification_area.Location" type="System.Drawing.Point, System.Drawing">
<value>232, 354</value>
<value>234, 353</value>
</data>
<data name="cb_minimise_notification_area.Size" type="System.Drawing.Size, System.Drawing">
<value>332, 20</value>
@ -10759,7 +10861,7 @@
<value>splitContainer1.Panel2</value>
</data>
<data name="&gt;&gt;cb_minimise_notification_area.ZOrder" xml:space="preserve">
<value>0</value>
<value>1</value>
</data>
<data name="lbl_version.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Left</value>
@ -10771,7 +10873,7 @@
<value>Microsoft Sans Serif, 9.75pt</value>
</data>
<data name="lbl_version.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 355</value>
<value>12, 354</value>
</data>
<data name="lbl_version.Size" type="System.Drawing.Size, System.Drawing">
<value>25, 16</value>
@ -10795,7 +10897,7 @@
<value>splitContainer1.Panel2</value>
</data>
<data name="&gt;&gt;lbl_version.ZOrder" xml:space="preserve">
<value>1</value>
<value>2</value>
</data>
<data name="btn_setup_game_shortcuts.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>None</value>
@ -10807,7 +10909,7 @@
<value>Microsoft Sans Serif, 21.75pt</value>
</data>
<data name="btn_setup_game_shortcuts.Location" type="System.Drawing.Point, System.Drawing">
<value>212, 186</value>
<value>212, 166</value>
</data>
<data name="btn_setup_game_shortcuts.Size" type="System.Drawing.Size, System.Drawing">
<value>360, 50</value>
@ -10816,7 +10918,7 @@
<value>4</value>
</data>
<data name="btn_setup_game_shortcuts.Text" xml:space="preserve">
<value>Setup Game &amp;Shortcuts</value>
<value>Game &amp;Shortcuts</value>
</data>
<data name="&gt;&gt;btn_setup_game_shortcuts.Name" xml:space="preserve">
<value>btn_setup_game_shortcuts</value>
@ -10828,7 +10930,7 @@
<value>splitContainer1.Panel2</value>
</data>
<data name="&gt;&gt;btn_setup_game_shortcuts.ZOrder" xml:space="preserve">
<value>2</value>
<value>3</value>
</data>
<data name="btn_exit.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Right</value>
@ -10840,7 +10942,7 @@
<value>NoControl</value>
</data>
<data name="btn_exit.Location" type="System.Drawing.Point, System.Drawing">
<value>700, 351</value>
<value>700, 350</value>
</data>
<data name="btn_exit.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 23</value>
@ -10861,7 +10963,7 @@
<value>splitContainer1.Panel2</value>
</data>
<data name="&gt;&gt;btn_exit.ZOrder" xml:space="preserve">
<value>3</value>
<value>4</value>
</data>
<data name="pb_game_shortcut.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
@ -63146,7 +63248,7 @@
<value>splitContainer1.Panel2</value>
</data>
<data name="&gt;&gt;pb_game_shortcut.ZOrder" xml:space="preserve">
<value>4</value>
<value>5</value>
</data>
<data name="&gt;&gt;splitContainer1.Panel2.Name" xml:space="preserve">
<value>splitContainer1.Panel2</value>
@ -63269,7 +63371,7 @@
<value>218, 22</value>
</data>
<data name="exitToolStripMenuItem.Text" xml:space="preserve">
<value>Close DisplayMagician</value>
<value>Exit DisplayMagician</value>
</data>
<data name="mainContextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
<value>219, 126</value>
@ -71106,9 +71208,15 @@
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>58</value>
</metadata>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>6, 13</value>
</data>
<data name="$this.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>784, 761</value>
</data>

View File

@ -1,4 +1,4 @@
using DisplayMagician.Shared;
using DisplayMagicianShared;
using Manina.Windows.Forms;
using System;
using System.Collections.Generic;

View File

@ -0,0 +1,121 @@

namespace DisplayMagician.UIForms
{
partial class SettingsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.cb_minimise_notification_area = new System.Windows.Forms.CheckBox();
this.cmb_loglevel = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.btn_back = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// cb_minimise_notification_area
//
this.cb_minimise_notification_area.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.cb_minimise_notification_area.AutoSize = true;
this.cb_minimise_notification_area.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F);
this.cb_minimise_notification_area.ForeColor = System.Drawing.Color.White;
this.cb_minimise_notification_area.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.cb_minimise_notification_area.Location = new System.Drawing.Point(73, 41);
this.cb_minimise_notification_area.Name = "cb_minimise_notification_area";
this.cb_minimise_notification_area.Size = new System.Drawing.Size(332, 20);
this.cb_minimise_notification_area.TabIndex = 6;
this.cb_minimise_notification_area.Text = "Start DisplayMagician minimised in notification area";
this.cb_minimise_notification_area.UseVisualStyleBackColor = true;
//
// cmb_loglevel
//
this.cmb_loglevel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.cmb_loglevel.FormattingEnabled = true;
this.cmb_loglevel.Location = new System.Drawing.Point(213, 86);
this.cmb_loglevel.Name = "cmb_loglevel";
this.cmb_loglevel.Size = new System.Drawing.Size(275, 24);
this.cmb_loglevel.TabIndex = 7;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.Transparent;
this.label1.Location = new System.Drawing.Point(70, 89);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(137, 16);
this.label1.TabIndex = 8;
this.label1.Text = "What type of logging?";
//
// btn_back
//
this.btn_back.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btn_back.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btn_back.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_back.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_back.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_back.ForeColor = System.Drawing.Color.White;
this.btn_back.Location = new System.Drawing.Point(457, 152);
this.btn_back.Name = "btn_back";
this.btn_back.Size = new System.Drawing.Size(75, 23);
this.btn_back.TabIndex = 9;
this.btn_back.Text = "&Back";
this.btn_back.UseVisualStyleBackColor = true;
this.btn_back.Click += new System.EventHandler(this.btn_back_Click);
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Black;
this.ClientSize = new System.Drawing.Size(544, 187);
this.Controls.Add(this.btn_back);
this.Controls.Add(this.label1);
this.Controls.Add(this.cmb_loglevel);
this.Controls.Add(this.cb_minimise_notification_area);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "SettingsForm";
this.ShowIcon = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Settings";
this.TopMost = true;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SettingsForm_FormClosing);
this.Load += new System.EventHandler(this.SettingsForm_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox cb_minimise_notification_area;
private System.Windows.Forms.ComboBox cmb_loglevel;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btn_back;
}
}

View File

@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DisplayMagician.UIForms
{
public partial class SettingsForm : Form
{
ProgramSettings mySettings = null;
private Dictionary<string, string> logLevelText = new Dictionary<string, string>();
public SettingsForm()
{
InitializeComponent();
// Populate the LogLevel dictionary
logLevelText.Add("Trace", "Full Application Trace (very large)");
logLevelText.Add("Debug", "Detailed Debug messages (large)");
logLevelText.Add("Info", "Information, Warning and Error messages");
logLevelText.Add("Warn", "Warning and Error messages only (Default)");
logLevelText.Add("Error", "Error messages only");
logLevelText.Add("Fatal", "Fatal Error messages only");
// Now use it to populate the LogLevel Dropdown
cmb_loglevel.Items.Clear();
cmb_loglevel.Items.AddRange(logLevelText.Values.ToArray());
}
private void SettingsForm_Load(object sender, EventArgs e)
{
// setup minimise on start
if (Program.AppProgramSettings.MinimiseOnStart)
cb_minimise_notification_area.Checked = true;
else
cb_minimise_notification_area.Checked = false;
// setup loglevel on start
switch (Program.AppProgramSettings.LogLevel)
{
case "Trace":
cmb_loglevel.SelectedIndex = cmb_loglevel.FindStringExact(logLevelText["Trace"]);
break;
case "Debug":
cmb_loglevel.SelectedIndex = cmb_loglevel.FindStringExact(logLevelText["Debug"]);
break;
case "Info":
cmb_loglevel.SelectedIndex = cmb_loglevel.FindStringExact(logLevelText["Info"]);
break;
case "Warn":
cmb_loglevel.SelectedIndex = cmb_loglevel.FindStringExact(logLevelText["Warn"]);
break;
case "Error":
cmb_loglevel.SelectedIndex = cmb_loglevel.FindStringExact(logLevelText["Error"]);
break;
case "Fatal":
cmb_loglevel.SelectedIndex = cmb_loglevel.FindStringExact(logLevelText["Fatal"]);
break;
default:
cmb_loglevel.SelectedIndex = cmb_loglevel.FindStringExact(logLevelText["Warn"]);
break;
}
}
private void SettingsForm_FormClosing(object sender, FormClosingEventArgs e)
{
// save minimise on close
if (cb_minimise_notification_area.Checked)
Program.AppProgramSettings.MinimiseOnStart = true;
else
Program.AppProgramSettings.MinimiseOnStart = false;
// save loglevel on close
if (cmb_loglevel.SelectedItem.Equals(logLevelText["Trace"]))
Program.AppProgramSettings.LogLevel = "Trace";
else if (cmb_loglevel.SelectedItem.Equals(logLevelText["Debug"]))
Program.AppProgramSettings.LogLevel = "Debug";
else if (cmb_loglevel.SelectedItem.Equals(logLevelText["Info"]))
Program.AppProgramSettings.LogLevel = "Info";
else if (cmb_loglevel.SelectedItem.Equals(logLevelText["Warn"]))
Program.AppProgramSettings.LogLevel = "Warn";
else if (cmb_loglevel.SelectedItem.Equals(logLevelText["Error"]))
Program.AppProgramSettings.LogLevel = "Error";
else if (cmb_loglevel.SelectedItem.Equals(logLevelText["Fatal"]))
Program.AppProgramSettings.LogLevel = "Fatal";
else
Program.AppProgramSettings.LogLevel = "Warn";
}
private void btn_back_Click(object sender, EventArgs e)
{
this.Close();
}
}
}

View File

@ -1,5 +1,5 @@
using DisplayMagician.Resources;
using DisplayMagician.Shared.UserControls;
using DisplayMagicianShared.UserControls;
namespace DisplayMagician.UIForms
{
@ -42,8 +42,19 @@ namespace DisplayMagician.UIForms
this.lbl_profile_shown_subtitle = new System.Windows.Forms.Label();
this.lbl_profile_shown = new System.Windows.Forms.Label();
this.ilv_saved_profiles = new Manina.Windows.Forms.ImageListView();
this.dv_profile = new DisplayMagician.Shared.UserControls.DisplayView();
this.dv_profile = new DisplayMagicianShared.UserControls.DisplayView();
this.tabp_audio = new System.Windows.Forms.TabPage();
this.gb_capture_settings = new System.Windows.Forms.GroupBox();
this.gb_capture_volume = new System.Windows.Forms.GroupBox();
this.rb_set_capture_volume = new System.Windows.Forms.RadioButton();
this.rb_keep_capture_volume = new System.Windows.Forms.RadioButton();
this.lbl_capture_volume = new System.Windows.Forms.Label();
this.nud_capture_volume = new System.Windows.Forms.NumericUpDown();
this.btn_rescan_capture = new System.Windows.Forms.Button();
this.cb_capture_device = new System.Windows.Forms.ComboBox();
this.rb_change_capture = new System.Windows.Forms.RadioButton();
this.rb_no_change_capture = new System.Windows.Forms.RadioButton();
this.gb_audio_settings = new System.Windows.Forms.GroupBox();
this.gb_audio_volume = new System.Windows.Forms.GroupBox();
this.rb_set_audio_volume = new System.Windows.Forms.RadioButton();
this.rb_keep_audio_volume = new System.Windows.Forms.RadioButton();
@ -91,7 +102,7 @@ namespace DisplayMagician.UIForms
this.btn_exe_to_start = new System.Windows.Forms.Button();
this.txt_args_executable = new System.Windows.Forms.TextBox();
this.cb_args_executable = new System.Windows.Forms.CheckBox();
this.btn_app_different_executable = new System.Windows.Forms.Button();
this.btn_choose_alternative_executable = new System.Windows.Forms.Button();
this.txt_alternative_executable = new System.Windows.Forms.TextBox();
this.rb_wait_alternative_executable = new System.Windows.Forms.RadioButton();
this.rb_wait_executable = new System.Windows.Forms.RadioButton();
@ -117,6 +128,9 @@ namespace DisplayMagician.UIForms
this.clm_name = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.rb_launcher = new System.Windows.Forms.RadioButton();
this.tabp_after = new System.Windows.Forms.TabPage();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.rb_switch_capture_permanent = new System.Windows.Forms.RadioButton();
this.rb_switch_capture_temp = new System.Windows.Forms.RadioButton();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.rb_switch_audio_permanent = new System.Windows.Forms.RadioButton();
this.rb_switch_audio_temp = new System.Windows.Forms.RadioButton();
@ -130,6 +144,10 @@ namespace DisplayMagician.UIForms
this.tabc_shortcut.SuspendLayout();
this.tabp_display.SuspendLayout();
this.tabp_audio.SuspendLayout();
this.gb_capture_settings.SuspendLayout();
this.gb_capture_volume.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nud_capture_volume)).BeginInit();
this.gb_audio_settings.SuspendLayout();
this.gb_audio_volume.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nud_audio_volume)).BeginInit();
this.tabp_before.SuspendLayout();
@ -143,6 +161,7 @@ namespace DisplayMagician.UIForms
this.p_game.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nud_timeout_game)).BeginInit();
this.tabp_after.SuspendLayout();
this.groupBox2.SuspendLayout();
this.groupBox1.SuspendLayout();
this.gb_display_after.SuspendLayout();
this.SuspendLayout();
@ -291,11 +310,8 @@ namespace DisplayMagician.UIForms
// tabp_audio
//
this.tabp_audio.BackColor = System.Drawing.Color.Black;
this.tabp_audio.Controls.Add(this.gb_audio_volume);
this.tabp_audio.Controls.Add(this.btn_rescan_audio);
this.tabp_audio.Controls.Add(this.cb_audio_device);
this.tabp_audio.Controls.Add(this.rb_change_audio);
this.tabp_audio.Controls.Add(this.rb_no_change_audio);
this.tabp_audio.Controls.Add(this.gb_capture_settings);
this.tabp_audio.Controls.Add(this.gb_audio_settings);
this.tabp_audio.Location = new System.Drawing.Point(4, 32);
this.tabp_audio.Name = "tabp_audio";
this.tabp_audio.Padding = new System.Windows.Forms.Padding(3);
@ -303,6 +319,152 @@ namespace DisplayMagician.UIForms
this.tabp_audio.TabIndex = 4;
this.tabp_audio.Text = "2. Choose Audio";
//
// gb_capture_settings
//
this.gb_capture_settings.Controls.Add(this.gb_capture_volume);
this.gb_capture_settings.Controls.Add(this.btn_rescan_capture);
this.gb_capture_settings.Controls.Add(this.cb_capture_device);
this.gb_capture_settings.Controls.Add(this.rb_change_capture);
this.gb_capture_settings.Controls.Add(this.rb_no_change_capture);
this.gb_capture_settings.ForeColor = System.Drawing.Color.White;
this.gb_capture_settings.Location = new System.Drawing.Point(65, 317);
this.gb_capture_settings.Name = "gb_capture_settings";
this.gb_capture_settings.Size = new System.Drawing.Size(953, 256);
this.gb_capture_settings.TabIndex = 21;
this.gb_capture_settings.TabStop = false;
this.gb_capture_settings.Text = "Microphone Settings";
//
// gb_capture_volume
//
this.gb_capture_volume.Controls.Add(this.rb_set_capture_volume);
this.gb_capture_volume.Controls.Add(this.rb_keep_capture_volume);
this.gb_capture_volume.Controls.Add(this.lbl_capture_volume);
this.gb_capture_volume.Controls.Add(this.nud_capture_volume);
this.gb_capture_volume.ForeColor = System.Drawing.Color.White;
this.gb_capture_volume.Location = new System.Drawing.Point(327, 114);
this.gb_capture_volume.Name = "gb_capture_volume";
this.gb_capture_volume.Size = new System.Drawing.Size(429, 128);
this.gb_capture_volume.TabIndex = 20;
this.gb_capture_volume.TabStop = false;
this.gb_capture_volume.Text = "Microphone Volume";
this.gb_capture_volume.Visible = false;
//
// rb_set_capture_volume
//
this.rb_set_capture_volume.AutoSize = true;
this.rb_set_capture_volume.ForeColor = System.Drawing.Color.White;
this.rb_set_capture_volume.Location = new System.Drawing.Point(62, 78);
this.rb_set_capture_volume.Name = "rb_set_capture_volume";
this.rb_set_capture_volume.Size = new System.Drawing.Size(167, 24);
this.rb_set_capture_volume.TabIndex = 13;
this.rb_set_capture_volume.Text = "Set audio volume at";
this.rb_set_capture_volume.UseVisualStyleBackColor = true;
this.rb_set_capture_volume.CheckedChanged += new System.EventHandler(this.rb_set_capture_volume_CheckedChanged);
//
// rb_keep_capture_volume
//
this.rb_keep_capture_volume.AutoSize = true;
this.rb_keep_capture_volume.Checked = true;
this.rb_keep_capture_volume.ForeColor = System.Drawing.Color.White;
this.rb_keep_capture_volume.Location = new System.Drawing.Point(62, 35);
this.rb_keep_capture_volume.Name = "rb_keep_capture_volume";
this.rb_keep_capture_volume.Size = new System.Drawing.Size(203, 24);
this.rb_keep_capture_volume.TabIndex = 12;
this.rb_keep_capture_volume.TabStop = true;
this.rb_keep_capture_volume.Text = "Leave audio volume as is";
this.rb_keep_capture_volume.UseVisualStyleBackColor = true;
this.rb_keep_capture_volume.CheckedChanged += new System.EventHandler(this.rb_keep_capture_volume_CheckedChanged);
//
// lbl_capture_volume
//
this.lbl_capture_volume.AutoSize = true;
this.lbl_capture_volume.ForeColor = System.Drawing.Color.White;
this.lbl_capture_volume.Location = new System.Drawing.Point(299, 80);
this.lbl_capture_volume.Name = "lbl_capture_volume";
this.lbl_capture_volume.Size = new System.Drawing.Size(63, 20);
this.lbl_capture_volume.TabIndex = 11;
this.lbl_capture_volume.Text = "percent";
//
// nud_capture_volume
//
this.nud_capture_volume.Enabled = false;
this.nud_capture_volume.Location = new System.Drawing.Point(233, 78);
this.nud_capture_volume.Name = "nud_capture_volume";
this.nud_capture_volume.Size = new System.Drawing.Size(60, 26);
this.nud_capture_volume.TabIndex = 10;
this.nud_capture_volume.Value = new decimal(new int[] {
100,
0,
0,
0});
this.nud_capture_volume.ValueChanged += new System.EventHandler(this.nud_capture_volume_ValueChanged);
//
// btn_rescan_capture
//
this.btn_rescan_capture.Enabled = false;
this.btn_rescan_capture.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_rescan_capture.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_rescan_capture.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_rescan_capture.ForeColor = System.Drawing.Color.White;
this.btn_rescan_capture.Location = new System.Drawing.Point(760, 73);
this.btn_rescan_capture.Name = "btn_rescan_capture";
this.btn_rescan_capture.Size = new System.Drawing.Size(71, 28);
this.btn_rescan_capture.TabIndex = 19;
this.btn_rescan_capture.Text = "rescan";
this.btn_rescan_capture.UseVisualStyleBackColor = true;
this.btn_rescan_capture.Click += new System.EventHandler(this.btn_rescan_capture_Click);
//
// cb_capture_device
//
this.cb_capture_device.Enabled = false;
this.cb_capture_device.FormattingEnabled = true;
this.cb_capture_device.Location = new System.Drawing.Point(325, 73);
this.cb_capture_device.Name = "cb_capture_device";
this.cb_capture_device.Size = new System.Drawing.Size(429, 28);
this.cb_capture_device.TabIndex = 18;
this.cb_capture_device.SelectedIndexChanged += new System.EventHandler(this.cb_capture_device_SelectedIndexChanged);
//
// rb_change_capture
//
this.rb_change_capture.AutoSize = true;
this.rb_change_capture.ForeColor = System.Drawing.Color.White;
this.rb_change_capture.Location = new System.Drawing.Point(121, 73);
this.rb_change_capture.Name = "rb_change_capture";
this.rb_change_capture.Size = new System.Drawing.Size(192, 24);
this.rb_change_capture.TabIndex = 17;
this.rb_change_capture.Text = "Change microphone to:";
this.rb_change_capture.UseVisualStyleBackColor = true;
this.rb_change_capture.CheckedChanged += new System.EventHandler(this.rb_change_capture_CheckedChanged);
//
// rb_no_change_capture
//
this.rb_no_change_capture.AutoSize = true;
this.rb_no_change_capture.Checked = true;
this.rb_no_change_capture.ForeColor = System.Drawing.Color.White;
this.rb_no_change_capture.Location = new System.Drawing.Point(121, 35);
this.rb_no_change_capture.Name = "rb_no_change_capture";
this.rb_no_change_capture.Size = new System.Drawing.Size(308, 24);
this.rb_no_change_capture.TabIndex = 16;
this.rb_no_change_capture.TabStop = true;
this.rb_no_change_capture.Text = "Don\'t change microphone input settings";
this.rb_no_change_capture.UseVisualStyleBackColor = true;
this.rb_no_change_capture.CheckedChanged += new System.EventHandler(this.rb_no_change_capture_CheckedChanged);
//
// gb_audio_settings
//
this.gb_audio_settings.Controls.Add(this.gb_audio_volume);
this.gb_audio_settings.Controls.Add(this.btn_rescan_audio);
this.gb_audio_settings.Controls.Add(this.cb_audio_device);
this.gb_audio_settings.Controls.Add(this.rb_change_audio);
this.gb_audio_settings.Controls.Add(this.rb_no_change_audio);
this.gb_audio_settings.ForeColor = System.Drawing.Color.White;
this.gb_audio_settings.Location = new System.Drawing.Point(65, 30);
this.gb_audio_settings.Name = "gb_audio_settings";
this.gb_audio_settings.Size = new System.Drawing.Size(953, 272);
this.gb_audio_settings.TabIndex = 0;
this.gb_audio_settings.TabStop = false;
this.gb_audio_settings.Text = "Audio Output Settings";
//
// gb_audio_volume
//
this.gb_audio_volume.Controls.Add(this.rb_set_audio_volume);
@ -310,10 +472,10 @@ namespace DisplayMagician.UIForms
this.gb_audio_volume.Controls.Add(this.lbl_audio_volume);
this.gb_audio_volume.Controls.Add(this.nud_audio_volume);
this.gb_audio_volume.ForeColor = System.Drawing.Color.White;
this.gb_audio_volume.Location = new System.Drawing.Point(392, 240);
this.gb_audio_volume.Location = new System.Drawing.Point(325, 113);
this.gb_audio_volume.Name = "gb_audio_volume";
this.gb_audio_volume.Size = new System.Drawing.Size(429, 147);
this.gb_audio_volume.TabIndex = 10;
this.gb_audio_volume.Size = new System.Drawing.Size(429, 133);
this.gb_audio_volume.TabIndex = 20;
this.gb_audio_volume.TabStop = false;
this.gb_audio_volume.Text = "Audio Output Volume";
this.gb_audio_volume.Visible = false;
@ -322,7 +484,7 @@ namespace DisplayMagician.UIForms
//
this.rb_set_audio_volume.AutoSize = true;
this.rb_set_audio_volume.ForeColor = System.Drawing.Color.White;
this.rb_set_audio_volume.Location = new System.Drawing.Point(38, 84);
this.rb_set_audio_volume.Location = new System.Drawing.Point(61, 82);
this.rb_set_audio_volume.Name = "rb_set_audio_volume";
this.rb_set_audio_volume.Size = new System.Drawing.Size(167, 24);
this.rb_set_audio_volume.TabIndex = 13;
@ -335,7 +497,7 @@ namespace DisplayMagician.UIForms
this.rb_keep_audio_volume.AutoSize = true;
this.rb_keep_audio_volume.Checked = true;
this.rb_keep_audio_volume.ForeColor = System.Drawing.Color.White;
this.rb_keep_audio_volume.Location = new System.Drawing.Point(38, 41);
this.rb_keep_audio_volume.Location = new System.Drawing.Point(61, 38);
this.rb_keep_audio_volume.Name = "rb_keep_audio_volume";
this.rb_keep_audio_volume.Size = new System.Drawing.Size(203, 24);
this.rb_keep_audio_volume.TabIndex = 12;
@ -348,7 +510,7 @@ namespace DisplayMagician.UIForms
//
this.lbl_audio_volume.AutoSize = true;
this.lbl_audio_volume.ForeColor = System.Drawing.Color.White;
this.lbl_audio_volume.Location = new System.Drawing.Point(275, 86);
this.lbl_audio_volume.Location = new System.Drawing.Point(298, 84);
this.lbl_audio_volume.Name = "lbl_audio_volume";
this.lbl_audio_volume.Size = new System.Drawing.Size(63, 20);
this.lbl_audio_volume.TabIndex = 11;
@ -357,7 +519,7 @@ namespace DisplayMagician.UIForms
// nud_audio_volume
//
this.nud_audio_volume.Enabled = false;
this.nud_audio_volume.Location = new System.Drawing.Point(209, 84);
this.nud_audio_volume.Location = new System.Drawing.Point(232, 82);
this.nud_audio_volume.Name = "nud_audio_volume";
this.nud_audio_volume.Size = new System.Drawing.Size(60, 26);
this.nud_audio_volume.TabIndex = 10;
@ -366,6 +528,7 @@ namespace DisplayMagician.UIForms
0,
0,
0});
this.nud_audio_volume.ValueChanged += new System.EventHandler(this.nud_audio_volume_ValueChanged);
//
// btn_rescan_audio
//
@ -374,10 +537,10 @@ namespace DisplayMagician.UIForms
this.btn_rescan_audio.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_rescan_audio.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_rescan_audio.ForeColor = System.Drawing.Color.White;
this.btn_rescan_audio.Location = new System.Drawing.Point(827, 186);
this.btn_rescan_audio.Location = new System.Drawing.Point(760, 72);
this.btn_rescan_audio.Name = "btn_rescan_audio";
this.btn_rescan_audio.Size = new System.Drawing.Size(71, 28);
this.btn_rescan_audio.TabIndex = 3;
this.btn_rescan_audio.TabIndex = 19;
this.btn_rescan_audio.Text = "rescan";
this.btn_rescan_audio.UseVisualStyleBackColor = true;
this.btn_rescan_audio.Click += new System.EventHandler(this.btn_rescan_audio_Click);
@ -386,20 +549,20 @@ namespace DisplayMagician.UIForms
//
this.cb_audio_device.Enabled = false;
this.cb_audio_device.FormattingEnabled = true;
this.cb_audio_device.Location = new System.Drawing.Point(392, 186);
this.cb_audio_device.Location = new System.Drawing.Point(325, 72);
this.cb_audio_device.Name = "cb_audio_device";
this.cb_audio_device.Size = new System.Drawing.Size(429, 28);
this.cb_audio_device.TabIndex = 2;
this.cb_audio_device.TabIndex = 18;
this.cb_audio_device.SelectedIndexChanged += new System.EventHandler(this.cb_audio_device_SelectedIndexChanged);
//
// rb_change_audio
//
this.rb_change_audio.AutoSize = true;
this.rb_change_audio.ForeColor = System.Drawing.Color.White;
this.rb_change_audio.Location = new System.Drawing.Point(188, 186);
this.rb_change_audio.Location = new System.Drawing.Point(121, 72);
this.rb_change_audio.Name = "rb_change_audio";
this.rb_change_audio.Size = new System.Drawing.Size(198, 24);
this.rb_change_audio.TabIndex = 1;
this.rb_change_audio.TabIndex = 17;
this.rb_change_audio.Text = "Change audio output to:";
this.rb_change_audio.UseVisualStyleBackColor = true;
this.rb_change_audio.CheckedChanged += new System.EventHandler(this.rb_change_audio_CheckedChanged);
@ -409,12 +572,12 @@ namespace DisplayMagician.UIForms
this.rb_no_change_audio.AutoSize = true;
this.rb_no_change_audio.Checked = true;
this.rb_no_change_audio.ForeColor = System.Drawing.Color.White;
this.rb_no_change_audio.Location = new System.Drawing.Point(188, 114);
this.rb_no_change_audio.Location = new System.Drawing.Point(121, 34);
this.rb_no_change_audio.Name = "rb_no_change_audio";
this.rb_no_change_audio.Size = new System.Drawing.Size(215, 24);
this.rb_no_change_audio.TabIndex = 0;
this.rb_no_change_audio.Size = new System.Drawing.Size(275, 24);
this.rb_no_change_audio.TabIndex = 16;
this.rb_no_change_audio.TabStop = true;
this.rb_no_change_audio.Text = "Don\'t change audio output";
this.rb_no_change_audio.Text = "Don\'t change audio output settings";
this.rb_no_change_audio.UseVisualStyleBackColor = true;
this.rb_no_change_audio.CheckedChanged += new System.EventHandler(this.rb_no_change_audio_CheckedChanged);
//
@ -808,7 +971,7 @@ namespace DisplayMagician.UIForms
this.p_standalone.Controls.Add(this.btn_exe_to_start);
this.p_standalone.Controls.Add(this.txt_args_executable);
this.p_standalone.Controls.Add(this.cb_args_executable);
this.p_standalone.Controls.Add(this.btn_app_different_executable);
this.p_standalone.Controls.Add(this.btn_choose_alternative_executable);
this.p_standalone.Controls.Add(this.txt_alternative_executable);
this.p_standalone.Controls.Add(this.rb_wait_alternative_executable);
this.p_standalone.Controls.Add(this.rb_wait_executable);
@ -826,7 +989,7 @@ namespace DisplayMagician.UIForms
//
this.btn_exe_to_start.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_exe_to_start.ForeColor = System.Drawing.Color.White;
this.btn_exe_to_start.Location = new System.Drawing.Point(593, 10);
this.btn_exe_to_start.Location = new System.Drawing.Point(666, 10);
this.btn_exe_to_start.Name = "btn_exe_to_start";
this.btn_exe_to_start.Size = new System.Drawing.Size(85, 27);
this.btn_exe_to_start.TabIndex = 12;
@ -856,17 +1019,17 @@ namespace DisplayMagician.UIForms
this.cb_args_executable.CheckedChanged += new System.EventHandler(this.cb_args_executable_CheckedChanged);
this.cb_args_executable.Paint += new System.Windows.Forms.PaintEventHandler(this.checkbox_Paint);
//
// btn_app_different_executable
// btn_choose_alternative_executable
//
this.btn_app_different_executable.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_app_different_executable.ForeColor = System.Drawing.Color.White;
this.btn_app_different_executable.Location = new System.Drawing.Point(877, 115);
this.btn_app_different_executable.Name = "btn_app_different_executable";
this.btn_app_different_executable.Size = new System.Drawing.Size(85, 27);
this.btn_app_different_executable.TabIndex = 9;
this.btn_app_different_executable.Text = "Choose";
this.btn_app_different_executable.UseVisualStyleBackColor = true;
this.btn_app_different_executable.Click += new System.EventHandler(this.btn_app_different_executable_Click);
this.btn_choose_alternative_executable.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_choose_alternative_executable.ForeColor = System.Drawing.Color.White;
this.btn_choose_alternative_executable.Location = new System.Drawing.Point(877, 115);
this.btn_choose_alternative_executable.Name = "btn_choose_alternative_executable";
this.btn_choose_alternative_executable.Size = new System.Drawing.Size(85, 27);
this.btn_choose_alternative_executable.TabIndex = 9;
this.btn_choose_alternative_executable.Text = "Choose";
this.btn_choose_alternative_executable.UseVisualStyleBackColor = true;
this.btn_choose_alternative_executable.Click += new System.EventHandler(this.btn_choose_alternative_executable_Click);
//
// txt_alternative_executable
//
@ -875,7 +1038,7 @@ namespace DisplayMagician.UIForms
this.txt_alternative_executable.Name = "txt_alternative_executable";
this.txt_alternative_executable.Size = new System.Drawing.Size(378, 26);
this.txt_alternative_executable.TabIndex = 4;
this.txt_alternative_executable.TextChanged += new System.EventHandler(this.txt_different_executable_TextChanged);
this.txt_alternative_executable.TextChanged += new System.EventHandler(this.txt_alternative_executable_TextChanged);
//
// rb_wait_alternative_executable
//
@ -887,7 +1050,7 @@ namespace DisplayMagician.UIForms
this.rb_wait_alternative_executable.TabIndex = 8;
this.rb_wait_alternative_executable.Text = "Wait until an alternative executable is closed before continuing:";
this.rb_wait_alternative_executable.UseVisualStyleBackColor = true;
this.rb_wait_alternative_executable.CheckedChanged += new System.EventHandler(this.rb_wait_process_CheckedChanged);
this.rb_wait_alternative_executable.CheckedChanged += new System.EventHandler(this.rb_wait_alternative_executable_CheckedChanged);
this.rb_wait_alternative_executable.Paint += new System.Windows.Forms.PaintEventHandler(this.radiobutton_Paint);
//
// rb_wait_executable
@ -909,7 +1072,7 @@ namespace DisplayMagician.UIForms
//
this.txt_executable.Location = new System.Drawing.Point(171, 10);
this.txt_executable.Name = "txt_executable";
this.txt_executable.Size = new System.Drawing.Size(416, 26);
this.txt_executable.Size = new System.Drawing.Size(489, 26);
this.txt_executable.TabIndex = 1;
this.txt_executable.TextChanged += new System.EventHandler(this.txt_executable_TextChanged);
//
@ -929,26 +1092,26 @@ namespace DisplayMagician.UIForms
//
this.label2.AutoSize = true;
this.label2.ForeColor = System.Drawing.Color.Transparent;
this.label2.Location = new System.Drawing.Point(819, 12);
this.label2.Location = new System.Drawing.Point(783, 12);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(70, 20);
this.label2.Size = new System.Drawing.Size(125, 20);
this.label2.TabIndex = 5;
this.label2.Text = "Timeout:";
this.label2.Text = "Max Wait (secs):";
this.label2.Paint += new System.Windows.Forms.PaintEventHandler(this.label_Paint);
//
// nud_timeout_executable
//
this.nud_timeout_executable.Location = new System.Drawing.Point(895, 10);
this.nud_timeout_executable.Location = new System.Drawing.Point(910, 10);
this.nud_timeout_executable.Maximum = new decimal(new int[] {
240,
0,
0,
0});
this.nud_timeout_executable.Name = "nud_timeout_executable";
this.nud_timeout_executable.Size = new System.Drawing.Size(70, 26);
this.nud_timeout_executable.Size = new System.Drawing.Size(55, 26);
this.nud_timeout_executable.TabIndex = 6;
this.nud_timeout_executable.Value = new decimal(new int[] {
30,
20,
0,
0,
0});
@ -1000,7 +1163,7 @@ namespace DisplayMagician.UIForms
this.txt_game_launcher.Location = new System.Drawing.Point(605, 76);
this.txt_game_launcher.Name = "txt_game_launcher";
this.txt_game_launcher.ReadOnly = true;
this.txt_game_launcher.Size = new System.Drawing.Size(175, 26);
this.txt_game_launcher.Size = new System.Drawing.Size(149, 26);
this.txt_game_launcher.TabIndex = 23;
//
// txt_game_name
@ -1036,11 +1199,14 @@ namespace DisplayMagician.UIForms
//
// btn_choose_game
//
this.btn_choose_game.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
this.btn_choose_game.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
this.btn_choose_game.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_choose_game.Font = new System.Drawing.Font("Microsoft Sans Serif", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_choose_game.ForeColor = System.Drawing.Color.White;
this.btn_choose_game.Location = new System.Drawing.Point(411, 115);
this.btn_choose_game.Location = new System.Drawing.Point(408, 117);
this.btn_choose_game.Name = "btn_choose_game";
this.btn_choose_game.Size = new System.Drawing.Size(29, 31);
this.btn_choose_game.Size = new System.Drawing.Size(40, 46);
this.btn_choose_game.TabIndex = 16;
this.btn_choose_game.Text = ">>";
this.btn_choose_game.UseVisualStyleBackColor = true;
@ -1085,26 +1251,26 @@ namespace DisplayMagician.UIForms
//
this.lbl_game_timeout.AutoSize = true;
this.lbl_game_timeout.ForeColor = System.Drawing.Color.White;
this.lbl_game_timeout.Location = new System.Drawing.Point(819, 79);
this.lbl_game_timeout.Location = new System.Drawing.Point(783, 79);
this.lbl_game_timeout.Name = "lbl_game_timeout";
this.lbl_game_timeout.Size = new System.Drawing.Size(70, 20);
this.lbl_game_timeout.Size = new System.Drawing.Size(125, 20);
this.lbl_game_timeout.TabIndex = 4;
this.lbl_game_timeout.Text = "Timeout:";
this.lbl_game_timeout.Text = "Max Wait (secs):";
this.lbl_game_timeout.Paint += new System.Windows.Forms.PaintEventHandler(this.label_Paint);
//
// nud_timeout_game
//
this.nud_timeout_game.Location = new System.Drawing.Point(895, 77);
this.nud_timeout_game.Location = new System.Drawing.Point(911, 77);
this.nud_timeout_game.Maximum = new decimal(new int[] {
240,
0,
0,
0});
this.nud_timeout_game.Name = "nud_timeout_game";
this.nud_timeout_game.Size = new System.Drawing.Size(70, 26);
this.nud_timeout_game.Size = new System.Drawing.Size(54, 26);
this.nud_timeout_game.TabIndex = 5;
this.nud_timeout_game.Value = new decimal(new int[] {
120,
20,
0,
0,
0});
@ -1141,6 +1307,7 @@ namespace DisplayMagician.UIForms
// tabp_after
//
this.tabp_after.BackColor = System.Drawing.Color.Black;
this.tabp_after.Controls.Add(this.groupBox2);
this.tabp_after.Controls.Add(this.groupBox1);
this.tabp_after.Controls.Add(this.gb_display_after);
this.tabp_after.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
@ -1152,42 +1319,83 @@ namespace DisplayMagician.UIForms
this.tabp_after.TabIndex = 3;
this.tabp_after.Text = "5. Choose what happens afterwards";
//
// groupBox2
//
this.groupBox2.Controls.Add(this.rb_switch_capture_permanent);
this.groupBox2.Controls.Add(this.rb_switch_capture_temp);
this.groupBox2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.groupBox2.ForeColor = System.Drawing.Color.White;
this.groupBox2.Location = new System.Drawing.Point(175, 404);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(765, 161);
this.groupBox2.TabIndex = 13;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "What happens to the Microphone afterwards?";
//
// rb_switch_capture_permanent
//
this.rb_switch_capture_permanent.AutoSize = true;
this.rb_switch_capture_permanent.ForeColor = System.Drawing.Color.White;
this.rb_switch_capture_permanent.Location = new System.Drawing.Point(98, 96);
this.rb_switch_capture_permanent.Name = "rb_switch_capture_permanent";
this.rb_switch_capture_permanent.Size = new System.Drawing.Size(492, 24);
this.rb_switch_capture_permanent.TabIndex = 12;
this.rb_switch_capture_permanent.Text = "Keep using the Microphone after Game ends (permanent change)";
this.rb_switch_capture_permanent.UseVisualStyleBackColor = true;
this.rb_switch_capture_permanent.CheckedChanged += new System.EventHandler(this.rb_switch_capture_permanent_CheckedChanged);
//
// rb_switch_capture_temp
//
this.rb_switch_capture_temp.AutoSize = true;
this.rb_switch_capture_temp.Checked = true;
this.rb_switch_capture_temp.ForeColor = System.Drawing.Color.White;
this.rb_switch_capture_temp.Location = new System.Drawing.Point(98, 48);
this.rb_switch_capture_temp.Name = "rb_switch_capture_temp";
this.rb_switch_capture_temp.Size = new System.Drawing.Size(553, 24);
this.rb_switch_capture_temp.TabIndex = 11;
this.rb_switch_capture_temp.TabStop = true;
this.rb_switch_capture_temp.Text = "Revert back to original Microphone (temporary change while running game)";
this.rb_switch_capture_temp.UseVisualStyleBackColor = true;
this.rb_switch_capture_temp.CheckedChanged += new System.EventHandler(this.rb_switch_capture_temp_CheckedChanged);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.rb_switch_audio_permanent);
this.groupBox1.Controls.Add(this.rb_switch_audio_temp);
this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.groupBox1.ForeColor = System.Drawing.Color.White;
this.groupBox1.Location = new System.Drawing.Point(175, 311);
this.groupBox1.Location = new System.Drawing.Point(175, 219);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(765, 203);
this.groupBox1.Size = new System.Drawing.Size(765, 161);
this.groupBox1.TabIndex = 12;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "What happens to the Audio afterwards?";
this.groupBox1.Text = "What happens to the Audio output afterwards?";
//
// rb_switch_audio_permanent
//
this.rb_switch_audio_permanent.AutoSize = true;
this.rb_switch_audio_permanent.ForeColor = System.Drawing.Color.White;
this.rb_switch_audio_permanent.Location = new System.Drawing.Point(98, 116);
this.rb_switch_audio_permanent.Location = new System.Drawing.Point(98, 96);
this.rb_switch_audio_permanent.Name = "rb_switch_audio_permanent";
this.rb_switch_audio_permanent.Size = new System.Drawing.Size(502, 24);
this.rb_switch_audio_permanent.TabIndex = 12;
this.rb_switch_audio_permanent.Text = "Keep using the Audio Device after Game ends (permanent change)";
this.rb_switch_audio_permanent.UseVisualStyleBackColor = true;
this.rb_switch_audio_permanent.CheckedChanged += new System.EventHandler(this.rb_switch_audio_permanent_CheckedChanged);
//
// rb_switch_audio_temp
//
this.rb_switch_audio_temp.AutoSize = true;
this.rb_switch_audio_temp.Checked = true;
this.rb_switch_audio_temp.ForeColor = System.Drawing.Color.White;
this.rb_switch_audio_temp.Location = new System.Drawing.Point(98, 68);
this.rb_switch_audio_temp.Location = new System.Drawing.Point(98, 48);
this.rb_switch_audio_temp.Name = "rb_switch_audio_temp";
this.rb_switch_audio_temp.Size = new System.Drawing.Size(563, 24);
this.rb_switch_audio_temp.TabIndex = 11;
this.rb_switch_audio_temp.TabStop = true;
this.rb_switch_audio_temp.Text = "Revert back to original Audio Device (temporary change while running game)";
this.rb_switch_audio_temp.UseVisualStyleBackColor = true;
this.rb_switch_audio_temp.CheckedChanged += new System.EventHandler(this.rb_switch_audio_temp_CheckedChanged);
//
// gb_display_after
//
@ -1195,9 +1403,9 @@ namespace DisplayMagician.UIForms
this.gb_display_after.Controls.Add(this.rb_switch_display_temp);
this.gb_display_after.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.gb_display_after.ForeColor = System.Drawing.Color.White;
this.gb_display_after.Location = new System.Drawing.Point(175, 58);
this.gb_display_after.Location = new System.Drawing.Point(175, 31);
this.gb_display_after.Name = "gb_display_after";
this.gb_display_after.Size = new System.Drawing.Size(765, 203);
this.gb_display_after.Size = new System.Drawing.Size(765, 162);
this.gb_display_after.TabIndex = 11;
this.gb_display_after.TabStop = false;
this.gb_display_after.Text = "What happens to the Display Profile afterwards?";
@ -1206,25 +1414,27 @@ namespace DisplayMagician.UIForms
//
this.rb_switch_display_permanent.AutoSize = true;
this.rb_switch_display_permanent.ForeColor = System.Drawing.Color.White;
this.rb_switch_display_permanent.Location = new System.Drawing.Point(98, 116);
this.rb_switch_display_permanent.Location = new System.Drawing.Point(98, 96);
this.rb_switch_display_permanent.Name = "rb_switch_display_permanent";
this.rb_switch_display_permanent.Size = new System.Drawing.Size(508, 24);
this.rb_switch_display_permanent.TabIndex = 12;
this.rb_switch_display_permanent.Text = "Keep using the Display Profile after Game ends (permanent change)";
this.rb_switch_display_permanent.UseVisualStyleBackColor = true;
this.rb_switch_display_permanent.CheckedChanged += new System.EventHandler(this.rb_switch_display_permanent_CheckedChanged);
//
// rb_switch_display_temp
//
this.rb_switch_display_temp.AutoSize = true;
this.rb_switch_display_temp.Checked = true;
this.rb_switch_display_temp.ForeColor = System.Drawing.Color.White;
this.rb_switch_display_temp.Location = new System.Drawing.Point(98, 68);
this.rb_switch_display_temp.Location = new System.Drawing.Point(98, 48);
this.rb_switch_display_temp.Name = "rb_switch_display_temp";
this.rb_switch_display_temp.Size = new System.Drawing.Size(569, 24);
this.rb_switch_display_temp.TabIndex = 11;
this.rb_switch_display_temp.TabStop = true;
this.rb_switch_display_temp.Text = "Revert back to original Display Profile (temporary change while running game)";
this.rb_switch_display_temp.UseVisualStyleBackColor = true;
this.rb_switch_display_temp.CheckedChanged += new System.EventHandler(this.rb_switch_display_temp_CheckedChanged);
//
// txt_shortcut_save_name
//
@ -1302,7 +1512,13 @@ namespace DisplayMagician.UIForms
this.tabp_display.ResumeLayout(false);
this.tabp_display.PerformLayout();
this.tabp_audio.ResumeLayout(false);
this.tabp_audio.PerformLayout();
this.gb_capture_settings.ResumeLayout(false);
this.gb_capture_settings.PerformLayout();
this.gb_capture_volume.ResumeLayout(false);
this.gb_capture_volume.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nud_capture_volume)).EndInit();
this.gb_audio_settings.ResumeLayout(false);
this.gb_audio_settings.PerformLayout();
this.gb_audio_volume.ResumeLayout(false);
this.gb_audio_volume.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nud_audio_volume)).EndInit();
@ -1324,6 +1540,8 @@ namespace DisplayMagician.UIForms
this.p_game.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nud_timeout_game)).EndInit();
this.tabp_after.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.gb_display_after.ResumeLayout(false);
@ -1367,7 +1585,7 @@ namespace DisplayMagician.UIForms
private System.Windows.Forms.Panel p_standalone;
private System.Windows.Forms.TextBox txt_args_executable;
private System.Windows.Forms.CheckBox cb_args_executable;
private System.Windows.Forms.Button btn_app_different_executable;
private System.Windows.Forms.Button btn_choose_alternative_executable;
private System.Windows.Forms.TextBox txt_alternative_executable;
private System.Windows.Forms.RadioButton rb_wait_alternative_executable;
private System.Windows.Forms.RadioButton rb_wait_executable;
@ -1413,20 +1631,34 @@ namespace DisplayMagician.UIForms
private System.Windows.Forms.CheckBox cb_start_program2;
private System.Windows.Forms.CheckBox cb_start_program1;
private System.Windows.Forms.TabPage tabp_audio;
private System.Windows.Forms.RadioButton rb_no_change_audio;
private System.Windows.Forms.RadioButton rb_change_audio;
private System.Windows.Forms.ComboBox cb_audio_device;
private System.Windows.Forms.Button btn_rescan_audio;
private System.Windows.Forms.GroupBox gb_display_after;
private System.Windows.Forms.RadioButton rb_switch_display_permanent;
private System.Windows.Forms.RadioButton rb_switch_display_temp;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.RadioButton rb_switch_audio_permanent;
private System.Windows.Forms.RadioButton rb_switch_audio_temp;
private System.Windows.Forms.GroupBox gb_capture_settings;
private System.Windows.Forms.GroupBox gb_capture_volume;
private System.Windows.Forms.RadioButton rb_set_capture_volume;
private System.Windows.Forms.RadioButton rb_keep_capture_volume;
private System.Windows.Forms.Label lbl_capture_volume;
private System.Windows.Forms.NumericUpDown nud_capture_volume;
private System.Windows.Forms.Button btn_rescan_capture;
private System.Windows.Forms.ComboBox cb_capture_device;
private System.Windows.Forms.RadioButton rb_change_capture;
private System.Windows.Forms.RadioButton rb_no_change_capture;
private System.Windows.Forms.GroupBox gb_audio_settings;
private System.Windows.Forms.GroupBox gb_audio_volume;
private System.Windows.Forms.RadioButton rb_set_audio_volume;
private System.Windows.Forms.RadioButton rb_keep_audio_volume;
private System.Windows.Forms.Label lbl_audio_volume;
private System.Windows.Forms.NumericUpDown nud_audio_volume;
private System.Windows.Forms.Button btn_rescan_audio;
private System.Windows.Forms.ComboBox cb_audio_device;
private System.Windows.Forms.RadioButton rb_change_audio;
private System.Windows.Forms.RadioButton rb_no_change_audio;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.RadioButton rb_switch_capture_permanent;
private System.Windows.Forms.RadioButton rb_switch_capture_temp;
}
}

View File

@ -8,7 +8,7 @@ using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using DisplayMagician.Resources;
using DisplayMagician.Shared;
using DisplayMagicianShared;
using DisplayMagician.GameLibraries;
using System.Globalization;
using Manina.Windows.Forms;
@ -27,11 +27,16 @@ namespace DisplayMagician.UIForms
private Executable _executableToUse;
private ShortcutPermanence _displayPermanence = ShortcutPermanence.Temporary;
private ShortcutPermanence _audioPermanence = ShortcutPermanence.Temporary;
private ShortcutPermanence _capturePermanence = ShortcutPermanence.Temporary;
List<StartProgram> _startPrograms = new List<StartProgram>();
private string _audioDevice = "";
private bool _changeAudioDevice = false;
private bool _setAudioVolume = false;
private decimal _audioVolume = -1;
private string _captureDevice = "";
private bool _changeCaptureDevice = false;
private bool _setCaptureVolume = false;
private decimal _captureVolume = -1;
private ShortcutItem _shortcutToEdit = null;
List<Game> allGames = new List<Game>();
private bool _isUnsaved = true;
@ -43,6 +48,9 @@ namespace DisplayMagician.UIForms
private List<CoreAudioDevice> audioDevices = null;
private CoreAudioDevice selectedAudioDevice = null;
private bool audioVolumeSetToDefault = true;
private List<CoreAudioDevice> captureDevices = null;
private CoreAudioDevice selectedCaptureDevice = null;
private bool captureVolumeSetToDefault = true;
public ShortcutForm(ShortcutItem shortcutToEdit)
{
@ -63,7 +71,7 @@ namespace DisplayMagician.UIForms
}*/
}
public string ProcessNameToMonitor
/* public string ProcessNameToMonitor
{
get
{
@ -79,11 +87,11 @@ namespace DisplayMagician.UIForms
{
// We we're setting this entry, then we want to set it to a particular entry
txt_alternative_executable.Text = value;
rb_wait_executable.Checked = true;
//rb_wait_executable.Checked = true;
}
}
public string ExecutableNameAndPath
*/
/* public string ExecutableNameAndPath
{
get => rb_switch_display_temp.Checked && rb_launcher.Checked ? txt_executable.Text : string.Empty;
set
@ -96,8 +104,8 @@ namespace DisplayMagician.UIForms
}
}
}
public uint ExecutableTimeout
*/
/* public uint ExecutableTimeout
{
get
{
@ -147,7 +155,7 @@ namespace DisplayMagician.UIForms
txt_game_name.Text = value;
}
}
*/
public ShortcutItem Shortcut
{
get => _shortcutToEdit;
@ -386,6 +394,31 @@ namespace DisplayMagician.UIForms
_audioVolume = -1;
}
// Save the Capture features
if (rb_change_capture.Checked)
{
_changeCaptureDevice = true;
_captureDevice = cb_capture_device.Text;
}
else
{
_changeCaptureDevice = false;
_captureDevice = "";
}
if (rb_set_capture_volume.Checked)
{
_setCaptureVolume = true;
_captureVolume = nud_capture_volume.Value;
}
else
{
_setCaptureVolume = false;
_captureVolume = -1;
}
// Check the audio permanence requirements
if (rb_switch_audio_temp.Checked)
_audioPermanence = ShortcutPermanence.Temporary;
@ -400,6 +433,13 @@ namespace DisplayMagician.UIForms
if (rb_switch_display_permanent.Checked)
_displayPermanence = ShortcutPermanence.Permanent;
// Check the microphone permanence requirements
if (rb_switch_capture_temp.Checked)
_capturePermanence = ShortcutPermanence.Temporary;
if (rb_switch_capture_permanent.Checked)
_capturePermanence = ShortcutPermanence.Permanent;
// Save the start program 1
StartProgram myStartProgram = new StartProgram();
myStartProgram.Priority = 1;
@ -457,9 +497,16 @@ namespace DisplayMagician.UIForms
_gameToUse,
_displayPermanence,
_audioPermanence,
_capturePermanence,
_gameToUse.GameToPlay.IconPath,
_changeAudioDevice,
_audioDevice,
_setAudioVolume,
_audioVolume,
_changeCaptureDevice,
_captureDevice,
_setCaptureVolume,
_captureVolume,
_startPrograms,
_autoName,
_uuid
@ -482,9 +529,16 @@ namespace DisplayMagician.UIForms
_gameToUse,
_displayPermanence,
_audioPermanence,
_capturePermanence,
_gameToUse.GameToPlay.IconPath,
_changeAudioDevice,
_audioDevice,
_setAudioVolume,
_audioVolume,
_changeCaptureDevice,
_captureDevice,
_setCaptureVolume,
_captureVolume,
_startPrograms,
_autoName,
_uuid
@ -516,9 +570,16 @@ namespace DisplayMagician.UIForms
_executableToUse,
_displayPermanence,
_audioPermanence,
_capturePermanence,
_executableToUse.ExecutableNameAndPath,
_changeAudioDevice,
_audioDevice,
_setAudioVolume,
_audioVolume,
_changeCaptureDevice,
_captureDevice,
_setCaptureVolume,
_captureVolume,
_startPrograms,
_autoName
);
@ -532,9 +593,16 @@ namespace DisplayMagician.UIForms
_profileToUse,
_displayPermanence,
_audioPermanence,
_capturePermanence,
_executableToUse.ExecutableNameAndPath,
_changeAudioDevice,
_audioDevice,
_setAudioVolume,
_audioVolume,
_changeCaptureDevice,
_captureDevice,
_setCaptureVolume,
_captureVolume,
_startPrograms,
_autoName
);
@ -549,7 +617,7 @@ namespace DisplayMagician.UIForms
this.Close();
}
private void txt_different_executable_TextChanged(object sender, EventArgs e)
private void txt_alternative_executable_TextChanged(object sender, EventArgs e)
{
if (_loadedShortcut)
_isUnsaved = true;
@ -730,9 +798,15 @@ namespace DisplayMagician.UIForms
selectedAudioDevice = audioDevice;
cb_audio_device.SelectedIndex = index;
if (_shortcutToEdit.SetAudioVolume && _shortcutToEdit.AudioVolume >= 0 && _shortcutToEdit.AudioVolume <= 100)
{
nud_audio_volume.Value = _shortcutToEdit.AudioVolume;
rb_set_audio_volume.Checked = true;
}
else
{
nud_audio_volume.Value = Convert.ToDecimal(audioDevice.Volume);
rb_set_audio_volume.Checked = false;
}
}
}
}
@ -781,6 +855,89 @@ namespace DisplayMagician.UIForms
rb_keep_audio_volume.Checked = true;
}
// Populate all the Capture devices in the capture devices list.
// Set the Capture device to the shortcut capture device only if
// the Change Capture radiobutton is set
rb_change_capture.Checked = _shortcutToEdit.ChangeCaptureDevice;
cb_capture_device.Items.Clear();
captureDevices = audioController.GetCaptureDevices().ToList();
// If the shortcut is to change the capture device
if (_shortcutToEdit.ChangeCaptureDevice)
{
// Then we need to populate the list
bool foundCaptureDevice = false;
foreach (CoreAudioDevice captureDevice in captureDevices)
{
if (captureDevice.State == AudioSwitcher.AudioApi.DeviceState.Active)
{
int index = cb_capture_device.Items.Add(captureDevice.FullName);
// Set the capture device to the default device by default
if (captureDevice.FullName.Equals(_shortcutToEdit.CaptureDevice))
{
foundCaptureDevice = true;
selectedCaptureDevice = captureDevice;
cb_capture_device.SelectedIndex = index;
if (_shortcutToEdit.SetCaptureVolume && _shortcutToEdit.CaptureVolume >= 0 && _shortcutToEdit.CaptureVolume <= 100)
{
nud_capture_volume.Value = _shortcutToEdit.CaptureVolume;
rb_set_capture_volume.Checked = true;
}
else
{
nud_capture_volume.Value = Convert.ToDecimal(captureDevice.Volume);
rb_set_capture_volume.Checked = false;
}
}
}
}
// We need to handle the edgecase where the selected capture device
// isn't currently plugged in. We don't want to break the shortcut
// as it could be plugged in when it comes time to actually run
// the shortcut, so we need to just add it to the list to not break
// the UI.
if (!foundCaptureDevice)
{
int index = cb_capture_device.Items.Add(_shortcutToEdit.CaptureDevice);
cb_capture_device.SelectedIndex = index;
selectedCaptureDevice = null;
if (_shortcutToEdit.SetCaptureVolume && _shortcutToEdit.CaptureVolume >= 0 && _shortcutToEdit.CaptureVolume <= 100)
{
rb_set_capture_volume.Checked = true;
nud_capture_volume.Value = _shortcutToEdit.CaptureVolume;
}
else
{
rb_keep_capture_volume.Checked = true;
nud_capture_volume.Value = 50;
}
}
}
else
{
captureVolumeSetToDefault = true;
// Then we need to populate the list
foreach (CoreAudioDevice captureDevice in captureDevices)
{
if (captureDevice.State == AudioSwitcher.AudioApi.DeviceState.Active)
{
int index = cb_capture_device.Items.Add(captureDevice.FullName);
// Set the capture device to the default device by default
if (captureDevice.IsDefaultDevice)
{
selectedCaptureDevice = captureDevice;
cb_capture_device.SelectedIndex = index;
nud_capture_volume.Value = Convert.ToDecimal(captureDevice.Volume);
}
}
}
rb_keep_capture_volume.Checked = true;
}
// Populate a full list of games
// Start with the Steam Games
allGames = new List<Game>();
@ -920,6 +1077,16 @@ namespace DisplayMagician.UIForms
break;
}
switch (_shortcutToEdit.CapturePermanence)
{
case ShortcutPermanence.Permanent:
rb_switch_capture_permanent.Checked = true;
break;
case ShortcutPermanence.Temporary:
rb_switch_capture_temp.Checked = true;
break;
}
// Set the launcher items if we have them
txt_game_launcher.Text = _shortcutToEdit.GameLibrary.ToString();
txt_game_name.Text = _shortcutToEdit.GameName;
@ -951,14 +1118,18 @@ namespace DisplayMagician.UIForms
{
cb_args_executable.Checked = true;
}
else
{
cb_args_executable.Checked = false;
}
if (_shortcutToEdit.ProcessNameToMonitorUsesExecutable)
{
rb_wait_executable.Checked = true;
rb_wait_alternative_executable.Checked = false;
//rb_wait_alternative_executable.Checked = false;
}
else
{
rb_wait_executable.Checked = false;
//rb_wait_executable.Checked = false;
rb_wait_alternative_executable.Checked = true;
}
txt_alternative_executable.Text = _shortcutToEdit.DifferentExecutableToMonitor;
@ -1022,7 +1193,7 @@ namespace DisplayMagician.UIForms
}
private void rb_wait_process_CheckedChanged(object sender, EventArgs e)
private void rb_wait_alternative_executable_CheckedChanged(object sender, EventArgs e)
{
if (rb_wait_alternative_executable.Checked)
{
@ -1030,6 +1201,7 @@ namespace DisplayMagician.UIForms
_isUnsaved = true;
rb_wait_executable.Checked = false;
txt_alternative_executable.Enabled = true;
btn_choose_alternative_executable.Enabled = true;
}
}
@ -1041,11 +1213,12 @@ namespace DisplayMagician.UIForms
_isUnsaved = true;
rb_wait_alternative_executable.Checked = false;
txt_alternative_executable.Enabled = false;
btn_choose_alternative_executable.Enabled = false;
}
}
private void btn_app_different_executable_Click(object sender, EventArgs e)
private void btn_choose_alternative_executable_Click(object sender, EventArgs e)
{
if (dialog_open.ShowDialog(this) == DialogResult.OK)
{
@ -1544,6 +1717,27 @@ namespace DisplayMagician.UIForms
}
}
private void rb_switch_audio_temp_CheckedChanged(object sender, EventArgs e)
{
if (rb_switch_audio_temp.Checked)
{
if (_loadedShortcut)
_isUnsaved = true;
rb_switch_audio_permanent.Checked = false;
}
}
private void rb_switch_audio_permanent_CheckedChanged(object sender, EventArgs e)
{
if (rb_switch_audio_permanent.Checked)
{
if (_loadedShortcut)
_isUnsaved = true;
rb_switch_audio_temp.Checked = false;
}
}
private void cb_audio_device_SelectedIndexChanged(object sender, EventArgs e)
{
if (_loadedShortcut)
@ -1555,8 +1749,7 @@ namespace DisplayMagician.UIForms
audioDevices = audioController.GetPlaybackDevices().ToList();
// If the shortcut is to change the audio device
if (_shortcutToEdit.ChangeAudioDevice)
{
// Then we need to populate the list
bool foundAudioDevice = false;
foreach (CoreAudioDevice audioDevice in audioDevices)
@ -1582,28 +1775,7 @@ namespace DisplayMagician.UIForms
if (!foundAudioDevice)
{
selectedAudioDevice = null;
nud_audio_volume.Value = _shortcutToEdit.AudioVolume;
}
}
else
{
audioVolumeSetToDefault = true;
// Then we need to populate the list
foreach (CoreAudioDevice audioDevice in audioDevices)
{
if (audioDevice.State == AudioSwitcher.AudioApi.DeviceState.Active)
{
int index = cb_audio_device.Items.Add(audioDevice.FullName);
// Set the audio device to the default device by default
if (audioDevice.IsDefaultDevice)
{
selectedAudioDevice = audioDevice;
cb_audio_device.SelectedIndex = index;
nud_audio_volume.Value = Convert.ToDecimal(audioDevice.Volume);
}
}
}
rb_keep_audio_volume.Checked = true;
nud_audio_volume.Value = 50;
}
}
@ -1704,5 +1876,193 @@ namespace DisplayMagician.UIForms
nud_audio_volume.Enabled = true;
}
private void btn_rescan_capture_Click(object sender, EventArgs e)
{
// Populate all the Capture devices in the capture devices list.
// Set the capture device to the shortcut capture device only if
// the Change capture radiobutton is set
rb_change_capture.Checked = _shortcutToEdit.ChangeCaptureDevice;
cb_capture_device.Items.Clear();
captureDevices = audioController.GetCaptureDevices().ToList();
// If the shortcut is to change the capture device
if (_shortcutToEdit.ChangeCaptureDevice)
{
// Then we need to populate the list
bool foundCaptureDevice = false;
foreach (CoreAudioDevice captureDevice in captureDevices)
{
if (captureDevice.State == AudioSwitcher.AudioApi.DeviceState.Active)
{
int index = cb_capture_device.Items.Add(captureDevice.FullName);
// Set the capture device to the default device by default
if (captureDevice.FullName.Equals(_shortcutToEdit.CaptureDevice))
{
foundCaptureDevice = true;
selectedCaptureDevice = captureDevice;
cb_capture_device.SelectedIndex = index;
if (_shortcutToEdit.SetCaptureVolume && _shortcutToEdit.CaptureVolume >= 0 && _shortcutToEdit.CaptureVolume <= 100)
nud_capture_volume.Value = _shortcutToEdit.CaptureVolume;
else
nud_capture_volume.Value = Convert.ToDecimal(captureDevice.Volume);
}
}
}
// We need to handle the edgecase where the selected capture device
// isn't currently plugged in. We don't want to break the shortcut
// as it could be plugged in when it comes time to actually run
// the shortcut, so we need to just add it to the list to not break
// the UI.
if (!foundCaptureDevice)
{
int index = cb_capture_device.Items.Add(_shortcutToEdit.CaptureDevice);
cb_capture_device.SelectedIndex = index;
selectedCaptureDevice = null;
if (_shortcutToEdit.SetCaptureVolume && _shortcutToEdit.CaptureVolume >= 0 && _shortcutToEdit.CaptureVolume <= 100)
{
rb_set_capture_volume.Checked = true;
nud_capture_volume.Value = _shortcutToEdit.CaptureVolume;
}
else
{
rb_keep_capture_volume.Checked = true;
nud_capture_volume.Value = 50;
}
}
}
else
{
captureVolumeSetToDefault = true;
// Then we need to populate the list
foreach (CoreAudioDevice captureDevice in captureDevices)
{
if (captureDevice.State == AudioSwitcher.AudioApi.DeviceState.Active)
{
int index = cb_capture_device.Items.Add(captureDevice.FullName);
// Set the capture device to the default device by default
if (captureDevice.IsDefaultDevice)
{
selectedCaptureDevice = captureDevice;
cb_capture_device.SelectedIndex = index;
nud_capture_volume.Value = Convert.ToDecimal(captureDevice.Volume);
}
}
}
rb_keep_capture_volume.Checked = true;
}
}
private void cb_capture_device_SelectedIndexChanged(object sender, EventArgs e)
{
if (_loadedShortcut)
_isUnsaved = true;
// Populate all the Capture devices in the capture devices list.
// Set the Capture device to the shortcut capture device only if
// the Change Capture radiobutton is set
captureDevices = audioController.GetCaptureDevices().ToList();
// Then we need to populate the list
bool foundCaptureDevice = false;
foreach (CoreAudioDevice captureDevice in captureDevices)
{
if (captureDevice.State == AudioSwitcher.AudioApi.DeviceState.Active)
{
// Set the capture device to the default device by default
if (captureDevice.FullName.Equals(cb_capture_device.SelectedItem.ToString()))
{
foundCaptureDevice = true;
selectedCaptureDevice = captureDevice;
nud_capture_volume.Value = Convert.ToDecimal(captureDevice.Volume);
}
}
}
// We need to handle the edgecase where the selected capture device
// isn't currently plugged in. We don't want to break the shortcut
// as it could be plugged in when it comes time to actually run
// the shortcut, so we need to just add it to the list to not break
// the UI.
if (!foundCaptureDevice)
{
selectedCaptureDevice = null;
nud_capture_volume.Value = 50;
}
}
private void rb_no_change_capture_CheckedChanged(object sender, EventArgs e)
{
if (rb_no_change_capture.Checked)
{
if (_loadedShortcut)
_isUnsaved = true;
cb_capture_device.Enabled = false;
btn_rescan_capture.Enabled = false;
gb_capture_volume.Visible = false;
}
}
private void rb_change_capture_CheckedChanged(object sender, EventArgs e)
{
if (rb_change_capture.Checked)
{
if (_loadedShortcut)
_isUnsaved = true;
cb_capture_device.Enabled = true;
btn_rescan_capture.Enabled = true;
gb_capture_volume.Visible = true;
}
}
private void rb_keep_capture_volume_CheckedChanged(object sender, EventArgs e)
{
if (_loadedShortcut)
_isUnsaved = true;
if (rb_set_capture_volume.Checked)
nud_capture_volume.Enabled = false;
}
private void rb_set_capture_volume_CheckedChanged(object sender, EventArgs e)
{
if (_loadedShortcut)
_isUnsaved = true;
if (rb_set_capture_volume.Checked)
nud_capture_volume.Enabled = true;
}
private void rb_switch_capture_temp_CheckedChanged(object sender, EventArgs e)
{
if (rb_switch_capture_temp.Checked)
{
if (_loadedShortcut)
_isUnsaved = true;
rb_switch_capture_permanent.Checked = false;
}
}
private void rb_switch_capture_permanent_CheckedChanged(object sender, EventArgs e)
{
if (rb_switch_capture_permanent.Checked)
{
if (_loadedShortcut)
_isUnsaved = true;
rb_switch_capture_temp.Checked = false;
}
}
private void nud_audio_volume_ValueChanged(object sender, EventArgs e)
{
_audioVolume = Convert.ToDecimal(nud_audio_volume.Value);
}
private void nud_capture_volume_ValueChanged(object sender, EventArgs e)
{
_captureVolume = Convert.ToDecimal(nud_capture_volume.Value);
}
}
}

View File

@ -40,6 +40,13 @@
this.dialog_save = new System.Windows.Forms.SaveFileDialog();
this.label1 = new System.Windows.Forms.Label();
this.tt_selected = new System.Windows.Forms.ToolTip(this.components);
this.lbl_create_shortcut = new System.Windows.Forms.Label();
this.cms_shortcuts = new System.Windows.Forms.ContextMenuStrip(this.components);
this.tsmi_edit = new System.Windows.Forms.ToolStripMenuItem();
this.tsmi_run = new System.Windows.Forms.ToolStripMenuItem();
this.tsmi_save_to_desktop = new System.Windows.Forms.ToolStripMenuItem();
this.tsmi_delete = new System.Windows.Forms.ToolStripMenuItem();
this.cms_shortcuts.SuspendLayout();
this.SuspendLayout();
//
// ilv_saved_shortcuts
@ -184,6 +191,61 @@
this.label1.TabIndex = 31;
this.label1.Text = "Game Shortcut Library";
//
// lbl_create_shortcut
//
this.lbl_create_shortcut.Anchor = System.Windows.Forms.AnchorStyles.None;
this.lbl_create_shortcut.AutoSize = true;
this.lbl_create_shortcut.BackColor = System.Drawing.Color.Brown;
this.lbl_create_shortcut.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lbl_create_shortcut.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
this.lbl_create_shortcut.ForeColor = System.Drawing.Color.White;
this.lbl_create_shortcut.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.lbl_create_shortcut.Location = new System.Drawing.Point(413, 562);
this.lbl_create_shortcut.Name = "lbl_create_shortcut";
this.lbl_create_shortcut.Size = new System.Drawing.Size(304, 22);
this.lbl_create_shortcut.TabIndex = 32;
this.lbl_create_shortcut.Text = "Click the \'New\' button to create a shortcut";
//
// cms_shortcuts
//
this.cms_shortcuts.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsmi_edit,
this.tsmi_run,
this.tsmi_save_to_desktop,
this.tsmi_delete});
this.cms_shortcuts.Name = "cms_shortcuts";
this.cms_shortcuts.Size = new System.Drawing.Size(216, 114);
//
// tsmi_edit
//
this.tsmi_edit.Font = new System.Drawing.Font("Segoe UI", 9F);
this.tsmi_edit.Name = "tsmi_edit";
this.tsmi_edit.Size = new System.Drawing.Size(215, 22);
this.tsmi_edit.Text = "Edit Shortcut...";
this.tsmi_edit.Click += new System.EventHandler(this.tsmi_edit_Click);
//
// tsmi_run
//
this.tsmi_run.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold);
this.tsmi_run.Name = "tsmi_run";
this.tsmi_run.Size = new System.Drawing.Size(215, 22);
this.tsmi_run.Text = "Run Shortcut...";
this.tsmi_run.Click += new System.EventHandler(this.tsmi_run_Click);
//
// tsmi_save_to_desktop
//
this.tsmi_save_to_desktop.Name = "tsmi_save_to_desktop";
this.tsmi_save_to_desktop.Size = new System.Drawing.Size(215, 22);
this.tsmi_save_to_desktop.Text = "Save Shortcut to Desktop...";
this.tsmi_save_to_desktop.Click += new System.EventHandler(this.tsmi_save_to_desktop_Click);
//
// tsmi_delete
//
this.tsmi_delete.Name = "tsmi_delete";
this.tsmi_delete.Size = new System.Drawing.Size(215, 22);
this.tsmi_delete.Text = "Delete Shortcut...";
this.tsmi_delete.Click += new System.EventHandler(this.tsmi_delete_Click);
//
// ShortcutLibraryForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -191,6 +253,7 @@
this.BackColor = System.Drawing.Color.Black;
this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
this.ClientSize = new System.Drawing.Size(1134, 716);
this.Controls.Add(this.lbl_create_shortcut);
this.Controls.Add(this.label1);
this.Controls.Add(this.btn_save);
this.Controls.Add(this.btn_new);
@ -207,7 +270,9 @@
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "DisplayMagician - Setup Game Shortcuts";
this.Activated += new System.EventHandler(this.ShortcutLibraryForm_Activated);
this.Load += new System.EventHandler(this.ShortcutLibraryForm_Load);
this.cms_shortcuts.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
@ -225,5 +290,11 @@
private System.Windows.Forms.SaveFileDialog dialog_save;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ToolTip tt_selected;
private System.Windows.Forms.Label lbl_create_shortcut;
private System.Windows.Forms.ContextMenuStrip cms_shortcuts;
private System.Windows.Forms.ToolStripMenuItem tsmi_edit;
private System.Windows.Forms.ToolStripMenuItem tsmi_run;
private System.Windows.Forms.ToolStripMenuItem tsmi_delete;
private System.Windows.Forms.ToolStripMenuItem tsmi_save_to_desktop;
}
}

View File

@ -1,18 +1,15 @@
using DisplayMagician.GameLibraries;
using DisplayMagician.Resources;
using DisplayMagician.Shared;
using DisplayMagicianShared;
using Manina.Windows.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.IconLib;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DisplayMagician.UIForms
@ -21,15 +18,11 @@ namespace DisplayMagician.UIForms
{
private ShortcutAdaptor _shortcutAdaptor = new ShortcutAdaptor();
//private ImageListViewItem _selectedShortcutILVItem = null;
private ShortcutItem _selectedShortcut = null;
public ShortcutLibraryForm()
{
InitializeComponent();
//_shortcutAdaptor = new ShortcutAdaptor();
//_shortcutRepository = new ShortcutRepository();
//_profileRepository = new ProfileRepository();
ilv_saved_shortcuts.MultiSelect = false;
ilv_saved_shortcuts.ThumbnailSize = new Size(100,100);
ilv_saved_shortcuts.AllowDrag = false;
@ -45,6 +38,8 @@ namespace DisplayMagician.UIForms
{
// Refresh the Shortcut Library UI
RefreshShortcutLibraryUI();
RemoveWarningIfShortcuts();
}
private void RefreshShortcutLibraryUI()
@ -62,9 +57,6 @@ namespace DisplayMagician.UIForms
foreach (ShortcutItem loadedShortcut in ShortcutRepository.AllShortcuts.OrderBy(s => s.Name))
{
//loadedProfile.SaveProfileImageToCache();
//newItem = new ImageListViewItem(loadedProfile.SavedProfileCacheFilename, loadedProfile.Name);
//newItem = new ImageListViewItem(loadedProfile, loadedProfile.Name);
newItem = new ImageListViewItem(loadedShortcut, loadedShortcut.Name);
// Select it if its the selectedProfile
@ -147,9 +139,28 @@ namespace DisplayMagician.UIForms
}
}
private void RemoveWarningIfShortcuts()
{
if (ShortcutRepository.AllShortcuts.Count > 0)
lbl_create_shortcut.Visible = false;
else
lbl_create_shortcut.Visible = true;
}
private void ilv_saved_shortcuts_ItemClick(object sender, ItemClickEventArgs e)
{
_selectedShortcut = GetShortcutFromName(e.Item.Text);
if (e.Buttons == MouseButtons.Right)
{
/* MessageBox.Show(
"Right button was clicked!",
"Mouse Button detected",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);*/
cms_shortcuts.Show(ilv_saved_shortcuts,e.Location);
}
}
private void ilv_saved_shortcuts_ItemDoubleClick(object sender, ItemClickEventArgs e)
@ -159,16 +170,19 @@ namespace DisplayMagician.UIForms
if (_selectedShortcut == null)
return;
var shortcutForm = new ShortcutForm(_selectedShortcut);
// Edit the Shortcut (now changed to RunShortcut)
/*var shortcutForm = new ShortcutForm(_selectedShortcut);
shortcutForm.ShowDialog(this);
if (shortcutForm.DialogResult == DialogResult.OK)
{
//ShortcutRepository.ReplaceShortcut(shortcutForm.Shortcut);
//_selectedShortcut = shortcutForm.Shortcut;
RefreshShortcutLibraryUI();
// As this is an edit, we need to manually force saving the shortcut library
ShortcutRepository.SaveShortcuts();
}
*/
// Run the shortcut when doubleclicked
btn_run.PerformClick();
}
@ -182,6 +196,7 @@ namespace DisplayMagician.UIForms
_selectedShortcut = shortcutForm.Shortcut;
RefreshShortcutLibraryUI();
}
RemoveWarningIfShortcuts();
}
private void btn_edit_Click(object sender, EventArgs e)
@ -197,8 +212,6 @@ namespace DisplayMagician.UIForms
shortcutForm.ShowDialog(this);
if (shortcutForm.DialogResult == DialogResult.OK)
{
//ShortcutRepository.ReplaceShortcut(shortcutForm.Shortcut);
//_selectedShortcut = shortcutForm.Shortcut;
RefreshShortcutLibraryUI();
// As this is an edit, we need to manually force saving the shortcut library
ShortcutRepository.SaveShortcuts();
@ -223,6 +236,7 @@ namespace DisplayMagician.UIForms
_selectedShortcut = null;
RefreshShortcutLibraryUI();
RemoveWarningIfShortcuts();
}
private void btn_run_Click(object sender, EventArgs e)
@ -233,9 +247,9 @@ namespace DisplayMagician.UIForms
// Figure out the string we're going to use as the MaskedForm message
string message = "";
if (_selectedShortcut.Category.Equals(ShortcutCategory.Application))
message = $"Starting the {_selectedShortcut.ExecutableNameAndPath} application and waiting until you close it.";
message = $"Running the {_selectedShortcut.ExecutableNameAndPath} application and waiting until you close it.";
else if (_selectedShortcut.Category.Equals(ShortcutCategory.Game))
message = $"Starting the {_selectedShortcut.GameName} game and waiting until you close it.";
message = $"Running the {_selectedShortcut.GameName} game and waiting until you close it.";
// Create a MaskForm that will cover the ShortcutLibrary Window to lock
// the controls and inform the user that the game is running....
@ -262,5 +276,30 @@ namespace DisplayMagician.UIForms
tt_selected.RemoveAll();
}
}
private void ShortcutLibraryForm_Activated(object sender, EventArgs e)
{
RemoveWarningIfShortcuts();
}
private void tsmi_save_to_desktop_Click(object sender, EventArgs e)
{
btn_save.PerformClick();
}
private void tsmi_run_Click(object sender, EventArgs e)
{
btn_run.PerformClick();
}
private void tsmi_edit_Click(object sender, EventArgs e)
{
btn_edit.PerformClick();
}
private void tsmi_delete_Click(object sender, EventArgs e)
{
btn_delete.PerformClick();
}
}
}

View File

@ -126,6 +126,9 @@
<metadata name="tt_selected.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>132, 17</value>
</metadata>
<metadata name="cms_shortcuts.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>242, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
using McMaster.Extensions.CommandLineUtils;
using McMaster.Extensions.CommandLineUtils.Validation;
using System.ComponentModel.DataAnnotations;
using DisplayMagician.Shared;
using DisplayMagicianShared;
using DisplayMagician.GameLibraries;
using System.Text.RegularExpressions;
using System.ServiceModel.Dispatcher;

View File

Before

Width:  |  Height:  |  Size: 457 KiB

After

Width:  |  Height:  |  Size: 457 KiB

View File

@ -8,8 +8,8 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{76DF2BCF-911B-4820-B63E-8F3468DB5E79}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>HeliosPlus.LogReporter</RootNamespace>
<AssemblyName>HeliosPlus.LogReporter</AssemblyName>
<RootNamespace>DisplayMagicianLogReporter</RootNamespace>
<AssemblyName>LogReporter</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
@ -48,7 +48,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<OutputPath>..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
@ -83,6 +83,9 @@
<Content Include="DisplayMagician.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AudioSwitcher.AudioApi.CoreAudio">
<Version>4.0.0-alpha5</Version>
</PackageReference>
<PackageReference Include="Costura.Fody">
<Version>4.1.0</Version>
</PackageReference>
@ -99,9 +102,9 @@
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DisplayMagician.Shared\DisplayMagician.Shared.csproj">
<ProjectReference Include="..\DisplayMagicianShared\DisplayMagicianShared.csproj">
<Project>{1cacda43-01c7-4cd4-bf6e-9421a29510fc}</Project>
<Name>DisplayMagician.Shared</Name>
<Name>DisplayMagicianShared</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>

View File

@ -7,16 +7,19 @@ using System.Linq;
using System.Reflection;
using WindowsDisplayAPI;
using WindowsDisplayAPI.DisplayConfig;
using DisplayMagician.Shared;
using NvAPIWrapper.GPU;
using NvAPIWrapper.Mosaic;
using AudioSwitcher.AudioApi.CoreAudio;
using DisplayMagicianShared;
namespace DisplayMagician.LogReporter
namespace DisplayMagicianLogReporter
{
internal class Program
{
private static StreamWriter _writer;
internal static string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DisplayMagician");
internal static string LoggingDirPath = Path.Combine(AppDataPath, "Logs");
private static void DumpObject<T>(
IEnumerable<T> items,
@ -87,6 +90,13 @@ namespace DisplayMagician.LogReporter
private static void Main(string[] args)
{
// This sets the Application User Model ID to "LittleBitBig.DisplayMagician" so that
// Windows 10 recognises the application, and allows features such as Toasts,
// taskbar pinning and similar.
// This is a helper function that sets the AUMID to a static default defined
// within ShellUtils under the DisplayMagicianShared project.
ShellUtils.SetDefaultProcessExplicitAppUserModelID();
Console.WriteLine("DisplayMagician LogReporter");
Console.WriteLine("======================");
Console.WriteLine();
@ -97,10 +107,60 @@ namespace DisplayMagician.LogReporter
Console.WriteLine();
Console.WriteLine("Starting the interrogation...");
Console.WriteLine();
try
{
Directory.CreateDirectory(LoggingDirPath);
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine($"ERROR - Cannot create logging directory as unauthorised: {LoggingDirPath}");
}
catch (ArgumentException ex)
{
Console.WriteLine($"ERROR - Cannot create logging directory as LoggingDirPath argument caused an ArgumentException: {LoggingDirPath}");
}
catch (PathTooLongException ex)
{
Console.WriteLine($"ERROR - Cannot create logging directory as the path is too long for Windows to create: {LoggingDirPath}");
}
catch (DirectoryNotFoundException ex)
{
Console.WriteLine($"ERROR - Cannot create logging directory as the DisplayMagician Local Application Data directory doesn't exist: {LoggingDirPath}");
}
catch (NotSupportedException ex)
{
Console.WriteLine($"ERROR - Cannot create logging directory as the Directory.CreateDirectory function isn't supported: {LoggingDirPath}");
}
string date = DateTime.Now.ToString("yyyyMMdd.HHmmss");
string logFile = Path.Combine(LoggingDirPath, $"LogReporter.{date}.log");
try
{
_writer = new StreamWriter(new FileStream(
string.Format("DisplayMagician.Reporting.{0}.log", date),
logFile,
FileMode.CreateNew));
}
catch (System.Security.SecurityException ex)
{
Console.WriteLine($"ERROR - Cannot create log file due to a security exception: {logFile}");
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine($"ERROR - Cannot create log file as unauthorised: {logFile}");
}
catch (ArgumentException ex)
{
Console.WriteLine($"ERROR - Cannot create log file as LogFile argument caused an ArgumentException while creating Filestream or StreamWriter: {logFile}");
}
catch (PathTooLongException ex)
{
Console.WriteLine($"ERROR - Cannot create log file as the path is too long for Windows to create: {logFile}");
}
catch (DirectoryNotFoundException ex)
{
Console.WriteLine($"ERROR - Cannot create log file as the DisplayMagician\\Logs Local Application Data directory doesn't exist: {logFile}");
}
try
{
@ -273,7 +333,17 @@ namespace DisplayMagician.LogReporter
try
{
DumpObject(GridTopology.GetGridTopologies(), "Storing a list of configured NZIVIDA Surround/Mosaic settings involving multiple Displays via a NVIDIA GPU", null, 3);
DumpObject(GridTopology.GetGridTopologies(), "Storing a list of configured NVIDIA Surround/Mosaic settings involving multiple Displays via a NVIDIA GPU", null, 3);
}
catch (Exception e)
{
WriteException(e);
}
try
{
CoreAudioController audioController = new CoreAudioController();
DumpObject(audioController.GetPlaybackDevices(), "Storing a list of detected Audio Devices", null, 3);
}
catch (Exception e)
{
@ -286,7 +356,7 @@ namespace DisplayMagician.LogReporter
Console.WriteLine(new string('=', Console.BufferWidth));
Console.WriteLine();
Console.WriteLine(@"Done, press enter to exit.");
Console.WriteLine(@"Finished! Press enter to exit LogReporter.");
Console.ReadLine();
}

View File

@ -4,12 +4,12 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DisplayMagician.Reporting")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("DisplayMagician LogReporter")]
[assembly: AssemblyDescription("Collect information about your computer to aid troubleshooting DisplayMagician errors.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DisplayMagician.Reporting")]
[assembly: AssemblyCopyright("Copyright © 2020 Terry MacDonald")]
[assembly: AssemblyCompany("LittleBitBig")]
[assembly: AssemblyProduct("DisplayMagician")]
[assembly: AssemblyCopyright("Copyright © Terry MacDonald 2020-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -19,7 +19,7 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6593e413-dadb-457b-892a-f17db1cf308b")]
[assembly: Guid("85444b80-98eb-4f39-b1e4-cdd27e7f86d0")]
// Version information for an assembly consists of the following four values:
//
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("0.2.1.0")]
[assembly: AssemblyFileVersion("0.2.1.0")]

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI>
<Dialog Id="LicenseAgreementDialogOverwritten" Width="370" Height="270" Title="!(loc.LicenseAgreementDlg_Title)">
<Control Id="LicenseAcceptedOverwrittenCheckBox" Type="CheckBox" X="20" Y="207" Width="330" Height="18" CheckBoxValue="1" Property="LicenseAcceptedOverwritten" Text="!(loc.LicenseAgreementDlgLicenseAcceptedCheckBox)" />
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">CostingComplete = 1</Publish>
<Condition Action="disable">
<![CDATA[ LicenseAcceptedOverwritten <> "1" ]]>
</Condition>
<Condition Action="enable">LicenseAcceptedOverwritten = "1"</Condition>
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.LicenseAgreementDlgBannerBitmap)" />
<Control Id="LicenseText" Type="ScrollableText" X="20" Y="60" Width="330" Height="140" Sunken="yes" TabSkip="no">
<!-- This is original line -->
<!--<Text SourceFile="!(wix.WixUILicenseRtf=$(var.LicenseRtf))" />-->
<!-- To enable EULA localization we change it to this -->
<Text SourceFile="$(var.ProjectDir)\!(loc.LicenseRtf)" />
<!-- In each of localization files (wxl) put line like this:
<String Id="LicenseRtf" Overridable="yes">\Lang\en-us\EULA_en-us.rtf</String>-->
</Control>
<Control Id="Print" Type="PushButton" X="112" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)">
<Publish Event="DoAction" Value="WixUIPrintEula">1</Publish>
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="340" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgDescription)" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgTitle)" />
</Dialog>
</UI>
</Fragment>
</Wix>

View File

@ -0,0 +1,283 @@
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="INSTALLLOCATION">
<Component Id="cmpBD0A0533F40E0B874A023E467EE15884" Guid="{9E252AC3-A9E2-4271-A836-CE1A0DB41573}">
<File Id="fil4C17B0D8A1167A78DB06FAABB5128E48" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\AudioSwitcher.AudioApi.CoreAudio.dll" />
</Component>
<Component Id="cmp1978460F20832AFD58CEFD336AAAA41B" Guid="{B1C9564E-2139-4D9E-82EC-325294B33702}">
<File Id="fil92D10CB9DD9C2F6D65022C362303A01F" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\AudioSwitcher.AudioApi.dll" />
</Component>
<Component Id="cmpB6DCEBC121FFE67E27945FC59FAF34EB" Guid="{D1D8FC7E-47DA-4495-92AF-7589D4E50DDE}">
<File Id="fil7ABE94A3C314EC0C3136C0157C33CA21" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\AutoUpdater.NET.dll" />
</Component>
<Component Id="cmp32E7E4241B870E8E1272B218DAFC18BD" Guid="{A0D0659E-8D02-48B3-BD47-3854038CF932}">
<File Id="fil9F175C8FEACC74CA04349855C1B662A9" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\AutoUpdater.NET.pdb" />
</Component>
<Component Id="cmp0BFD48C29EF7E91136AE7ECB2562A439" Guid="{7C257836-2E19-4F56-85BE-8B452F1956E3}">
<File Id="fil0FFAD7737931E9EEF891817E676A5F76" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\CircularProgressBar.dll" />
</Component>
<Component Id="cmpC627D6669C8B7F6118B278B985611D23" Guid="{83884D9B-0E7C-49FE-9AF6-3DCB35148FD8}">
<File Id="fil494F3C121DAECC3F76C20D7C096C7BC5" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\DisplayMagician.exe" />
</Component>
<Component Id="cmpCDC1AACC3E4B47262615C1CF34C96FDC" Guid="{250AE88F-BF30-4F1F-9096-03B36F94F48E}">
<File Id="fil77D26E1B67AD540F5834D9920B42F24F" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\DisplayMagician.exe.config" />
</Component>
<Component Id="cmpBC67EE8B6ADC74240F4BA176F17FA2E7" Guid="{863A2F09-7073-49F2-B700-6ED211931505}">
<File Id="filE26162A5F46BEB1D56A2594C1A1AC999" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\DisplayMagician.pdb" />
</Component>
<Component Id="cmp85F426B2D7B7BE110260F69908CF89DC" Guid="{D08BBC86-A447-4E46-8161-5DBF7740EB29}">
<File Id="filC8384C8C912AFA89A3E04DC60C8F3435" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\DisplayMagician.Shared.dll" />
</Component>
<Component Id="cmp079376624ED9003D040D434FD0AD79FC" Guid="{231B5C6C-FD35-4364-9AC3-D89241F06298}">
<File Id="fil0C4BCA2C88059E0B2B383EB35ACA08B9" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\DisplayMagician.Shared.pdb" />
</Component>
<Component Id="cmpE03B764D1598084EA84F72C0DC54A5FE" Guid="{215E8DB1-98C8-4E0D-BEC0-98C60EFDC138}">
<File Id="fil6C34EA41DEE6DDE2872AD7D4621058B4" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\DisplayMagicianShellExtension.dll" />
</Component>
<Component Id="cmpFA9BAE6E0F706FE8C2FB87226A21172A" Guid="{54DE6126-F5CC-42B3-AD6B-489A72B94B29}">
<File Id="filA371B7953F2BB8391D1F8458D683079B" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\DisplayMagicianShellExtension.pdb" />
</Component>
<Component Id="cmp03435CB09F2E9F019BAA38AE75428254" Guid="{4BB16EF8-2542-472C-9091-B71D38D93D1E}">
<File Id="filBC272C58432E02E698865174349D0E05" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\EDIDParser.dll" />
</Component>
<Component Id="cmp2776B662029F8701F5335F0DF08E554F" Guid="{C7AB573F-875D-428E-A11E-E175B05E7FA1}">
<File Id="fil8C05FEAC04235CDBA853630807C24809" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\HtmlAgilityPack.dll" />
</Component>
<Component Id="cmpA038AEB808EE721D74BCE483FE0CF5C4" Guid="{8E567C6E-35EB-40AD-A0EF-4A063A5C7729}">
<File Id="filFB7CF8A0E43ACB661913A0E02FDDCD11" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\HtmlAgilityPack.pdb" />
</Component>
<Component Id="cmp04AD32E960B2A9FBA1822AE873954545" Guid="{7C4A777B-F3FB-4B5B-A352-3F444D8B88E4}">
<File Id="filEA9147DB83A2C0F65371B43F4D9C9BCB" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\IconExtractor.dll" />
</Component>
<Component Id="cmp48136D75F10658FE78119AADF6F1725A" Guid="{478EF650-A33B-4C7B-90F0-8AF2D183EFDF}">
<File Id="fil84FFF5217D881EA07D3B9D2D538F7AE8" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\IconLib.dll" />
</Component>
<Component Id="cmpE3BF3E5AF0925FB86E3F382572243621" Guid="{3DE8C956-9275-41ED-B159-AE3AF36BCBBB}">
<File Id="fil0A93B7A09C08D0A230B2C949A8AA5304" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\IconPicker.dll" />
</Component>
<Component Id="cmp618EC65A5E4D9E8FEBB887B76DA4FD50" Guid="{3F4F9229-5BD3-4EF7-A812-0A3AA9BA6882}">
<File Id="fil78062F10F05E50F2506C12C4B217E151" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\ImageListView.dll" />
</Component>
<Component Id="cmp875F9AB6D5D996C61588EFA96C16CB26" Guid="{A59B21FB-CA6C-44FE-BC18-46BE1BD3490C}">
<File Id="fil3B270748720CCFAA24387517AB8FF3FF" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\LogReporter.exe" />
</Component>
<Component Id="cmp1AE47A82DB5E00D1488DE0C214B82747" Guid="{77E99484-5443-41F6-A578-E48ED3BA902C}">
<File Id="fil645AD0FF1C2BEDCD684F41EA8688B73A" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\LogReporter.exe.config" />
</Component>
<Component Id="cmp3C945FD02B7EBC852A737F0B9EA06402" Guid="{49D7E54F-3573-4D0B-BB98-150B40BA615B}">
<File Id="filC104ADE5B3714AABC35E4D29B909E535" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\LogReporter.pdb" />
</Component>
<Component Id="cmp9822C8E3EA9DED31B19647D3BEF403FF" Guid="{1FB6BA30-0CEF-4C43-B92B-19A7CE5270C6}">
<File Id="fil3E9465C169638FDC17B20EB6A1B0BF4D" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\McMaster.Extensions.CommandLineUtils.dll" />
</Component>
<Component Id="cmpECA87B17F9BBA2AE63349CE09D7514F3" Guid="{7A109499-4AA8-4BD8-86B9-606A78A9BBE0}">
<File Id="filC0D7D34F5027CC5C711404C26E1C74C4" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\Microsoft.Toolkit.Uwp.Notifications.dll" />
</Component>
<Component Id="cmpC7A842805FA293C91E6B671E1E4857CB" Guid="{CCD44B95-B5AD-490F-8861-9F9EF171DB98}">
<File Id="fil7F4E71A0451AD02B2EAE01D281D242D1" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\Microsoft.Toolkit.Uwp.Notifications.pdb" />
</Component>
<Component Id="cmp49B14D6F63FD6F782375E764F888D9F6" Guid="{E9243541-FF9F-49A8-96D3-ADEA23C0B1F3}">
<File Id="filB77C4B64126F698E45A7DA791BDB4DB9" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\MintPlayer.IconUtils.dll" />
</Component>
<Component Id="cmpE48528C4F5932A4EFD89F7331108F45D" Guid="{B63BEA94-D028-40F5-B020-B9FE808E99D8}">
<File Id="filF1B84C2C6BCC693224B7A7959445B74F" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\Newtonsoft.Json.dll" />
</Component>
<Component Id="cmp0758E167CC73C057A0ECE2DC5E35F506" Guid="{CAD401DE-BF37-410C-9E4B-DF86DF02F10C}">
<File Id="fil61D8D3E960CBBF3448E98CF5D5492B82" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\NLog.dll" />
</Component>
<Component Id="cmp24DB16B950576B6883BCB451D9881EBC" Guid="{B1B36B57-A637-463C-94CA-E9743E37392C}">
<File Id="fil2EE7C5C495E3AB1AC7458B4EC0C9D6FA" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\NvAPIWrapper.dll" />
</Component>
<Component Id="cmp46530108D41744F25886A5898DC5A274" Guid="{5AC24854-1BAA-409C-AC4C-88330837BC1D}">
<File Id="fil85B076D4C5F8142F16F909C45A7CDC9E" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\QueryString.NETCore.dll" />
</Component>
<Component Id="cmpE475EAC321A295365F62D280DFFFCFDD" Guid="{74B90189-3AFB-4499-AB70-FEBD1D26C4EC}">
<File Id="filC778B8BCCE4C543832118259908D143D" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\QueryString.NETCore.pdb" />
</Component>
<Component Id="cmp35AEFE57A4E4F326AB35BB1BFAC10ABC" Guid="{D77485A9-8D02-49A9-99D7-74073CA5C793}">
<File Id="filEAC63730569977F90ACD168AAD355C82" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\ServerRegistrationManager.exe" />
</Component>
<Component Id="cmpBF2E14544E7404D9716B1E616AFF1821" Guid="{D3D4A86F-CB3B-498C-985E-F39C9D03B8C5}">
<File Id="filB3D88EA6FA1A17CF31BA69CA52ED367C" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\SharpShell.dll" />
</Component>
<Component Id="cmpA97212A22F03B19D8D9FB95C1B706F67" Guid="{8D1CFCEC-9C7F-4468-98D8-DD6F92F9DD16}">
<File Id="filDD1B5F5F06ECE1BB9340F6D6E605F66C" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\System.Drawing.Common.dll" />
</Component>
<Component Id="cmp7964C303BA027BE990A3E8327EC91498" Guid="{E827A1EC-AF0A-4194-8F1A-0A2D8A7160E4}">
<File Id="fil4F3DC2E517A3ADABE5047501AC692728" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\System.ValueTuple.dll" />
</Component>
<Component Id="cmp5C0F2F2987EC8A4E1ABFC07281B44BC0" Guid="{FF9C0D70-2E1D-4F01-AD70-0A178E6BC876}">
<File Id="fil817D8F2ACA83169F37944BCA193C33A4" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\ValveKeyValue.dll" />
</Component>
<Component Id="cmp6C1CA4699436E48FBC65429D3DDE3729" Guid="{5D708839-0269-4AB3-9981-8724C741F2BF}">
<File Id="fil51D5FE7B16ABC635EDA85484998C6933" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\WindowsDisplayAPI.dll" />
</Component>
<Component Id="cmpCA92E5DFCB483577A26FEC321AFD558D" Guid="{8D00AF96-41F7-4B97-838B-28348B9FB23A}">
<File Id="fil544EB8EEB0462E3B5707E7102161835A" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\WinFormAnimation.dll" />
</Component>
<Directory Id="dirBDEF052B2576CF9365A2D0E000A240F9" Name="ar">
<Component Id="cmp4533A51FA0E8641930679AD37424B8B9" Guid="{6F3CD511-DD42-4045-9817-EF68E4704A41}">
<File Id="filF3758524BE9C3ABCE40D87629C673C18" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\ar\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir1C3D787E1A6537A1AC7450DEBBB621D8" Name="cs">
<Component Id="cmpB8E69B802F308C31E92E32AB958DAF68" Guid="{718EE802-8C61-4F31-B90E-2064072112B2}">
<File Id="fil12637BCCCB56BECA8444E55A912DA159" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\cs\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir9E7B3AF1734850560874B26C769E072C" Name="da">
<Component Id="cmp7806D754FCAB20844210E15AE6C04EBE" Guid="{B8D78154-22AB-4DEE-9C38-B1606AB14811}">
<File Id="fil9FFD1C98F8DE06D17A0CC3FF98E5936C" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\da\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirB27348B57A5DB473BF7C6C7DF00A5DBA" Name="de">
<Component Id="cmp040780EB1A6483479A96E102B7E22681" Guid="{F43B79CC-1530-4B51-9292-17877DC420A2}">
<File Id="fil9AD235E083DC8DEF92331B132A05959B" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\de\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir562D8D513850F1ADE7FBC3F03925F40D" Name="es">
<Component Id="cmpC488B4BB40BA5248FFBD28351333AEE2" Guid="{AC13A2DF-A523-4921-AA24-831AB0C106A2}">
<File Id="filB7AEDD98BBD6A14C33FCC1D98E9735CB" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\es\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir72226116A8527C99EDF529487A911522" Name="fr">
<Component Id="cmpB1D2F10332449DEAAAAE97A0E648E9C0" Guid="{20661849-90F1-4AFE-AC69-CE8DC57F08D6}">
<File Id="filFF20F561B08D3234BC482D24C196AD83" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\fr\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir35E624903EE34E687FB4AA2ED234EDEB" Name="it">
<Component Id="cmpA69B8A712387D3B90D6813098B05C34A" Guid="{A9DFE5A6-97B7-483A-AF82-205B148EBA81}">
<File Id="fil2D9EDE43E581C5EF8945CEE55BC949C7" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\it\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirBFA76CA2FD807FBC75C9577ED4EFA0D5" Name="ja-JP">
<Component Id="cmpC4DF80F866A83C22E8A0E9C8FC25C9C1" Guid="{AD3AA284-7DD0-4897-80C3-B2D1E05A6753}">
<File Id="fil7F7345572F76E3B2B39945B731C396E0" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\ja-JP\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir36D6CA8E5A6770CE8A5D00823F5A6613" Name="ko">
<Component Id="cmp7C71840B04F7F507D8FA41923689CDF2" Guid="{A48CB415-F212-4850-9E2A-4645DCA6BFFF}">
<File Id="fil13140B2D039385BDE51EFB5A048E0237" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\ko\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir8FBB90DDC324F6321DFF9F2D6D84E64E" Name="nl">
<Component Id="cmp564BF443013A98EBC72A01B8D461D8B0" Guid="{C9B827FB-43B2-43BE-9C00-E50A5A6C8D7B}">
<File Id="filD4D6AB197C7B096673F930535427786B" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\nl\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir21989BFF92788839A813E6BD05B4E026" Name="pl">
<Component Id="cmp2B08E9F49E70994AD433A60E3F7B0BEB" Guid="{FEAC2DA7-FBFC-44C3-A762-6E0AE6A9A2AF}">
<File Id="filA54B32D27F233C7C8283785EDED604B7" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\pl\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir22B21054EA6650472394994548C8D815" Name="pt">
<Component Id="cmp092F57310F36F676B6C8E8397742A26C" Guid="{E9965BA3-A9CD-4B8E-89A4-2362BF4D5467}">
<File Id="filE31F4F38C11AEEE51085DEB2F03C38BE" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\pt\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir018DA28F958AD633693D708EED8737E4" Name="pt-BR">
<Component Id="cmp624BAAB1945C8547300753CB1BE04D2F" Guid="{A782DCAE-8976-432E-9B2A-F3924E5A295B}">
<File Id="filE0FBDBC75D47655E4E4B937D089A6A4F" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\pt-BR\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirD7F168AE7E2140C2AFD9C7E999CF79E1" Name="ru">
<Component Id="cmpA4C0AEE73CF23CAC1F85DF3325071906" Guid="{4A0A0AA9-A33C-4E06-8AF6-3855B37D8343}">
<File Id="filB4EF5073568270FAC3FA05B5E9CC9533" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\ru\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir87D7C9C83B53FFBE05D144C750CBC9FA" Name="sk">
<Component Id="cmp4131995471E81CAF43CA25A941AA1309" Guid="{E32085C0-1B54-41A8-86FD-AF59CBC656F4}">
<File Id="fil51F2FF4688BDA96458542E8AB4252A92" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\sk\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirCF5A8114DE3D476B3D414A1B48B20988" Name="sv">
<Component Id="cmpD7962077D44195A7BCC3B8DC0B809152" Guid="{106F48E2-61B6-4BB4-BC2A-AB3ABC37C4DD}">
<File Id="filFA90139457939D319E71E1B5A11061DC" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\sv\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirF1E7F88F9C5F44DE50975BA01DEAF21E" Name="th">
<Component Id="cmp344C9604A259DAB1C241685400F60C59" Guid="{E7199ACA-0115-4877-829C-547A4D5BE182}">
<File Id="fil9827FE8AA424E94EE3455E6A4427B100" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\th\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirC98B6E60883E9973639508E26AA40BC3" Name="tr">
<Component Id="cmp1D08C460D6987792DC635727E811FC55" Guid="{7A0CB770-014C-4F73-A289-34E0792EACE0}">
<File Id="filE5830FEDD90EC9926F85B5A3B7E95893" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\tr\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir7D3A56698BA4558E7D105FEAFC74CB06" Name="zh">
<Component Id="cmpFB11AB8C27CB0CC824707BF5FC281DEB" Guid="{726C26E3-9B54-4695-98C4-0C783B05112B}">
<File Id="fil76F96B6C812A297E50E6BD01B4C011FD" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\zh\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirA5F6E8CCFDF225B493B7CE1167F0EBF1" Name="zh-tw">
<Component Id="cmpADCB01377702CFEE9215ABA07C18DBB5" Guid="{86E2D7D9-0EA0-408A-89E3-ED938A0A917C}">
<File Id="fil696FE2B3C66436774101EA3587397848" KeyPath="yes" Source="$(env.DisplayMagicianFilesDir)\zh-tw\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="DisplayMagician">
<ComponentRef Id="cmpBD0A0533F40E0B874A023E467EE15884" />
<ComponentRef Id="cmp1978460F20832AFD58CEFD336AAAA41B" />
<ComponentRef Id="cmpB6DCEBC121FFE67E27945FC59FAF34EB" />
<ComponentRef Id="cmp32E7E4241B870E8E1272B218DAFC18BD" />
<ComponentRef Id="cmp0BFD48C29EF7E91136AE7ECB2562A439" />
<ComponentRef Id="cmpC627D6669C8B7F6118B278B985611D23" />
<ComponentRef Id="cmpCDC1AACC3E4B47262615C1CF34C96FDC" />
<ComponentRef Id="cmpBC67EE8B6ADC74240F4BA176F17FA2E7" />
<ComponentRef Id="cmp85F426B2D7B7BE110260F69908CF89DC" />
<ComponentRef Id="cmp079376624ED9003D040D434FD0AD79FC" />
<ComponentRef Id="cmpE03B764D1598084EA84F72C0DC54A5FE" />
<ComponentRef Id="cmpFA9BAE6E0F706FE8C2FB87226A21172A" />
<ComponentRef Id="cmp03435CB09F2E9F019BAA38AE75428254" />
<ComponentRef Id="cmp2776B662029F8701F5335F0DF08E554F" />
<ComponentRef Id="cmpA038AEB808EE721D74BCE483FE0CF5C4" />
<ComponentRef Id="cmp04AD32E960B2A9FBA1822AE873954545" />
<ComponentRef Id="cmp48136D75F10658FE78119AADF6F1725A" />
<ComponentRef Id="cmpE3BF3E5AF0925FB86E3F382572243621" />
<ComponentRef Id="cmp618EC65A5E4D9E8FEBB887B76DA4FD50" />
<ComponentRef Id="cmp875F9AB6D5D996C61588EFA96C16CB26" />
<ComponentRef Id="cmp1AE47A82DB5E00D1488DE0C214B82747" />
<ComponentRef Id="cmp3C945FD02B7EBC852A737F0B9EA06402" />
<ComponentRef Id="cmp9822C8E3EA9DED31B19647D3BEF403FF" />
<ComponentRef Id="cmpECA87B17F9BBA2AE63349CE09D7514F3" />
<ComponentRef Id="cmpC7A842805FA293C91E6B671E1E4857CB" />
<ComponentRef Id="cmp49B14D6F63FD6F782375E764F888D9F6" />
<ComponentRef Id="cmpE48528C4F5932A4EFD89F7331108F45D" />
<ComponentRef Id="cmp0758E167CC73C057A0ECE2DC5E35F506" />
<ComponentRef Id="cmp24DB16B950576B6883BCB451D9881EBC" />
<ComponentRef Id="cmp46530108D41744F25886A5898DC5A274" />
<ComponentRef Id="cmpE475EAC321A295365F62D280DFFFCFDD" />
<ComponentRef Id="cmp35AEFE57A4E4F326AB35BB1BFAC10ABC" />
<ComponentRef Id="cmpBF2E14544E7404D9716B1E616AFF1821" />
<ComponentRef Id="cmpA97212A22F03B19D8D9FB95C1B706F67" />
<ComponentRef Id="cmp7964C303BA027BE990A3E8327EC91498" />
<ComponentRef Id="cmp5C0F2F2987EC8A4E1ABFC07281B44BC0" />
<ComponentRef Id="cmp6C1CA4699436E48FBC65429D3DDE3729" />
<ComponentRef Id="cmpCA92E5DFCB483577A26FEC321AFD558D" />
<ComponentRef Id="cmp4533A51FA0E8641930679AD37424B8B9" />
<ComponentRef Id="cmpB8E69B802F308C31E92E32AB958DAF68" />
<ComponentRef Id="cmp7806D754FCAB20844210E15AE6C04EBE" />
<ComponentRef Id="cmp040780EB1A6483479A96E102B7E22681" />
<ComponentRef Id="cmpC488B4BB40BA5248FFBD28351333AEE2" />
<ComponentRef Id="cmpB1D2F10332449DEAAAAE97A0E648E9C0" />
<ComponentRef Id="cmpA69B8A712387D3B90D6813098B05C34A" />
<ComponentRef Id="cmpC4DF80F866A83C22E8A0E9C8FC25C9C1" />
<ComponentRef Id="cmp7C71840B04F7F507D8FA41923689CDF2" />
<ComponentRef Id="cmp564BF443013A98EBC72A01B8D461D8B0" />
<ComponentRef Id="cmp2B08E9F49E70994AD433A60E3F7B0BEB" />
<ComponentRef Id="cmp092F57310F36F676B6C8E8397742A26C" />
<ComponentRef Id="cmp624BAAB1945C8547300753CB1BE04D2F" />
<ComponentRef Id="cmpA4C0AEE73CF23CAC1F85DF3325071906" />
<ComponentRef Id="cmp4131995471E81CAF43CA25A941AA1309" />
<ComponentRef Id="cmpD7962077D44195A7BCC3B8DC0B809152" />
<ComponentRef Id="cmp344C9604A259DAB1C241685400F60C59" />
<ComponentRef Id="cmp1D08C460D6987792DC635727E811FC55" />
<ComponentRef Id="cmpFB11AB8C27CB0CC824707BF5FC281DEB" />
<ComponentRef Id="cmpADCB01377702CFEE9215ABA07C18DBB5" />
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>3.10</ProductVersion>
<ProjectGuid>dfd22d4d-f2e4-4ba4-b32a-7a990a35ba08</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>DisplayMagicianSetup</OutputName>
<OutputType>Package</OutputType>
<Name>DisplayMagicianSetup</Name>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug;DisplayMagicianFilesDir=H:\vscode-projects\DisplayMagician\DisplayMagician\bin\Debug</DefineConstants>
<CompilerAdditionalOptions>-arch x64</CompilerAdditionalOptions>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<CompilerAdditionalOptions>-arch x64</CompilerAdditionalOptions>
<DefineConstants>DisplayMagicianFilesDir=H:\vscode-projects\DisplayMagician\DisplayMagician\bin\Debug</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DefineConstants>DisplayMagicianFilesDir=H:\vscode-projects\DisplayMagician\DisplayMagician\bin\Debug;</DefineConstants>
<CompilerAdditionalOptions>-arch x64</CompilerAdditionalOptions>
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
<SuppressAllWarnings>False</SuppressAllWarnings>
<Pedantic>True</Pedantic>
<WixVariables>
</WixVariables>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
<SuppressAllWarnings>False</SuppressAllWarnings>
<Pedantic>True</Pedantic>
<DefineConstants>DisplayMagicianFilesDir=H:\vscode-projects\DisplayMagician\DisplayMagician\bin\Debug</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Include="CustomDialogs\LicenseAgreementDialogOverwritten.wxs" />
<Compile Include="Fragments\DisplayMagicianFilesFragment.wxs" />
<Compile Include="Product.wxs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DisplayMagicianLogReporter\DisplayMagicianLogReporter.csproj">
<Name>DisplayMagicianLogReporter</Name>
<Project>{76df2bcf-911b-4820-b63e-8f3468db5e79}</Project>
<Private>True</Private>
<DoNotHarvest>
</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\DisplayMagicianShared\DisplayMagicianShared.csproj">
<Name>DisplayMagicianShared</Name>
<Project>{1cacda43-01c7-4cd4-bf6e-9421a29510fc}</Project>
<Private>True</Private>
<DoNotHarvest>
</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\DisplayMagicianShellExtension\DisplayMagicianShellExtension.csproj">
<Name>DisplayMagicianShellExtension</Name>
<Project>{55d4ff65-edc7-48ef-933e-b6e7f3809b68}</Project>
<Private>True</Private>
<DoNotHarvest>
</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\DisplayMagician\DisplayMagician.csproj">
<Name>DisplayMagician</Name>
<Project>{608d941a-b431-400c-a91d-c6f971c29577}</Project>
<Private>True</Private>
<DoNotHarvest>
</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Includes" />
<Folder Include="Fragments" />
<Folder Include="CustomActions" />
<Folder Include="CustomDialogs" />
<Folder Include="Lang" />
<Folder Include="Lang\en-us" />
<Folder Include="Resources" />
</ItemGroup>
<ItemGroup>
<Content Include="Includes\DisplayMagicianVariables.wxi" />
<Content Include="Lang\en-us\EULA_en-us.rtf" />
<Content Include="Resources\DisplayMagician.ico" />
<Content Include="Resources\WixUIBannerBmp.png" />
<Content Include="Resources\WixUIDialogBmp.png" />
<Content Include="Resources\WixUIDialogBmpDarker.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Lang\en-us\Loc_en-us.wxl" />
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixUtilExtension">
<HintPath>C:\Program Files (x86)\WiX Toolset v3.14\bin\WixUtilExtension.dll</HintPath>
<Name>WixUtilExtension</Name>
</WixExtension>
<WixExtension Include="WixUIExtension">
<HintPath>C:\Program Files (x86)\WiX Toolset v3.14\bin\WixUIExtension.dll</HintPath>
<Name>WixUIExtension</Name>
</WixExtension>
<WixExtension Include="WixNetFxExtension">
<HintPath>C:\Program Files (x86)\WiX Toolset v3.14\bin\WixNetFxExtension.dll</HintPath>
<Name>WixNetFxExtension</Name>
</WixExtension>
</ItemGroup>
<Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
<Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
</Target>
<PropertyGroup>
<PreBuildEvent>"$(WIX)bin\heat.exe" dir H:\vscode-projects\DisplayMagician\DisplayMagician\bin\Debug -cg DisplayMagicianFiles -gg -scom -sreg -sfrag -srd -dr APPLICATIONROOTDIRECTORY -var var.DisplayMagicianFilesDir -out "$(ProjectDir)Fragments\DisplayMagicianFilesFragment.wxs"</PreBuildEvent>
</PropertyGroup>
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Wix.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,255 @@
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="APPLICATIONROOTDIRECTORY">
<Component Id="cmp53B07BB21F5AFE76F5469BD1F4BA65C9" Guid="{45338E58-9B9B-4F25-9EAC-5E15FED0578A}">
<File Id="fil8CC3C83921B00F72D50A1E4EEB792DFE" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\AudioSwitcher.AudioApi.CoreAudio.dll" />
</Component>
<Component Id="cmp8243CB1E312705B4BA74BC791635270C" Guid="{92A3238C-FC29-4DDE-AAEB-ED43152C74D1}">
<File Id="filC0B7F66C67664353137460031E28BC1B" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\AudioSwitcher.AudioApi.dll" />
</Component>
<Component Id="cmp493DD683A43D05F764F3DEEF08ECA4C6" Guid="{7D44687B-760E-44F7-BC7F-06D924B02556}">
<File Id="filC8194EB99DFB64B8589F5D80DC8E3B4D" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\AutoUpdater.NET.dll" />
</Component>
<Component Id="cmp357CADF4E916AADB1DD6BD7938986798" Guid="{20377E64-25F8-40B8-A722-8120A5E87AE8}">
<File Id="fil900464E773972F43219693B12A52EDE2" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\AutoUpdater.NET.pdb" />
</Component>
<Component Id="cmp78B9C7C9D51B2878B72DCBACE49DE398" Guid="{DC021925-6497-4B5A-A606-E1E4DD42C298}">
<File Id="filDE7F24A649EB60701DC0EC41FE83CBBE" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\CircularProgressBar.dll" />
</Component>
<Component Id="cmp7EE113DB90D07F08FCE70C1861DEA947" Guid="{2003F312-E070-4896-972B-3EA4BF026F15}">
<File Id="filF7D383DE2E27A23D8552666CEA0DDC80" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\DisplayMagician.exe" />
</Component>
<Component Id="cmpCF520827D65E51E3ECB59344A6F528D0" Guid="{CD54C8B4-B3BC-4419-A61F-74089D50FC8E}">
<File Id="fil2841FB135B81D3B7EF6634B1E3E562DA" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\DisplayMagician.exe.config" />
</Component>
<Component Id="cmp20CF355FCD243C61CF66FB91F20BEA24" Guid="{9BED7655-D894-48CD-BD86-25192BBD98DA}">
<File Id="fil00FEE1F8F6F3766FD0431A9B72F4FCC7" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\DisplayMagician.pdb" />
</Component>
<Component Id="cmp936B3459EEFF10D8EB978B7DD0F9FDDA" Guid="{6D4DDEB7-B506-4B8E-A0FE-0E109590B230}">
<File Id="fil44F64B4F8FBBEAA84A71077F7F3B6B4D" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\DisplayMagician.Shared.dll" />
</Component>
<Component Id="cmpEFA0EED8369E2F430E0ED6D9EB027553" Guid="{6069188C-D39C-484D-8029-A0DD34A8004F}">
<File Id="fil52BE9F94EBFDF8C5CFEC426A17966F40" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\DisplayMagician.Shared.pdb" />
</Component>
<Component Id="cmpE8833A8E220525D7707A018B20CEDD87" Guid="{36EE3CAB-A7B9-47A0-8736-2D834F0EAE41}">
<File Id="filD4FD53D2FBF78674DBC3A1B446B44FC5" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\EDIDParser.dll" />
</Component>
<Component Id="cmp8C52E948AAB2D43DF696BB7D003A8E4B" Guid="{B46914FD-28D6-4193-9039-FB565B26502F}">
<File Id="fil1965347683EC48A269FE672473CD04C2" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\HtmlAgilityPack.dll" />
</Component>
<Component Id="cmp137F8F514DF6364F5BBFCBDB1B1B9807" Guid="{93132EFA-014D-46F1-8793-2F38D0644E8B}">
<File Id="filA79B24FCE8AA4DA0DC9A3ACBE5D830DD" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\HtmlAgilityPack.pdb" />
</Component>
<Component Id="cmpC13B4DB64E30D03117ECF099B1A9CD9C" Guid="{3AF5562D-49A0-495E-83E5-18C983C0852C}">
<File Id="fil44FFB513E29A8346713440B4BCB7F1E6" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\IconExtractor.dll" />
</Component>
<Component Id="cmp6AB92D1CF70395670A490E1B9BD347DE" Guid="{D3040106-D35D-4B1B-904E-F5BF11B708A2}">
<File Id="fil4DD582D50D7AC9DDD5292A76257854FA" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\IconLib.dll" />
</Component>
<Component Id="cmp23C6CFB3962E9B4E2A7E8EF56F20A99F" Guid="{066BD4D9-583C-4C18-97D5-29FFF34535AD}">
<File Id="fil0F18A66FBBBB6C44A052B9FB77ACD8F8" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\IconPicker.dll" />
</Component>
<Component Id="cmp5069692C1912B298A026EA30A39A2F36" Guid="{048CBBEC-8920-4DB2-AD05-BC4C7AC041E6}">
<File Id="fil15BCAD6A05EB985A23A6B9DE3EFEB933" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\ImageListView.dll" />
</Component>
<Component Id="cmp6B91543EC1EAFC09F3C7747C1333F99A" Guid="{7B954702-3E31-4A52-AC10-385D526F47AC}">
<File Id="fil34AC49C1FA6CC0335FB4F16BCD03AA7B" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\McMaster.Extensions.CommandLineUtils.dll" />
</Component>
<Component Id="cmp8A11CDCDF04C29EC9CA9A0C1D0D78B04" Guid="{F3B33283-72AE-4770-B315-6C3EA51BD1C5}">
<File Id="fil151DD1163831E94E80724A88F88C2231" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\Microsoft.Toolkit.Uwp.Notifications.dll" />
</Component>
<Component Id="cmp62D956D9975F1430FEAB37FCAD94474F" Guid="{31FD7423-1B64-4486-9954-D7C8894435D8}">
<File Id="fil4F519990E7E5387E7BAEB5C056617826" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\Microsoft.Toolkit.Uwp.Notifications.pdb" />
</Component>
<Component Id="cmpA6AEEDB3EBF416E3AD000E7408FE3402" Guid="{3C511BBD-5848-43AD-9D78-74CBF39FF17C}">
<File Id="filA93EB7C7565EEDD39AF3362752AE09DB" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\MintPlayer.IconUtils.dll" />
</Component>
<Component Id="cmpA7927FF61A499CF81EE0A562CDFEDEC7" Guid="{99E54CE3-D85F-40EB-A59F-8F3CDEA20D9E}">
<File Id="filD7DC5F43B3964ACECD7725F05E664960" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\Newtonsoft.Json.dll" />
</Component>
<Component Id="cmpC64ECA245317593760E42F3996F3A079" Guid="{17288878-B3C7-4D5A-940A-977CBFEA5A5D}">
<File Id="fil5299F0448E950048C778AA65A04FB498" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\NLog.dll" />
</Component>
<Component Id="cmp5CFF8A0C9C138424DA47E04F4B0986EB" Guid="{CA90292D-0E82-47C6-A566-C960185AF4C5}">
<File Id="filDB484734B403A8C8EE2F5B5165068C91" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\NvAPIWrapper.dll" />
</Component>
<Component Id="cmpBEC07D0236076B07E4E7D7632CCA69CB" Guid="{ABF648F1-17BF-4959-9A47-CEB77BA148D5}">
<File Id="fil8C59ED1965E9E2D1C82459BE5C1E903E" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\QueryString.NETCore.dll" />
</Component>
<Component Id="cmpAE5FC77E7BB7E9CB720EF7CEE118A4CE" Guid="{35DFC824-B1A1-491B-862D-8D3A344CAC6F}">
<File Id="filD448167ABB54E447850BA2A203C5FCA1" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\QueryString.NETCore.pdb" />
</Component>
<Component Id="cmpB76F273FDED5EA841158E966B403CFC8" Guid="{D1E02032-96EA-4862-AB4A-1A7CB1F436EA}">
<File Id="fil8A5957F9C3DCF1A6D414F9F34402CB53" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\System.Drawing.Common.dll" />
</Component>
<Component Id="cmp7DD29D6442A6E450B2316729EA2C0F1D" Guid="{9913EAB7-3C02-4605-BBD9-D9A892E46E6E}">
<File Id="fil9DF3290031BCB652454E62345D1FAE6B" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\System.ValueTuple.dll" />
</Component>
<Component Id="cmpA8825A49786C04320E75BCFC8E961667" Guid="{A78A3D6D-F120-4E25-BCD3-847C2CC9326C}">
<File Id="filD5FED76D92088BA98BD9CF7D4D9B7EF2" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\ValveKeyValue.dll" />
</Component>
<Component Id="cmp650327FC006E09EDFC7039D6E7A6F340" Guid="{DC847339-CD4E-4AFC-ABE1-89E1B1AB5201}">
<File Id="filB58835925907FAE2AB432C29CD8C03B4" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\WindowsDisplayAPI.dll" />
</Component>
<Component Id="cmp27AC6F10258FA1C97C54F3C1D153D122" Guid="{AB96F714-C01D-48B1-B6C1-676CB28D5124}">
<File Id="fil01CF08752F4284E3144706F10481AEA0" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\WinFormAnimation.dll" />
</Component>
<Directory Id="dirC9CEBA44737D7806DC2F52AE07FB1335" Name="ar">
<Component Id="cmp1D8A437520B8A88B5329BA85AF49F972" Guid="{7A185A4D-2E84-45B2-BCF2-43B78DF80672}">
<File Id="filC934041A1382ABA35ECB5DE3BB6C4148" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\ar\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir1764AC367AADA7667CA18D19856EB829" Name="cs">
<Component Id="cmp1B983AD82D33902E3869C2CD3E625557" Guid="{1D07E0AB-399A-4966-86C5-B5BF9AF70585}">
<File Id="fil5CE1877B3764F3FA8C53E465EC4F1E6B" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\cs\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir70240FB68A7D32052E3646DFEC7177A6" Name="da">
<Component Id="cmp645D07231E6F1B4B9F84AAED05DE08B9" Guid="{BC427D42-E11A-4C8A-843F-3EA7D82416C9}">
<File Id="fil6664ED7C2E9121315323240F4A94F71F" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\da\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir1C628EE15A29CD6ED08798D6B0A06B2F" Name="de">
<Component Id="cmpF7E34D6BF19681066F5E973C8D30C63A" Guid="{67F5B2F4-F0D6-40EC-B1FD-E3A8826A5EAD}">
<File Id="filC2D506AF5C5B86FA443A326E067EF823" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\de\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir6B7DF5E7779A02DE589C2D4AABF889BA" Name="es">
<Component Id="cmpB54DE98A33D508FC6EF7E3761CDF0661" Guid="{A7230A09-17D1-4538-A5DB-7EB4690FDC33}">
<File Id="filCDFD6865877E32514969EAE54D3CC9F9" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\es\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirCCE997692B032DBDA6174416BFED255E" Name="fr">
<Component Id="cmp81105D91EF7C9FAB44E52202DBAF417C" Guid="{4D53E23F-4282-48DC-AC10-DF3D5C3146A7}">
<File Id="fil6B84F6EC6C9F50B7139B0E99914B401A" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\fr\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirC0620602576770B728F6D7CF835E4230" Name="it">
<Component Id="cmpCC505044A437DF227E44E7B31A54D0BF" Guid="{74458EBA-75AE-44C0-8FC5-E57178966E5E}">
<File Id="filD812096039F1E9D729065E7109AB857F" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\it\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir299EDA906CCCF90FED2B1DE9A0AE661D" Name="ja-JP">
<Component Id="cmp2B1808EAFED02DC5D42D475F2BB83458" Guid="{092E2C7C-D849-483E-BC68-FDD7CF84B84F}">
<File Id="filA3B2CB69DE697F856902A5EB591C1BA9" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\ja-JP\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir5F675FF0062E1C1CACE0170EC20A5208" Name="ko">
<Component Id="cmpE8B7CCFB66BD36E9CF741814FEE6AD14" Guid="{4EF7F400-C217-43C5-8C3D-1E931C1CB79A}">
<File Id="fil1A20D0790F057F2E9E188792193A32BD" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\ko\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir0BFBA37D9F94C8F490A10DA87815DED5" Name="nl">
<Component Id="cmp9449E2C32768367A145DF20983A12FF7" Guid="{34611ADD-681A-4F0D-A64A-1F5800387316}">
<File Id="filE87E30BFF942128946D7656D111B9E28" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\nl\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir5D30DDBDF1F855D2C3CFCAE5A7D4DFB7" Name="pl">
<Component Id="cmp34EDF353BCC5E92A39657F713CAF1AA0" Guid="{CDB834D9-1C90-49B5-9B1B-CA9675B6D765}">
<File Id="filB0BCC1B40E0F3F37F614E9AC51A1BEDF" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\pl\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir32D9AD0C9188498053C05E4C1D09269D" Name="pt">
<Component Id="cmp1E67A3938BF74EC5ADD54FAB69A80CB3" Guid="{09A155ED-F43A-44F8-8C2C-CF32E09B71DD}">
<File Id="filB6A7729764F42969B1A0A1093D3F600D" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\pt\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir3EA1054A4A68F70CEF22E983B9D684DB" Name="pt-BR">
<Component Id="cmpEEAAA81C74F88DC87008EB031C2F1030" Guid="{7E7A9B89-C529-4F69-832C-F98DCA61B61E}">
<File Id="filBDE4FF11B65DE8486E6AE2917075C4F2" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\pt-BR\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirF9A13AB290C9570B2C0CE7CB6EF9D86E" Name="ru">
<Component Id="cmpA923B5BC9CB54BE671D485B3A39D93A5" Guid="{E125BA7D-5078-421F-A16C-87115BC67E15}">
<File Id="fil0672B3CFA1451A14C32747BE1794732F" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\ru\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dir0A61397BAE3772A68E21EF1C51156F2C" Name="sk">
<Component Id="cmp8D4C4B444510137E2D82B4FD6A0B9776" Guid="{593DE901-0B6F-4934-A535-F8EC555C725C}">
<File Id="filC5765B8E01B5B47AAF9794806A76E690" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\sk\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirBBD306FA33D57073FD02CF4EFC3A0326" Name="sv">
<Component Id="cmpFB55A1004D6DF4923A748FDC2F523D8B" Guid="{052C836A-6FC5-4BA9-9027-9A43B10FA30B}">
<File Id="fil54738B12543ED9C06F79D373D2EB015B" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\sv\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirCE3BF130A177608F70523C718370D4AB" Name="th">
<Component Id="cmp4490FE644B0447492BBB39E2832B87C0" Guid="{EA5F9919-3AEF-402E-ABF7-05F594988A12}">
<File Id="fil4735CFBE1739CDA690669E71EA774734" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\th\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirC06FC06848A827DE7E1246A3EEE173B9" Name="tr">
<Component Id="cmp7311ACB3A3BB0005E1BD421A03BAC70D" Guid="{3CAE5EA9-2196-479B-8CE0-3C6E66E3387F}">
<File Id="fil9EDE895C94E3E737A7E2345A3354E4ED" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\tr\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirA9E5CFBEBA3415CA12E141D142550091" Name="zh">
<Component Id="cmp0E8893641CCC97E160269D736795633C" Guid="{049E5177-B898-4C0E-91B9-7F5A50A1E708}">
<File Id="filD14D5D68900793C75702C773F11A305F" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\zh\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
<Directory Id="dirB915F738D24EC7F5CE340DC7A43B9BD1" Name="zh-tw">
<Component Id="cmp1D85EF433AB8DDB383D91C1C33BAA91A" Guid="{56499EEC-57A1-436F-9712-870231A19C02}">
<File Id="fil03FB6CBB0D2712EFAD51B20D66FE4B9B" KeyPath="yes" Source="$(var.DisplayMagicianFilesDir)\zh-tw\AutoUpdater.NET.resources.dll" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="DisplayMagicianFiles">
<ComponentRef Id="cmp53B07BB21F5AFE76F5469BD1F4BA65C9" />
<ComponentRef Id="cmp8243CB1E312705B4BA74BC791635270C" />
<ComponentRef Id="cmp493DD683A43D05F764F3DEEF08ECA4C6" />
<ComponentRef Id="cmp357CADF4E916AADB1DD6BD7938986798" />
<ComponentRef Id="cmp78B9C7C9D51B2878B72DCBACE49DE398" />
<ComponentRef Id="cmp7EE113DB90D07F08FCE70C1861DEA947" />
<ComponentRef Id="cmpCF520827D65E51E3ECB59344A6F528D0" />
<ComponentRef Id="cmp20CF355FCD243C61CF66FB91F20BEA24" />
<ComponentRef Id="cmp936B3459EEFF10D8EB978B7DD0F9FDDA" />
<ComponentRef Id="cmpEFA0EED8369E2F430E0ED6D9EB027553" />
<ComponentRef Id="cmpE8833A8E220525D7707A018B20CEDD87" />
<ComponentRef Id="cmp8C52E948AAB2D43DF696BB7D003A8E4B" />
<ComponentRef Id="cmp137F8F514DF6364F5BBFCBDB1B1B9807" />
<ComponentRef Id="cmpC13B4DB64E30D03117ECF099B1A9CD9C" />
<ComponentRef Id="cmp6AB92D1CF70395670A490E1B9BD347DE" />
<ComponentRef Id="cmp23C6CFB3962E9B4E2A7E8EF56F20A99F" />
<ComponentRef Id="cmp5069692C1912B298A026EA30A39A2F36" />
<ComponentRef Id="cmp6B91543EC1EAFC09F3C7747C1333F99A" />
<ComponentRef Id="cmp8A11CDCDF04C29EC9CA9A0C1D0D78B04" />
<ComponentRef Id="cmp62D956D9975F1430FEAB37FCAD94474F" />
<ComponentRef Id="cmpA6AEEDB3EBF416E3AD000E7408FE3402" />
<ComponentRef Id="cmpA7927FF61A499CF81EE0A562CDFEDEC7" />
<ComponentRef Id="cmpC64ECA245317593760E42F3996F3A079" />
<ComponentRef Id="cmp5CFF8A0C9C138424DA47E04F4B0986EB" />
<ComponentRef Id="cmpBEC07D0236076B07E4E7D7632CCA69CB" />
<ComponentRef Id="cmpAE5FC77E7BB7E9CB720EF7CEE118A4CE" />
<ComponentRef Id="cmpB76F273FDED5EA841158E966B403CFC8" />
<ComponentRef Id="cmp7DD29D6442A6E450B2316729EA2C0F1D" />
<ComponentRef Id="cmpA8825A49786C04320E75BCFC8E961667" />
<ComponentRef Id="cmp650327FC006E09EDFC7039D6E7A6F340" />
<ComponentRef Id="cmp27AC6F10258FA1C97C54F3C1D153D122" />
<ComponentRef Id="cmp1D8A437520B8A88B5329BA85AF49F972" />
<ComponentRef Id="cmp1B983AD82D33902E3869C2CD3E625557" />
<ComponentRef Id="cmp645D07231E6F1B4B9F84AAED05DE08B9" />
<ComponentRef Id="cmpF7E34D6BF19681066F5E973C8D30C63A" />
<ComponentRef Id="cmpB54DE98A33D508FC6EF7E3761CDF0661" />
<ComponentRef Id="cmp81105D91EF7C9FAB44E52202DBAF417C" />
<ComponentRef Id="cmpCC505044A437DF227E44E7B31A54D0BF" />
<ComponentRef Id="cmp2B1808EAFED02DC5D42D475F2BB83458" />
<ComponentRef Id="cmpE8B7CCFB66BD36E9CF741814FEE6AD14" />
<ComponentRef Id="cmp9449E2C32768367A145DF20983A12FF7" />
<ComponentRef Id="cmp34EDF353BCC5E92A39657F713CAF1AA0" />
<ComponentRef Id="cmp1E67A3938BF74EC5ADD54FAB69A80CB3" />
<ComponentRef Id="cmpEEAAA81C74F88DC87008EB031C2F1030" />
<ComponentRef Id="cmpA923B5BC9CB54BE671D485B3A39D93A5" />
<ComponentRef Id="cmp8D4C4B444510137E2D82B4FD6A0B9776" />
<ComponentRef Id="cmpFB55A1004D6DF4923A748FDC2F523D8B" />
<ComponentRef Id="cmp4490FE644B0447492BBB39E2832B87C0" />
<ComponentRef Id="cmp7311ACB3A3BB0005E1BD421A03BAC70D" />
<ComponentRef Id="cmp0E8893641CCC97E160269D736795633C" />
<ComponentRef Id="cmp1D85EF433AB8DDB383D91C1C33BAA91A" />
</ComponentGroup>
</Fragment>
</Wix>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Include>
<!--
Versioning. These have to be changed for upgrades.
It's not enough to just include newer files.
-->
<?define MajorVersion="0" ?>
<?define MinorVersion="2" ?>
<?define BuildVersion="0" ?>
<!-- Revision is NOT used by WiX in the upgrade procedure -->
<!-- Full version number to display -->
<?define VersionNumber="$(var.MajorVersion).$(var.MinorVersion).$(var.BuildVersion)" ?>
<!--
Upgrade code HAS to be the same for all updates.
Once you've chosen it don't change it.
-->
<?define UpgradeCode="33E22B4C-982F-4B02-A3DE-085693742DB5" ?>
<!--
Path to the resources directory. resources don't really need to be included
in the project structure but I like to include them for for clarity
-->
<?define ResourcesDir="$(var.ProjectDir)Resources" ?>
<!--
The name of your application exe file. This will be used to kill the process when updating
and creating the desktop shortcut
-->
<?define ExeProcessName="DisplayMagician" ?>
</Include>

Binary file not shown.

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="LANG">1033</String>
<String Id="ProductName">DisplayMagician</String>
<String Id="ProductDescription">DisplayMagician will automatically run your games with a different display profile or audio settings and then will revert everything back to the way it was when you've finished playing.</String>
<String Id="LicenseRtf" Overridable="yes">\Lang\en-us\EULA_en-us.rtf</String>
<String Id="ManufacturerName">LittleBitBig</String>
<String Id="LogReporterName">LogReporter</String>
<String Id="LogReporterDescription">LogReporter will collect details about your computer to help us troubleshoot errors running DisplayMagician.</String>
<String Id="AppNotSupported">This application is is not supported on your current OS. Your OS must be Windows 8.1 or later (64-bit only).</String>
<String Id="DotNetFrameworkNeeded">.NET Framework 4.8 or higher is required for DisplayMagician to work. Please install the latest .NET Framework then run this installer again. You can download the latest .NET Framework from https://dotnet.microsoft.com/download/dotnet-framework.</String>
<String Id="MustCloseDisplayMagician">You must close !(loc.ProductName) in order to upgrade it!</String>
<String Id="DowngradeErrorMessage">You cannot downgrade !(loc.ProductName) to a lower version using this installer. Please uninstall the older version of !(loc.ProductName) first!</String>
<String Id="DisplayMagicianNewerVersionInstalled">A newer version of !(loc.ProductName) is already installed.</String>
<String Id="WelcomeDlgTitle">{\White_Title}Welcome to the [ProductName] [ProductVersion] Setup Wizard</String>
<String Id="WelcomeDlgDescription">{\White_Normal}DisplayMagician will automatically run your games with a different display profile or audio settings and then will revert everything back to the way it was when you've finished playing. If you want to install DisplayMagician then click Next to continue or Cancel to exit.</String>
<String Id="LicenseAgreementDlgTitle">{\White_Title}End User License Agreement</String>
<String Id="LicenseAgreementDlgDescription">{\White_Normal}Please read and accept this License Agreement</String>
<String Id="ExitDialogTitle">{\White_Title}Completed the [ProductName] Setup Wizard</String>
<String Id="ExitDialogDescription">{\White_Normal}Click the Finish button to exit the Setup Wizard.</String>
<String Id="FatalErrorTitle">{\White_Title}[ProductName] Setup Wizard ended prematurely</String>
<String Id="FatalErrorDescription1">{\White_Normal}[ProductName] Setup Wizard ended prematurely because of an error. Your system has not been modified. To install this program at a later time, run Setup Wizard again.</String>
<String Id="UserExitTitle">{\White_Title}[ProductName] Setup Wizard was interrupted</String>
<String Id="UserExitDescription1">{\White_Normal}[ProductName] setup was interrupted. Your system has not been modified. To install this program at a later time, please run the installation again.</String>
<String Id="DiskCostDlgTitle">{\White_Title}Disk Space Requirements</String>
<String Id="DiskCostDlgDescription">{\White_Normal}The disk space required for the installation of the selected features.</String>
<String Id="BrowseDlgTitle">{\White_Title}Change destination folder</String>
<String Id="BrowseDlgDescription">{\White_Normal}Browse to the destination folder</String>
<String Id="FilesInUseTitle">{\White_Title}Files in Use</String>
<String Id="FilesInUseDescription">{\White_Normal}Some files that need to be updated are currently in use.</String>
<String Id="InstallDirDlgTitle">{\White_Title}Destination Folder</String>
<String Id="InstallDirDlgDescription">{\White_Normal}Click Next to install to the default folder or click Change to choose another.</String>
<String Id="VerifyReadyDlgInstallTitle">{\White_Title}Ready to install [ProductName]</String>
<String Id="VerifyReadyDlgChangeTitle">{\White_Title}Ready to change [ProductName]</String>
<String Id="VerifyReadyDlgRepairTitle">{\White_Title}Ready to repair [ProductName]</String>
<String Id="VerifyReadyDlgRemoveTitle">{\White_Title}Ready to remove [ProductName]</String>
<String Id="VerifyReadyDlgUpdateTitle">{\White_Title}Ready to update [ProductName]</String>
<String Id="MaintenanceWelcomeDlgTitle">{\White_Title}Welcome to the [ProductName] Setup Wizard</String>
<String Id="MaintenanceWelcomeDlgDescription">{\White_Normal}The Setup Wizard allows you to change the way [ProductName] features are installed on your computer or to remove it from your computer. Click Next to continue or Cancel to exit the Setup Wizard.</String>
<String Id="MaintenanceTypeDlgTitle">{\White_Title}Change, repair, or remove installation</String>
<String Id="MaintenanceTypeDlgDescription">{\White_Normal}Select the operation you wish to perform.</String>
</WixLocalization>

View File

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Code from https://weblogs.sqlteam.com/mladenp/2010/02/11/wix-3-tutorial-solutionproject-structure-and-dev-resources/ -->
<!-- Add xmlns:util namespace definition to be able to use stuff from WixUtilExtension dll-->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<!-- This is how we include wxi files -->
<?include $(sys.CURRENTDIR)Includes\DisplayMagicianVariables.wxi ?>
<!--
Id="*" is to enable upgrading. * means that the product ID will be autogenerated on each build.
Name is made of localized product name and version number.
-->
<Product Id="6F8E03A4-4BB7-4BAF-B19D-F761BAFDC186" Name="!(loc.ProductName)" Language="!(loc.LANG)" Version="$(var.VersionNumber)" Manufacturer="!(loc.ManufacturerName)" UpgradeCode="$(var.UpgradeCode)">
<!-- Define the minimum supported installer version (3.0) and that the install should be done for the whole machine not just the current user -->
<Package InstallerVersion="314" Compressed="yes" InstallPrivileges="elevated" InstallScope="perMachine" Platform="x64"/>
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<!-- Upgrade settings. This will be explained in more detail in a future post -->
<!-- <Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion OnlyDetect="yes" Minimum="$(var.VersionNumber)" IncludeMinimum="no" Property="NEWER_VERSION_FOUND" />
<UpgradeVersion Minimum="0.0.0.0" IncludeMinimum="yes" Maximum="$(var.VersionNumber)" IncludeMaximum="no" Property="OLDER_VERSION_FOUND" />
</Upgrade> -->
<MajorUpgrade AllowDowngrades="no" AllowSameVersionUpgrades="no" DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" />
<!-- Reference the global WIXNETFX4RELEASEINSTALLED property so that will automatically pull in the .Net 4.8 variables (WiX 3.14 and higher only supported) -->
<!--<PropertyRef Id="WIX_IS_NETFRAMEWORK_48_OR_LATER_INSTALLED"/>
<Condition Message="!(loc.DotNetFrameworkNeeded)">
<![CDATA[Installed OR WIX_IS_NETFRAMEWORK_48_OR_LATER_INSTALLED]]>
</Condition>-->
<!-- Load the -->
<PropertyRef Id="WIXNETFX4RELEASEINSTALLED"/>
<Condition Message="!(loc.DotNetFrameworkNeeded)">
<![CDATA[Installed OR (WIXNETFX4RELEASEINSTALLED >= "#528040")]]>
</Condition>
<!--
Startup conditions that checks if .Net Framework 4.8 is installed or if
we're running Windows 8.1 or higher as the OS.
If not the installation is aborted.
By doing the (Installed OR ...) property means that this condition will only
be evaluated if the app is being installed and not on uninstall or changing
-->
<Condition Message="!(loc.AppNotSupported)">
<![CDATA[Installed OR (VersionNT64 >= 603)]]>
</Condition>
<!-- This will ask the user to close the DisplayMagician app if it's running while upgrading -->
<util:CloseApplication Id="CloseDisplayMagician" CloseMessage="no" Description="!(loc.MustCloseDisplayMagician)"
ElevatedCloseMessage="no" RebootPrompt="no" Target="$(var.ExeProcessName)" />
<!-- Use the built in WixUI_InstallDir GUI -->
<UIRef Id="WixUI_InstallDir" />
<UI>
<!-- Add in some text styles to make the text white -->
<TextStyle Id="White_Normal" FaceName="Tahoma" Size="8" Red="255" Green="255" Blue="255" />
<TextStyle Id="White_Bigger" FaceName="Tahoma" Size="12" Red="255" Green="255" Blue="255" />
<TextStyle Id="White_Title" FaceName="Tahoma" Size="9" Bold="yes" Red="255" Green="255" Blue="255" />
<!-- These dialog references are needed for CloseApplication above to work correctly -->
<DialogRef Id="FilesInUse" />
<DialogRef Id="MsiRMFilesInUse" />
<!-- Here we'll add the GUI logic for installation and updating in a future post-->
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDialogOverwritten">1</Publish>
<Publish Dialog="LicenseAgreementDialogOverwritten" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
<Publish Dialog="LicenseAgreementDialogOverwritten" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAcceptedOverwritten = "1" AND NOT OLDER_VERSION_FOUND</Publish>
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDialogOverwritten">1</Publish>
<!--<Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>-->
</UI>
<!-- Set the icon to show next to the program name in Add/Remove programs -->
<Icon Id="DisplayMagicianIcon.ico" SourceFile="$(var.ResourcesDir)\DisplayMagician.ico" />
<Property Id="ARPPRODUCTICON" Value="DisplayMagicianIcon.ico" />
<!-- Installer UI custom pictures. File names are made up. Add path to your pics -->
<WixVariable Id="WixUIBannerBmp" Value="Resources\WixUIBannerBmpDark.png" />
<WixVariable Id="WixUIDialogBmp" Value="Resources\WixUIDialogBmp.png" />
<!-- the default directory structure -->
<Directory Id="TARGETDIR" Name="SourceDir">
<!-- Create a 64-bit Programs Folder for the Application-->
<Directory Id="ProgramFiles64Folder">
<Directory Id="APPLICATIONROOTDIRECTORY" Name="!(loc.ProductName)" />
</Directory>
<!-- Create a Start Menu Folder for the Application-->
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="!(loc.ProductName)"/>
</Directory>
<Component Id="HKLMRegistryEntries" Guid="4AB42CB7-3E2A-465B-9BE2-DDDE7D34797B">
<RegistryValue Root="HKLM" Key="Software\DisplayMagician" Type="string" Name="InstallDir" Value="[APPLICATIONROOTDIRECTORY]" KeyPath="yes"/>
</Component>
<Component Id="HKCURegistryEntries" Guid="481CA633-0BC0-49CD-B673-51BE9560B00F">
<RegistryValue Root="HKCU" Key="Software\DisplayMagician" Type="string" Name="AppDataDir" Value="[LocalAppDataFolder]" KeyPath="yes"/>
</Component>
</Directory>
<!-- Now we create an Application shortcut -->
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="6C7BFB9E-8549-4E34-BE44-E1A718146755" >
<Shortcut Id="ApplicationStartMenuShortcut"
Name="!(loc.ProductName)"
Description="!(loc.ProductDescription)"
Target="[APPLICATIONROOTDIRECTORY]$(var.DisplayMagician.TargetFileName)"
WorkingDirectory="APPLICATIONROOTDIRECTORY"
Icon="DisplayMagicianIcon.ico">
<!--AUMID-->
<ShortcutProperty Key="System.AppUserModel.ID" Value="LittleBitBig.DisplayMagician"/>
<!--COM CLSID-->
<ShortcutProperty Key="System.AppUserModel.ToastActivatorCLSID" Value="{56F14154-6339-4B94-8B82-80F78D5BCEAF}"/>
</Shortcut>
<RemoveFolder Id="CleanUpApplicationShortCut" Directory="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\DisplayMagician" Name="DisplayMagicianInstalled" Type="integer" Value="1" KeyPath="yes"/>
</Component>
<Component Id="LogReporterShortcut" Guid="1C24F22F-8796-4CF0-9E84-7D06B6662239">
<Shortcut Id="LogReporterStartMenuShortcut"
Name="!(loc.LogReporterName)"
Description="!(loc.LogReporterDescription)"
Target="[APPLICATIONROOTDIRECTORY]$(var.DisplayMagicianLogReporter.TargetFileName)"
WorkingDirectory="APPLICATIONROOTDIRECTORY"
Icon="DisplayMagicianIcon.ico" />
<RemoveFolder Id="CleanUpLogReporterShortCut" Directory="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\DisplayMagician" Name="LogReporterInstalled" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</DirectoryRef>
<!-- Set the default install location to the value of APPLICATIONROOTDIRECTORY (usually c:\Program Files\YourProductName) -->
<Property Id="WIXUI_INSTALLDIR" Value="APPLICATIONROOTDIRECTORY" />
<!-- Set the last page to show a Launch DisplayMagician checkbox -->
<!--<Property Id="WixShellExecTarget" Value="[APPLICATIONROOTDIRECTORY]$(var.DisplayMagician.TargetFileName)" />
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch !(loc.ProductName)" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />-->
<!-- Preapre custom actions to register and unregisterthe ShellExtension DLL -->
<CustomAction Id="InstallShell" FileKey="ServerRegistrationManager.exe" ExeCommand='install "[APPLICATIONROOTDIRECTORY]\DisplayMagicianShellExtension.dll" -codebase' Execute="deferred" Return="check" Impersonate="no" />
<CustomAction Id="UninstallShell" FileKey="ServerRegistrationManager.exe" ExeCommand='uninstall "[APPLICATIONROOTDIRECTORY]\DisplayMagicianShellExtension.dll"' Execute="deferred" Return="check" Impersonate="no" />
<!-- Plumb the registering and unregistering of the ShellExtension DLL into the instllation sequence -->
<InstallExecuteSequence>
<Custom Action="InstallShell" After="InstallFiles">NOT Installed</Custom>
<Custom Action="UninstallShell" Before="RemoveFiles">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
</InstallExecuteSequence>
<!-- Set the components defined in our fragment files that will be used for our feature -->
<Feature Id="DisplayMagicianFeature" Title="!(loc.ProductName)" Level="1">
<ComponentGroupRef Id="DisplayMagicianFiles" />
<ComponentRef Id="ApplicationShortcut" />
<ComponentRef Id="LogReporterShortcut" />
<ComponentRef Id="HKLMRegistryEntries" />
<ComponentRef Id="HKCURegistryEntries" />
<!-- Add in the 3 ShellExtension files we need to make the COM registration work -->
<Component Guid="*" Directory="APPLICATIONROOTDIRECTORY">
<File Id="DisplayMagicianShellExtension.dll" KeyPath="yes" Source="$(var.DisplayMagicianShellExtension.TargetDir)\DisplayMagicianShellExtension.dll" />
</Component>
<Component Guid="*" Directory="APPLICATIONROOTDIRECTORY">
<File Id="ServerRegistrationManager.exe" Source="$(var.DisplayMagicianShellExtension.TargetDir)\ServerRegistrationManager.exe" KeyPath="yes" />
</Component>
<Component Guid="*" Directory="APPLICATIONROOTDIRECTORY">
<File Id="SharpShell.dll" Source="$(var.DisplayMagicianShellExtension.TargetDir)\SharpShell.dll" KeyPath="yes" />
</Component>
<!-- Add in the LogReporter files we need -->
<Component Guid="*" Directory="APPLICATIONROOTDIRECTORY">
<File Id="LogReporter.exe" KeyPath="yes" Source="$(var.DisplayMagicianLogReporter.TargetDir)\LogReporter.exe" />
</Component>
<Component Guid="*" Directory="APPLICATIONROOTDIRECTORY">
<File Id="LogReporter.exe.config" KeyPath="yes" Source="$(var.DisplayMagicianLogReporter.TargetDir)\LogReporter.exe.config" />
</Component>
</Feature>
</Product>
</Wix>

View File

Before

Width:  |  Height:  |  Size: 457 KiB

After

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

View File

@ -17,7 +17,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Debug\</OutputPath>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
@ -57,7 +57,6 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="ResizeDrawing.cs" />
<Compile Include="RestartManagerSession.cs" />
<Compile Include="ScanLineOrdering.cs" />
<Compile Include="NVIDIA\SurroundHelper.cs" />
<Compile Include="NVIDIA\SurroundTopologyDisplay.cs" />
@ -68,10 +67,8 @@
<Compile Include="ProfileIcon.cs" />
<Compile Include="Rotation.cs" />
<Compile Include="Scaling.cs" />
<Compile Include="ShellHelper.cs" />
<Compile Include="ProfileRepository.cs" />
<Compile Include="TaskBarSettings.cs" />
<Compile Include="TaskBarStuckRectangle.cs" />
<Compile Include="ShellUtils.cs" />
<Compile Include="Topology\Path.cs" />
<Compile Include="Topology\PathHelper.cs" />
<Compile Include="Topology\PathTarget.cs" />

View File

@ -1,9 +1,10 @@
namespace DisplayMagician.Shared
namespace DisplayMagicianShared
{
public enum DisplayMagicianStartupAction
{
RunShortcut,
ChangeProfile,
CreateProfile,
StartUpNormally
}
}

View File

@ -1,7 +1,7 @@
using NvAPIWrapper.Native.Display;
using NvAPIWrapper.Native.Mosaic;
namespace DisplayMagician.Shared.NVIDIA
namespace DisplayMagicianShared.NVIDIA
{
internal static class SurroundHelper
{

View File

@ -6,7 +6,7 @@ using NvAPIWrapper.Mosaic;
using NvAPIWrapper.Native.Interfaces.Mosaic;
using System.Collections.Generic;
namespace DisplayMagician.Shared.NVIDIA
namespace DisplayMagicianShared.NVIDIA
{
public class SurroundTopology
{

View File

@ -10,7 +10,7 @@ using Newtonsoft.Json.Converters;
using NvAPIWrapper.Mosaic;
using NvAPIWrapper.Native.Exceptions;
namespace DisplayMagician.Shared.NVIDIA
namespace DisplayMagicianShared.NVIDIA
{
public class SurroundTopologyDisplay
{

View File

@ -1,4 +1,4 @@
namespace DisplayMagician.Shared
namespace DisplayMagicianShared
{
public enum PixelShift
{

View File

@ -5,9 +5,9 @@ using System.Drawing.IconLib;
using System.Drawing.Imaging;
using System.Linq;
using System.Windows.Forms;
using DisplayMagician.Shared.Topology;
using DisplayMagicianShared.Topology;
namespace DisplayMagician.Shared
namespace DisplayMagicianShared
{
public class ProfileIcon
{

View File

@ -7,18 +7,18 @@ using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
using WindowsDisplayAPI.DisplayConfig;
using DisplayMagician.Shared.Resources;
using DisplayMagicianShared.Resources;
using Newtonsoft.Json;
using NvAPIWrapper.Mosaic;
using NvAPIWrapper.Native.Mosaic;
using DisplayMagician.Shared.Topology;
using DisplayMagicianShared.Topology;
using System.Drawing;
using System.Drawing.Imaging;
using WindowsDisplayAPI;
using System.Text.RegularExpressions;
using NvAPIWrapper.Display;
namespace DisplayMagician.Shared
namespace DisplayMagicianShared
{
public class ProfileItem : IComparable
{

View File

@ -1,4 +1,4 @@
using DisplayMagician.Shared;
using DisplayMagicianShared;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@ -8,11 +8,11 @@ using System.IO;
using System.Linq;
using System.Text;
using WindowsDisplayAPI.DisplayConfig;
using DisplayMagician.Shared.Resources;
using DisplayMagicianShared.Resources;
using Newtonsoft.Json;
using NvAPIWrapper.Mosaic;
using NvAPIWrapper.Native.Mosaic;
using DisplayMagician.Shared.Topology;
using DisplayMagicianShared.Topology;
using System.Drawing;
using System.Drawing.Imaging;
using WindowsDisplayAPI;
@ -26,10 +26,10 @@ using System.Resources;
using System.Net.NetworkInformation;
using NvAPIWrapper.Mosaic;
using NvAPIWrapper.Native.Mosaic;
using DisplayMagician.Shared.Topology;
using DisplayMagicianShared.Topology;
using NvAPIWrapper.Native.GPU;
namespace DisplayMagician.Shared
namespace DisplayMagicianShared
{
public static class ProfileRepository
@ -347,15 +347,6 @@ namespace DisplayMagician.Shared
// then we also need to reproduce the Icons
if (ContainsProfile(profile))
{
// rename the old Profile Icon to the new name
//string newSavedProfileIconCacheFilename = Path.Combine(_profileStorageJsonPath, String.Concat(@"profile-", profile.UUID, @".ico"));
//File.Move(profile.SavedProfileIconCacheFilename, newSavedProfileIconCacheFilename);
// Then update the profile too
//profile.SavedProfileIconCacheFilename = newSavedProfileIconCacheFilename;
// Save the Profiles JSON as it's different now
SaveProfiles();
@ -373,7 +364,7 @@ namespace DisplayMagician.Shared
ProfileItem activeProfile = new ProfileItem
{
Name = "Current Display Profile",
Paths = PathInfo.GetActivePaths().Select(info => new DisplayMagician.Shared.Topology.Path(info)).ToArray()
Paths = PathInfo.GetActivePaths().Select(info => new DisplayMagicianShared.Topology.Path(info)).ToArray()
};
activeProfile.ProfileIcon = new ProfileIcon(activeProfile);
@ -452,7 +443,7 @@ namespace DisplayMagician.Shared
ProfileItem myCurrentProfile = new ProfileItem
{
Name = "Current Display Profile",
Paths = PathInfo.GetActivePaths().Select(info => new DisplayMagician.Shared.Topology.Path(info)).ToArray()
Paths = PathInfo.GetActivePaths().Select(info => new DisplayMagicianShared.Topology.Path(info)).ToArray()
};
_currentProfile = myCurrentProfile;
@ -481,7 +472,7 @@ namespace DisplayMagician.Shared
ProfileItem myCurrentProfile = new ProfileItem
{
Name = "Current Display Profile",
Paths = PathInfo.GetActivePaths().Select(info => new DisplayMagician.Shared.Topology.Path(info)).ToArray()
Paths = PathInfo.GetActivePaths().Select(info => new DisplayMagicianShared.Topology.Path(info)).ToArray()
};
_currentProfile = myCurrentProfile;
@ -599,7 +590,7 @@ namespace DisplayMagician.Shared
myPhysicalGPU.Foundry.ToString(),
myPhysicalGPU.GPUId.ToString(),
myPhysicalGPU.GPUType.ToString(),
aGPUOutput.OutputId.ToString(),
//aGPUOutput.OutputId.ToString(),
aConnectedDisplayDevice.ConnectionType.ToString(),
aConnectedDisplayDevice.DisplayId.ToString()
};

View File

@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("HeliosDisplayManagement.Shared")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("DisplayMagician.Shared")]
[assembly: AssemblyDescription("Shared libraries for DisplayMagician")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DisplayMagician.Shared")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyCompany("LittleBitBig")]
[assembly: AssemblyProduct("DisplayMagician")]
[assembly: AssemblyCopyright("Copyright © Terry MacDonald 2020-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -22,7 +22,7 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1cacda43-01c7-4cd4-bf6e-9421a29510fc")]
[assembly: Guid("c63ad693-1518-423a-add0-a14056fa3a55")]
// Version information for an assembly consists of the following four values:
//
@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.5.*")]
[assembly: AssemblyFileVersion("0.9.5.0")]
[assembly: AssemblyVersion("0.2.1.*")]
[assembly: AssemblyFileVersion("0.2.1.0")]

View File

@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace DisplayMagician.Shared.Properties {
namespace DisplayMagicianShared.Properties {
using System;
@ -39,7 +39,7 @@ namespace DisplayMagician.Shared.Properties {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DisplayMagician.Shared.Properties.Resources", typeof(Resources).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DisplayMagicianShared.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;

View File

@ -1,7 +1,7 @@
using System;
using System.Drawing;
namespace DisplayMagician.Shared
namespace DisplayMagicianShared
{
public static class ResizeDrawing
{

View File

Before

Width:  |  Height:  |  Size: 457 KiB

After

Width:  |  Height:  |  Size: 457 KiB

View File

@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace DisplayMagician.Shared.Resources {
namespace DisplayMagicianShared.Resources {
using System;
@ -39,7 +39,7 @@ namespace DisplayMagician.Shared.Resources {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DisplayMagician.Shared.Resources.Language", typeof(Language).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DisplayMagicianShared.Resources.Language", typeof(Language).Assembly);
resourceMan = temp;
}
return resourceMan;

View File

@ -1,4 +1,4 @@
namespace DisplayMagician.Shared
namespace DisplayMagicianShared
{
public enum Rotation
{

View File

@ -1,4 +1,4 @@
namespace DisplayMagician.Shared
namespace DisplayMagicianShared
{
public enum Scaling
{

View File

@ -1,4 +1,4 @@
namespace DisplayMagician.Shared
namespace DisplayMagicianShared
{
public enum ScanLineOrdering
{

View File

@ -0,0 +1,23 @@
using System.Runtime.InteropServices;
namespace DisplayMagicianShared
{
public class ShellUtils
{
public static string AUMID = "LittleBitBig.DisplayMagician";
// Add the ability to set an Application AUMID so that Windows 10+ recognises the
// application and things like Toasts, Tasbar pinning and similar functionality
// works as intended. This DLL import avoids the need to package the app as an MSIX
// or moving to a WiX based installer at this stage, or the need to add this to the
// Windows Store.
[DllImport("shell32.dll", SetLastError = true)]
public static extern void SetCurrentProcessExplicitAppUserModelID([MarshalAs(UnmanagedType.LPWStr)] string AppID);
public static void SetDefaultProcessExplicitAppUserModelID()
{
SetCurrentProcessExplicitAppUserModelID(AUMID);
}
}
}

View File

@ -7,7 +7,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Collections.Generic;
namespace DisplayMagician.Shared.Topology
namespace DisplayMagicianShared.Topology
{
public class Path
{

View File

@ -1,6 +1,6 @@
using WindowsDisplayAPI.Native.DisplayConfig;
namespace DisplayMagician.Shared.Topology
namespace DisplayMagicianShared.Topology
{
internal static class PathHelper
{

View File

@ -1,12 +1,12 @@
using System;
using System.Linq;
using WindowsDisplayAPI.DisplayConfig;
using DisplayMagician.Shared.NVIDIA;
using DisplayMagicianShared.NVIDIA;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Collections.Generic;
namespace DisplayMagician.Shared.Topology
namespace DisplayMagicianShared.Topology
{
public class PathTarget : IEquatable<PathTarget>
{

View File

@ -1,4 +1,4 @@
namespace DisplayMagician.Shared.UserControls
namespace DisplayMagicianShared.UserControls
{
partial class DisplayView
{

View File

@ -1,9 +1,9 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using DisplayMagician.Shared.Topology;
using DisplayMagicianShared.Topology;
namespace DisplayMagician.Shared.UserControls
namespace DisplayMagicianShared.UserControls
{
public partial class DisplayView : UserControl
{
@ -36,6 +36,10 @@ namespace DisplayMagician.Shared.UserControls
{
DrawView(e.Graphics);
}
else
{
DrawEmptyView(e.Graphics);
}
}
private void DrawPath(Graphics g, Path path)
@ -233,5 +237,12 @@ namespace DisplayMagician.Shared.UserControls
DrawPath(g, path);
}
}
private void DrawEmptyView(Graphics g)
{
RectangleF rect = g.VisibleClipBounds;
g.FillRectangle(new SolidBrush(Color.FromArgb(15, Color.White)), rect);
g.DrawRectangle(Pens.Black, rect.X, rect.Y, rect.Width, rect.Height);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,175 @@
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.IO;
using System;
using SharpShell.Attributes;
using SharpShell.SharpContextMenu;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Win32;
using System.Drawing;
namespace DisplayMagicianShellExtension
{
[ComVisible(true)]
[Guid("de271cd7-fa82-439f-b128-202d473bb51e")]
[RegistrationName("DisplayMagician.ShellExtension")]
[COMServerAssociation(AssociationType.DesktopBackground)]
public class DisplayMagicianDesktopMenuExtension : SharpContextMenu
{
// Other constants that are useful
internal static Version _version = new Version(0, 1, 0);
internal static string AlternateAppHomePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "DisplayMagician");
internal static string AppDataPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DisplayMagician");
private static string AppProfileStoragePath = System.IO.Path.Combine(AppDataPath, $"Profiles");
private static string _profileStorageJsonFileName = System.IO.Path.Combine(AppProfileStoragePath, $"DisplayProfiles_1.0.json");
internal static string registryDisplayMagician = @"SOFTWARE\DisplayMagician";
string DisplayMagicianFullname = "";
string DisplayMagicianInstallDir = "";
Process DisplayMagicianProcess = null;
private struct ProfileData
{
public string UUID;
public string Name;
public Bitmap Bitmap;
}
public DisplayMagicianDesktopMenuExtension()
{ }
protected override bool CanShowMenu()
{
//Logging.Log($"Starting CanShowMenu");
// Only show this menu if DisplayMagician is installed
DisplayMagicianInstallDir = "";
try
{
RegistryKey DisplayMagicianKey = Registry.LocalMachine.OpenSubKey(registryDisplayMagician, RegistryKeyPermissionCheck.ReadSubTree);
DisplayMagicianInstallDir = DisplayMagicianKey.GetValue("InstallDir", AlternateAppHomePath).ToString();
}
catch (Exception)
{
DisplayMagicianInstallDir = AlternateAppHomePath;
}
DisplayMagicianFullname = Path.Combine(DisplayMagicianInstallDir, "DisplayMagician.exe");
//Logging.Log($"DisplayMagician is installed in {DisplayMagicianFullname}");
if (File.Exists(DisplayMagicianFullname))
{
//Logging.Log($"CanShowMenu is returning true (can show menu)");
return true;
}
else
{
//Logging.Log($"CanShowMenu is returning false (cannot show menu)");
return false;
}
}
protected override ContextMenuStrip CreateMenu()
{
//Logging.Log($"Starting CreateMenu");
var explorerMenuStrip = new ContextMenuStrip();
List<ProfileData> profiles = new List<ProfileData>();
if (File.Exists(_profileStorageJsonFileName))
{
//Logging.Log($"{_profileStorageJsonFileName} file exists");
MatchCollection mc;
string uuid = "";
string profileName = "";
string profileBitmapData = "";
foreach (string aLine in File.ReadLines(_profileStorageJsonFileName, Encoding.Unicode))
{
//Logging.Log($"Processing line: {_profileStorageJsonFileName}");
string lineToProcess = aLine;
if (lineToProcess.StartsWith(" \"UUID\""))
{
//Logging.Log($"Line starts with 4 spaces and UUID");
mc = Regex.Matches(lineToProcess, " \"UUID\": \"(.*)\"");
uuid = mc[0].Groups[1].ToString();
}
else if (lineToProcess.StartsWith(" \"Name\""))
{
//Logging.Log($"Line starts with 4 spaces and Name");
mc = Regex.Matches(lineToProcess, " \"Name\": \"(.*)\"");
profileName = mc[0].Groups[1].ToString();
}
else if (lineToProcess.StartsWith(" \"ProfileBitmap\""))
{
//Logging.Log($"Line starts with 4 spaces and Name");
mc = Regex.Matches(lineToProcess, " \"ProfileBitmap\": \"(.*)\"");
profileBitmapData = mc[0].Groups[1].ToString();
if (!String.IsNullOrEmpty(uuid) && !String.IsNullOrEmpty(profileName))
{
var bytes = Convert.FromBase64String(profileBitmapData);
Bitmap profileBitmap;
using (var ms = new MemoryStream(bytes))
profileBitmap = new Bitmap(Bitmap.FromStream(ms),16,16);
ProfileData newProfile = new ProfileData();
newProfile.UUID = uuid;
newProfile.Name = profileName;
if (profileBitmap is Bitmap)
{
newProfile.Bitmap = profileBitmap;
}
else
newProfile.Bitmap = null;
profiles.Add(newProfile);
}
}
}
}
var extensionMenu = new ToolStripMenuItem("DisplayMagician: Change display profiles...", Properties.Resources.MenuImage);
explorerMenuStrip.Items.Add(extensionMenu);
// Add the first menu to create a new Display Profile
extensionMenu.DropDownItems.Add(new ToolStripMenuItem("Create a new display profile", null,
(sender, args) =>
{
//Logging.Log(DisplayMagicianFullname + $" CreateProfile");
DisplayMagicianProcess = Process.Start(DisplayMagicianFullname, $"CreateProfile");
//Logging.Log(DisplayMagicianProcess.ToString());
}
));
if (profiles.Count > 0)
{
extensionMenu.DropDownItems.Add(new ToolStripSeparator());
foreach (ProfileData profile in profiles.OrderBy(p => p.Name))
{
extensionMenu.DropDownItems.Add(new ToolStripMenuItem(profile.Name, profile.Bitmap,
(sender, args) =>
{
//Logging.Log(DisplayMagicianFullname + $" ChangeProfile \"{pair.Value}\"");
DisplayMagicianProcess = Process.Start(DisplayMagicianFullname,$"ChangeProfile \"{profile.UUID}\"");
//Logging.Log(DisplayMagicianProcess.ToString());
}
));
}
}
return explorerMenuStrip;
}
}
}

View File

@ -7,8 +7,8 @@
<ProjectGuid>{55D4FF65-EDC7-48EF-933E-B6E7F3809B68}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DisplayMagician.ShellExtension</RootNamespace>
<AssemblyName>DisplayMagician.ShellExtension</AssemblyName>
<RootNamespace>DisplayMagicianShellExtension</RootNamespace>
<AssemblyName>DisplayMagicianShellExtension</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
@ -17,7 +17,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Debug\</OutputPath>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
@ -63,7 +63,7 @@
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<Generator>PublicResXFileCodeGenerator</Generator>
<SubType>Designer</SubType>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>

View File

@ -6,11 +6,11 @@ using System.Runtime.InteropServices;
// associated with an assembly.
[assembly: AssemblyTitle("DisplayMagician Shell Extension")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyDescription("Change display profiles from your Desktop using this popup menu.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("LittleBitBig")]
[assembly: AssemblyProduct("DisplayMagician")]
[assembly: AssemblyCopyright("Copyright © Terry MacDonald 2020-2021, Copyright © Soroush Falahati 2017-2020")]
[assembly: AssemblyCopyright("Copyright © Terry MacDonald 2020-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -22,7 +22,7 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("346e3285-43ca-45bc-8b33-1d4cdfe32e00")]
[assembly: Guid("592ecbe6-3052-47bb-b962-101abb5e0ce9")]
// Version information for an assembly consists of the following four values:
//
@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.5.*")]
[assembly: AssemblyFileVersion("0.9.5.0")]
[assembly: AssemblyVersion("0.2.1.*")]
[assembly: AssemblyFileVersion("0.2.1.0")]

View File

@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace DisplayMagician.ShellExtension.Properties {
namespace DisplayMagicianShellExtension.Properties {
using System;
@ -22,7 +22,7 @@ namespace DisplayMagician.ShellExtension.Properties {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
public class Resources {
private static global::System.Resources.ResourceManager resourceMan;
@ -36,10 +36,10 @@ namespace DisplayMagician.ShellExtension.Properties {
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DisplayMagician.ShellExtension.Properties.Resources", typeof(Resources).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DisplayMagicianShellExtension.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
@ -51,7 +51,7 @@ namespace DisplayMagician.ShellExtension.Properties {
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
@ -63,7 +63,7 @@ namespace DisplayMagician.ShellExtension.Properties {
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon DisplayMagician {
public static System.Drawing.Icon DisplayMagician {
get {
object obj = ResourceManager.GetObject("DisplayMagician", resourceCulture);
return ((System.Drawing.Icon)(obj));
@ -73,9 +73,9 @@ namespace DisplayMagician.ShellExtension.Properties {
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DisplayMagicianMenuImage {
public static System.Drawing.Bitmap MenuImage {
get {
object obj = ResourceManager.GetObject("DisplayMagicianMenuImage", resourceCulture);
object obj = ResourceManager.GetObject("MenuImage", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}

View File

@ -121,7 +121,7 @@
<data name="DisplayMagician" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\DisplayMagician.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="DisplayMagicianMenuImage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<data name="MenuImage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\DisplayMagicianMenuImage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

Before

Width:  |  Height:  |  Size: 457 KiB

After

Width:  |  Height:  |  Size: 457 KiB

View File

@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace DisplayMagician.ShellExtension.Resources {
namespace DisplayMagicianShellExtension.Resources {
using System;
@ -39,7 +39,7 @@ namespace DisplayMagician.ShellExtension.Resources {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DisplayMagician.ShellExtension.Resources.Language", typeof(Language).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DisplayMagicianShellExtension.Resources.Language", typeof(Language).Assembly);
resourceMan = temp;
}
return resourceMan;

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

View File

@ -4,6 +4,12 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
<ApplicationIcon>DisplayMagician.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>bin\Debug\</OutputPath>
</PropertyGroup>
<ItemGroup>
@ -13,8 +19,8 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DisplayMagician.LogReporter\DisplayMagician.LogReporter.csproj" />
<ProjectReference Include="..\DisplayMagician.Shared\DisplayMagician.Shared.csproj" />
<ProjectReference Include="..\DisplayMagician.LogReporter\DisplayMagicianLogReporter.csproj" />
<ProjectReference Include="..\DisplayMagicianShared\DisplayMagicianShared.csproj" />
<ProjectReference Include="..\DisplayMagician\DisplayMagician.csproj" />
</ItemGroup>

Some files were not shown because too many files have changed in this diff Show More