Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tray Icon + Toast Notification service #13

Merged
merged 2 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LanpartySeating.Desktop.Installer/ExcludeFiles.xslt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<!-- Remove the configuration files, they should be provided by the user -->
<xsl:key
name="FilesToRemove"
match="wix:Component[wix:File[contains(@Source, 'appsettings.json')]]"
match="wix:Component[wix:File[contains(@Source, 'appsettings.Production.json')]]"
use="@Id"
/>
<xsl:key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,34 @@
<!-- Default to Version 1.0.0 if not specified via /p:Version=x.x.x from cli -->
<Version Condition=" '$(Version)' == '' ">1.0.0</Version>
<!-- Propagate version information from msbuild to the WiX project -->
<DefineConstants>$(DefineConstants);Version=$(Version);PublishOutput=..\Lanpartyseating.Desktop\bin\$(Configuration)\net8.0-windows\win-$(InstallerPlatform)\publish</DefineConstants>
<DefineConstants>$(DefineConstants);Version=$(Version);ServicePublishOutput=..\Lanpartyseating.Desktop\bin\$(Configuration)\net8.0-windows\win-$(InstallerPlatform)\publish;TrayPublishOutput=..\Lanpartyseating.Desktop.Tray\bin\$(Configuration)\net8.0-windows10.0.22621.0\win-$(InstallerPlatform)\publish</DefineConstants>
<OutputType>package</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<!-- Default to x64 if not specified via /p:InstallerPlatform=x64 or /p:InstallerPlatform=arm64 from cli -->
<InstallerPlatform Condition=" '$(InstallerPlatform)' == '' ">x64</InstallerPlatform>
<OutputName>LanpartySeating.Desktop.Installer-$(InstallerPlatform)</OutputName>
</PropertyGroup>
<ItemGroup>
<HarvestDirectory Include="..\Lanpartyseating.Desktop.Tray\bin\$(Configuration)\net8.0-windows10.0.22621.0\win-$(InstallerPlatform)\publish\">
<DirectoryRefId>TRAYINSTALLFOLDER</DirectoryRefId>
<ComponentGroupName>TrayApplicationFilesComponentGroup</ComponentGroupName>
<KeepEmptyDirectories>true</KeepEmptyDirectories>
<SuppressRootDirectory>true</SuppressRootDirectory>
<PreprocessorVariable>var.TrayPublishOutput</PreprocessorVariable>
</HarvestDirectory>
<HarvestDirectory Include="..\Lanpartyseating.Desktop\bin\$(Configuration)\net8.0-windows\win-$(InstallerPlatform)\publish\">
<DirectoryRefId>INSTALLFOLDER</DirectoryRefId>
<ComponentGroupName>ApplicationFilesComponentGroup</ComponentGroupName>
<DirectoryRefId>SERVICEINSTALLFOLDER</DirectoryRefId>
<ComponentGroupName>ServiceApplicationFilesComponentGroup</ComponentGroupName>
<KeepEmptyDirectories>true</KeepEmptyDirectories>
<SuppressRootDirectory>true</SuppressRootDirectory>
<Transforms>ExcludeFiles.xslt</Transforms>
<PreprocessorVariable>var.PublishOutput</PreprocessorVariable>
<PreprocessorVariable>var.ServicePublishOutput</PreprocessorVariable>
</HarvestDirectory>
</ItemGroup>
<Target Name="CustomBeforeBuild" BeforeTargets="BeforeBuild">
<Message Text="BeforeBuild is running" Importance="high" />
<Message Text="InstallerPlatform is $(InstallerPlatform)" Importance="high" />
<Exec Command="dotnet publish ..\Lanpartyseating.Desktop\Lanpartyseating.Desktop.csproj -c Release -r win-$(InstallerPlatform) -o ..\Lanpartyseating.Desktop\bin\$(Configuration)\net8.0-windows\win-$(InstallerPlatform)\publish\" />
<Exec Command="dotnet publish ..\Lanpartyseating.Desktop.Tray\Lanpartyseating.Desktop.Tray.csproj -c Release -r win-$(InstallerPlatform) -o ..\Lanpartyseating.Desktop.Tray\bin\$(Configuration)\net8.0-windows10.0.22621.0\win-$(InstallerPlatform)\publish\" />
</Target>
<ItemGroup>
<PackageReference Include="WixToolset.Heat" Version="4.0.3" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>

<?define Name = "Lanparty Seating Desktop Client" ?>
<?define FolderName = "Lanparty Seating" ?>
<?define ServiceFolderName = "Lanparty Seating" ?>
<?define TrayFolderName = "Lanparty Seating Tray" ?>
<?define Manufacturer = "Otakuthon PC Gaming" ?>
<?define UpgradeCode = "{B7277C09-B011-4D40-8995-2093303E9F28}" ?>

Expand All @@ -16,22 +17,54 @@

<Feature Id="MainApplication" Title="Lanpartyseating.Desktop Application" Level="1">
<!-- Reference the component group inside the feature. -->
<ComponentGroupRef Id="ApplicationFilesComponentGroup" />
<ComponentGroupRef Id="ServiceApplicationFilesComponentGroup" />
<ComponentRef Id="ConfigPermissions" />
</Feature>

<Feature Id="TrayApplication" Title="Lanpartyseating.Desktop.Tray Application" Level="1">
<!-- Reference the component group inside the feature. -->
<ComponentGroupRef Id="TrayApplicationFilesComponentGroup" />
</Feature>

<!-- Allow upgrades and prevent downgrades -->
<MajorUpgrade DowngradeErrorMessage="A later version of $(Name) is already installed. Setup will now exit." />

<!-- Define the ProgramFiles64Folder directory -->
<StandardDirectory Id="ProgramFiles64Folder">
<Directory Id="INSTALLFOLDER" Name="$(FolderName)" />
<Directory Id="TRAYINSTALLFOLDER" Name="$(TrayFolderName)" />
</StandardDirectory>
<StandardDirectory Id="ProgramFiles64Folder">
<Directory Id="SERVICEINSTALLFOLDER" Name="$(ServiceFolderName)" />
</StandardDirectory>
<!-- Define the ProgramData directory -->
<StandardDirectory Id="CommonAppDataFolder">
<Directory Id="CONFIGFOLDER" Name="$(FolderName)" />
<Directory Id="CONFIGFOLDER" Name="$(ServiceFolderName)" />
</StandardDirectory>

<!-- Shortcut directory -->
<!-- C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp -->
<Directory Id="CommonStartupFolder" Name="ProgramData">
<Directory Id="CommonProgramsFolder" Name="Microsoft">
<Directory Id="CommonStartUpFolder" Name="Windows">
<Directory Id="CommonProgramsMenuFolder" Name="Start Menu">
<Directory Id="CommonStartupMenuFolder" Name="Programs">
<Directory Id="AllUsersStartupFolder" Name="Startup">
<Component Id="TrayShortcut" Bitness="always64" Guid="cc97c616-d26f-4b49-b410-08801d1a53c9">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="Lanparty Seating Desktop Client"
Description="My Application Description"
WorkingDirectory="TRAYINSTALLFOLDER"
Target="[TRAYINSTALLFOLDER]\Lanpartyseating.Desktop.Tray.exe">
<ShortcutProperty Key="{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 5" Value="Otakuthon.Lanpartyseating.Desktop" />
</Shortcut>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>

<DirectoryRef Id="CONFIGFOLDER">
<!-- Create config folder to store appsettings.json -->
<!-- Make sure regular users can't read the config file because it contains credentials -->
Expand All @@ -47,15 +80,15 @@

<!-- The files inside this DirectoryRef are linked to
the Lanpartyseating.Desktop directory via INSTALLFOLDER -->
<DirectoryRef Id="INSTALLFOLDER">
<DirectoryRef Id="SERVICEINSTALLFOLDER">

<!-- Create a single component which is the Lanpartyseating.Desktop.exe file -->
<Component Id="ServiceExecutable" Bitness="always64" Guid="3bcec0f5-8bfa-4fd0-98e8-2ebe0371efa4">

<File Source="..\Lanpartyseating.Desktop\bin\$(Configuration)\net8.0-windows\win-$(InstallerPlatform)\publish\Lanpartyseating.Desktop.exe" />

<!-- Remove all files from the INSTALLFOLDER on uninstall -->
<RemoveFile Id="ALLFILES" Name="*.*" On="both" />
<RemoveFile Id="ALLSERVICEFILES" Name="*.*" On="both" />

<!-- Tell WiX to install the Service -->
<ServiceInstall Id="ServiceInstaller"
Expand All @@ -78,10 +111,35 @@
</Component>
</DirectoryRef>

<DirectoryRef Id="TRAYINSTALLFOLDER">

<!-- Create a single component which is the Lanpartyseating.Desktop.exe file -->
<!-- <Component Id="TrayExecutable" Bitness="always64" Guid="cc97c616-d26f-4b49-b410-08801d1a53c9">-->

<!-- <File Source="..\Lanpartyseating.Desktop.Tray\bin\$(Configuration)\net8.0-windows10.0.22621.0\win-$(InstallerPlatform)\publish\Lanpartyseating.Desktop.Tray.exe" KeyPath="yes" />-->

<!-- Remove all files from the INSTALLFOLDER on uninstall -->
<!-- <RemoveFile Id="ALLTRAYFILES" Name="*.*" On="both" />-->

<!-- <Shortcut Id="ApplicationStartMenuShortcut"-->
<!-- Name="Lanparty Seating Desktop Client"-->
<!-- Description="My Application Description"-->
<!-- WorkingDirectory="TRAYINSTALLFOLDER"-->
<!-- Directory="STARTFOLDER"-->
<!-- Advertise="yes"/>-->
<!-- <RemoveFolder Id="RemoveSTARTFOLDER" Directory="STARTFOLDER" On="uninstall"/>-->
<!-- <RegistryValue Root="HKCU" Key="Software\Otakuthon\LanpartySeatingDesktop" Name="installed" Type="integer" Value="1" />-->

<!-- </Component>-->
</DirectoryRef>

<!-- Tell WiX to install the service -->
<Feature Id="Service" Title="Lanpartyseating.Desktop Service" Level="1">
<ComponentRef Id="ServiceExecutable" />
</Feature>
<Feature Id="Tray" Title="Lanpartyseating.DesktopTray Application" Level="1">
<ComponentRef Id="TrayShortcut" />
</Feature>

</Package>
</Wix>
10 changes: 10 additions & 0 deletions Lanpartyseating.Desktop.Abstractions/BaseMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;

namespace Lanpartyseating.Desktop.Abstractions;

[JsonDerivedType(typeof(ReservationStateRequest), typeDiscriminator: "sessionstaterequest")]
[JsonDerivedType(typeof(ReservationStateResponse), typeDiscriminator: "sessionstateresponse")]
[JsonDerivedType(typeof(TextMessage), typeDiscriminator: "textmessage")]
public abstract class BaseMessage
{
}
16 changes: 16 additions & 0 deletions Lanpartyseating.Desktop.Abstractions/JsonMessageSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Lanpartyseating.Desktop.Abstractions;

using System.Text.Json;

public static class JsonMessageSerializer
{
public static T Deserialize<T>(string json) where T : BaseMessage
{
return JsonSerializer.Deserialize<T>(json);
}

public static string Serialize(BaseMessage message)
{
return JsonSerializer.Serialize(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Lanpartyseating.Desktop.Abstractions;

public class ReservationStateRequest : BaseMessage
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Lanpartyseating.Desktop.Abstractions;

public class ReservationStateResponse : BaseMessage
{
public bool IsSessionActive { get; set; }
public DateTimeOffset ReservationStart { get; set; }
public DateTimeOffset ReservationEnd { get; set; }
}
6 changes: 6 additions & 0 deletions Lanpartyseating.Desktop.Abstractions/TextMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Lanpartyseating.Desktop.Abstractions;

public class TextMessage : BaseMessage
{
public string Content { get; set; }
}
9 changes: 9 additions & 0 deletions Lanpartyseating.Desktop.Tray/ApplicationManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
29 changes: 29 additions & 0 deletions Lanpartyseating.Desktop.Tray/Lanpartyseating.Desktop.Tray.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>trayicon.ico</ApplicationIcon>
<ImplicitUsings>enable</ImplicitUsings>
<ApplicationManifest>ApplicationManifest.xml</ApplicationManifest>
<AssemblyTitle>Otakuthon PC Gaming</AssemblyTitle>
</PropertyGroup>

<ItemGroup>
<None Remove="trayicon.ico" />
<EmbeddedResource Include="trayicon.ico" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="Microsoft.WindowsAPICodePack.Shell" Version="1.1.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Lanpartyseating.Desktop.Abstractions\Lanpartyseating.Desktop.Abstractions.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Compile Update="Form1.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
</Project>
27 changes: 27 additions & 0 deletions Lanpartyseating.Desktop.Tray/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Runtime.InteropServices;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Lanpartyseating.Desktop.Tray;

static class Program
{
[DllImport("shell32.dll", SetLastError = true)]
static extern void SetCurrentProcessExplicitAppUserModelID([MarshalAs(UnmanagedType.LPWStr)] string AppID);

static async Task Main(string[] args)
{
// This code snippet uses the Shell32 API to create a shortcut and set the AppUserModelID
var appUserModelId = "Otakuthon.Lanpartyseating.Desktop"; // Replace with your actual ID
SetCurrentProcessExplicitAppUserModelID(appUserModelId);

var hostBuilder = Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton<TrayIcon>();
services.AddHostedService<TrayIconService>();
services.AddHostedService<ToastNotificationService>();
});
await hostBuilder.RunConsoleAsync();;
}
}
Loading
Loading