Skip to content

Commit

Permalink
Merge pull request #10 from otakulan/feature/tgh/msi-installer
Browse files Browse the repository at this point in the history
Create MSI installer for deployment
  • Loading branch information
starcraft66 authored Oct 27, 2023
2 parents d41a8c6 + eece286 commit ea22d51
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 8 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/build-installer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: .NET

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
- name: Cache NuGet packages
uses: actions/cache@v3
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}-${{ hashFiles('**/*.wixproj') }}
- name: Restore dependencies
run: dotnet restore
- name: Build application
run: dotnet build --no-restore --verbosity normal Lanpartyseating.Desktop --configuration Release
- name: Test
run: dotnet test --no-restore --verbosity normal Lanpartyseating.Desktop.Tests --configuration Release
- name: Build
run: dotnet build LanpartySeating.Desktop.Installer/LanpartySeating.Desktop.Installer.wixproj --configuration Release --property:Version=1.0.20
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: LanpartySeating.Desktop.Installer
path: |
LanpartySeating.Desktop.Installer/bin/Release/LanpartySeating.Desktop.Installer.msi
LanpartySeating.Desktop.Installer/bin/Release/LanpartySeating.Desktop.Installer.wixpdb
33 changes: 33 additions & 0 deletions LanpartySeating.Desktop.Installer/ExcludeFiles.xslt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wix="http://wixtoolset.org/schemas/v4/wxs">
<xsl:output method="xml" indent="yes"/>

<!-- Identity transformation: copy all content by default -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<!-- Remove the executable, we reference it in the service installation -->
<xsl:key
name="FilesToRemove"
match="wix:Component[wix:File[contains(@Source, 'Lanpartyseating.Desktop.exe')]]"
use="@Id"
/>

<!-- Remove the configuration files, they should be provided by the user -->
<xsl:key
name="FilesToRemove"
match="wix:Component[wix:File[contains(@Source, 'appsettings.json')]]"
use="@Id"
/>
<xsl:key
name="FilesToRemove"
match="wix:Component[wix:File[contains(@Source, 'appsettings.Development.json')]]"
use="@Id"
/>

<!-- ...but if the element has the "FilesToRemove" key then don't render anything (i.e. removing it from the output) -->
<xsl:template match="wix:ComponentRef[ key( 'FilesToRemove', @Id ) ]" />
<xsl:template match="wix:Component[ key( 'FilesToRemove', @Id ) ]" />
</xsl:stylesheet>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="WixToolset.Sdk/4.0.2">
<PropertyGroup>
<!-- 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)</DefineConstants>
<OutputType>package</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<InstallerPlatform>x64</InstallerPlatform>
</PropertyGroup>
<ItemGroup>
<HarvestDirectory Include="..\Lanpartyseating.Desktop\bin\$(Configuration)\net7.0-windows\">
<DirectoryRefId>INSTALLFOLDER</DirectoryRefId>
<ComponentGroupName>ApplicationFilesComponentGroup</ComponentGroupName>
<KeepEmptyDirectories>true</KeepEmptyDirectories>
<SuppressRootDirectory>true</SuppressRootDirectory>
<Transforms>ExcludeFiles.xslt</Transforms>
</HarvestDirectory>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lanpartyseating.Desktop\Lanpartyseating.Desktop.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="WixToolset.Heat" Version="4.0.2" />
<PackageReference Include="WixToolset.Util.wixext" Version="4.0.2" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>

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

<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
<Package Name="$(Name)"
Manufacturer="$(Manufacturer)"
Version="$(Version)"
UpgradeCode="$(UpgradeCode)"
Compressed="true">

<Media Id="1" Cabinet="application.cab" EmbedCab="yes" />

<Feature Id="MainApplication" Title="Lanpartyseating.Desktop Application" Level="1">
<!-- Reference the component group inside the feature. -->
<ComponentGroupRef Id="ApplicationFilesComponentGroup" />
<ComponentRef Id="ConfigPermissions" />
</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)" />
</StandardDirectory>
<!-- Define the ProgramData directory -->
<StandardDirectory Id="CommonAppDataFolder">
<Directory Id="CONFIGFOLDER" Name="$(FolderName)" />
</StandardDirectory>

<DirectoryRef Id="CONFIGFOLDER">
<!-- Create config folder to store appsettings.json -->
<!-- Make sure regular users can't read the config file because it contains credentials -->
<Component Id="ConfigPermissions" Guid="16b25c34-404e-47d5-9fd5-b88eb507216d">
<CreateFolder>
<!-- Deny read access to Everyone -->
<util:PermissionEx User="Users"
GenericRead="no"
Read="no"
GenericExecute="no"
Domain="[LOCAL_MACHINE]" />

<util:PermissionEx User="Administrators"
GenericAll="yes"
GenericWrite="yes"
Delete="yes"
Domain="[LOCAL_MACHINE]" />

<util:PermissionEx User="LocalService"
GenericRead="yes"
GenericWrite="yes"
Delete="yes"
Domain="[LOCAL_MACHINE]" />
</CreateFolder>
</Component>
</DirectoryRef>

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

<!-- 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)\net7.0-windows\Lanpartyseating.Desktop.exe" />

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

<!-- Tell WiX to install the Service -->
<ServiceInstall Id="ServiceInstaller"
Type="ownProcess"
Name="Lanpartyseating.Desktop"
DisplayName="Lanparty Seating Desktop Client"
Description="A desktop client for the Lanparty Seating System"
Start="auto"
Account="LocalSystem"
Interactive="no"
ErrorControl="normal" />

<!-- Tell WiX not to start the service on install but to stop it on uninstall -->
<ServiceControl Id="StartService"
Start="none"
Stop="both"
Remove="uninstall"
Name="Lanpartyseating.Desktop"
Wait="true" />
</Component>
</DirectoryRef>

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

</Package>
</Wix>
11 changes: 7 additions & 4 deletions Lanpartyseating.Desktop/Business/Callbacks.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using Lanpartyseating.Desktop.Config;
using Lanpartyseating.Desktop.Contracts;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand All @@ -24,28 +25,30 @@ public Callbacks(ILogger<Callbacks> logger, IOptions<SeatingOptions> options, Ut
public void NewReservation(Message payload)
{
var payloadObject = payload.Payload.Unbox<NewReservation>();

_logger.LogInformation($"New reservation created for station #{payloadObject.StationNumber}");
if (!_utils.ForThisStation(payloadObject.StationNumber, Environment.MachineName)) return;
// return;

_utils.LoginInteractiveSession(_options.GamerAccountUsername, _options.GamerAccountPassword);
}

public void TournamentStart(Message payload)
{
var payloadObject = payload.Payload.Unbox<TournamentStart>();

_logger.LogInformation($"Tournament started for station #{payloadObject.StationNumber}");
if (!_utils.ForThisStation(payloadObject.StationNumber, Environment.MachineName)) return;
// return;

_utils.LoginInteractiveSession(_options.TournamentAccountUsername, _options.TournamentAccountPassword);
}

public void CancelReservation(Message payload)
{
var payloadObject = payload.Payload.Unbox<CancelReservation>();

_logger.LogInformation($"Reservation cancelled for station #{payloadObject.StationNumber}");
if (!_utils.ForThisStation(payloadObject.StationNumber, Environment.MachineName)) return;
// return;
// Log off the user

_utils.LogoffInteractiveSession();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Options;
using Lanpartyseating.Desktop.Config;
using Microsoft.Extensions.Options;
using Phoenix;
using PhoenixTests.WebSocketImpl;

Expand Down
2 changes: 1 addition & 1 deletion Lanpartyseating.Desktop/Config/SeatingOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Lanpartyseating.Desktop;
namespace Lanpartyseating.Desktop.Config;

public class SeatingOptions
{
Expand Down
9 changes: 9 additions & 0 deletions Lanpartyseating.Desktop/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using JetBrains.Annotations;
using Lanpartyseating.Desktop.Business;
using Lanpartyseating.Desktop.Config;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Lanpartyseating.Desktop;
Expand All @@ -10,6 +12,13 @@ internal class Program
static void Main(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
.ConfigureHostConfiguration(config =>
{
config.AddJsonFile(
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
"Lanparty Seating",
"appsettings.json"), true);
})
.ConfigureServices(services =>
{
services.AddWindowsService(options =>
Expand Down
6 changes: 5 additions & 1 deletion Lanpartyseating.Desktop/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
{
"profiles": {
"Lanpartyseating.Desktop": {
"Debug": {
"commandName": "Project",
"dotnetRunMessages": true,
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
},
"Release": {
"commandName": "Project",
"dotnetRunMessages": true
}
}
}
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ computers. Its primary purpose is to facilitate various actions related to gamin
logout of users, session time extension or reduction without interrupting players, preparing computers for tournaments,
and monitoring computer status.

**Please Note:** As of the current release, none of the aforementioned functionality has been implemented, but
**Please Note:** As of the current release, not all of the aforementioned functionality has been implemented, but
Lanpartyseating.Desktop is designed to evolve over time.

## Features
Expand All @@ -27,6 +27,23 @@ The core features planned for Lanpartyseating.Desktop include:
4. **Computer Monitoring:** The client will provide real-time monitoring of computer status, allowing administrators to
identify and address issues promptly.

## Configuration

Lanpartyseating.Desktop is configured using the `appsettings.json` file, located either in the same directory as the
executable or in the `C:\ProgramData\Lanparty Seating` directory.

The following settings are available:

| Setting | Description |
|------------------------------|----------------------------------------------------------------|
| `Seating.WebsocketEndpoint` | The `lanparty-seating` WebSocket endpoint to connect to. |
| `Seating.GamerUsername` | The username of the gamer account to use for automatic login. |
| `Seating.GamerPassword` | The password of the gamer account to use for automatic login. |
| `Seating.TournamentUsername` | The username of the tournament account to use for tournaments. |
| `Seating.TournamentPassword` | The password of the tournament account to use for tournaments. |

An example configuration file can be found in the repo at `Lanpartyseating.Desktop/appsettings.json`.

### Phoenix.Channel

The client connects to a Phoenix.Channel within the web application, enabling seamless communication between the desktop
Expand Down

0 comments on commit ea22d51

Please sign in to comment.