diff --git a/.codecov.yml b/.codecov.yml
index 86207739c5b..a55ee4d34f7 100644
--- a/.codecov.yml
+++ b/.codecov.yml
@@ -8,6 +8,7 @@ coverage:
comment:
layout: "header, diff, changes"
ignore:
+ - "build"
- "src/Tgstation.Server.Host/Database/Design"
- "src/Tgstation.Server.Host/Database/Migrations/MySqlDatabaseContextModelSnapshot.cs"
- "src/Tgstation.Server.Host/Database/Migrations/PostgresSqlDatabaseContextModelSnapshot.cs"
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index e6c9393e814..a9eff3af351 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -34,7 +34,7 @@ You can of course, as always, ask for help at [#coderbus](irc://irc.rizon.net/co
### Development Environment
-You need the Dotnet 6.0 SDK and npm>=v5.7 (in your PATH) to compile the server. In order to build the service version you also need a .NET 4.7.1 build chain
+You need the Dotnet 6.0 SDK and npm>=v5.7 (in your PATH) to compile the server. In order to build the service version you also need a .NET 4.7.2 build chain. In order to build the .msi installer, you'll need [Visual Studio 2022](https://visualstudio.microsoft.com/vs/) or greater and the [Visual Studio Installer Projects Extension](https://marketplace.visualstudio.com/items?itemName=VisualStudioClient.MicrosoftVisualStudio2022InstallerProjects).
The recommended IDE is Visual Studio 2019 which has installation options for both of these.
diff --git a/.github/workflows/ci-suite.yml b/.github/workflows/ci-suite.yml
index 0f88ac92116..08afc555d03 100644
--- a/.github/workflows/ci-suite.yml
+++ b/.github/workflows/ci-suite.yml
@@ -920,11 +920,39 @@ jobs:
name: packaging-debian
path: tgstation-server-v${{ env.TGS_VERSION }}.debian.packaging.tar.xz
+ build-msi:
+ name: Build .msi Package
+ needs: start-ci-run-gate
+ runs-on: windows-latest
+ if: "!(cancelled() || failure()) && needs.start-ci-run-gate.result == 'success'"
+ steps:
+ - name: Setup dotnet
+ uses: actions/setup-dotnet@v2
+ with:
+ dotnet-version: ${{ env.TGS_DOTNET_VERSION }}
+
+ - name: Setup VS Dev Environment
+ uses: seanmiddleditch/gha-setup-vsdevenv@v4
+
+ - name: Disable Out of Process Building
+ working-directory: C:/Program Files/Microsoft Visual Studio/2022/Enterprise/Common7/IDE/CommonExtensions/Microsoft/VSI/DisableOutOfProcBuild
+ run: ./DisableOutOfProcBuild.exe
+
+ - name: Build .vdproj
+ shell: powershell
+ run: build/package/winget/build_package.ps1
+
+ - name: Upload .msi
+ uses: actions/upload-artifact@v3
+ with:
+ name: packaging-windows
+ path: packaging/build/package/winget/Tgstation.Server.Host.Service.Msi/Release/tgstation-server.msi
+
deployment-gate:
name: Deployment Gate
- needs: [ dox-build, docker-build, build-deb, validate-openapi-spec, upload-code-coverage ]
+ needs: [ dox-build, docker-build, build-deb, validate-openapi-spec, upload-code-coverage, build-msi ]
runs-on: ubuntu-latest
- if: "!(cancelled() || failure()) && needs.dox-build.result == 'success' && needs.docker-build.result == 'success' && needs.build-deb.result == 'success' && needs.validate-openapi-spec.result == 'success' && needs.upload-code-coverage.result == 'success' && github.event_name == 'push'"
+ if: "!(cancelled() || failure()) && needs.dox-build.result == 'success' && needs.docker-build.result == 'success' && needs.build-deb.result == 'success' && needs.build-msi.result == 'success' && needs.validate-openapi-spec.result == 'success' && needs.upload-code-coverage.result == 'success' && github.event_name == 'push'"
steps:
- name: GitHub Requires at Least One Step for a Job
run: exit 0
@@ -1120,6 +1148,12 @@ jobs:
name: packaging-debian
path: packaging-debian
+ - name: Retrieve .msi
+ uses: actions/download-artifact@v3
+ with:
+ name: packaging-windows
+ path: packaging-windows
+
- name: Zip Artifacts
shell: powershell
run: |
@@ -1203,6 +1237,16 @@ jobs:
asset_name: tgstation-server-v${{ env.TGS_VERSION }}.debian.packaging.tar.xz
asset_content_type: application/x-tar
+ - name: Upload .msi
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.DEV_PUSH_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: ./packaging-windows/tgstation-server.msi
+ asset_name: tgstation-server.msi
+ asset_content_type: application/octet-stream
+
deploy-docker:
name: Deploy TGS (Docker)
needs: deploy-tgs
diff --git a/.gitignore b/.gitignore
index 9d6c8caecd5..607abbf4c2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,4 @@ release_notes.md
*nupkg
*.sqlite3
packaging/
+build/package/winget/Tgstation.Server.Host.Service.Msi/Release/
diff --git a/README.md b/README.md
index bb07b4281e5..c73f4d905ad 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,39 @@ Follow the instructions for your OS below.
#### Windows
-Download and install the [ASP .NET Core Runtime (>= v6.0)](https://dotnet.microsoft.com/download/dotnet/6.0) (Choose the option to `Run Server Apps` for your system). If you plan to install tgstation-server as a Windows service, you should also ensure that your .NET Framework runtime version is >= v4.7.2 (Most modern systems have it by default. Download can be found on same page). Ensure that the `dotnet` executable file is in your system's `PATH` variable (or that of the user's that will be running the server), you can test this by opening a command prompt and running `dotnet --list-runtimes`.
+##### Installer
+
+If you don't have it installed already, download and install the [ASP .NET Core Runtime (>= v6.0)](https://dotnet.microsoft.com/download/dotnet/6.0). Ensure that the `dotnet` executable file is in your system's `PATH` variable (or that of the user's that will be running the server). You can test this by opening a command prompt and running `dotnet --list-runtimes`.
+
+You should also ensure that your .NET Framework runtime version is >= v4.7.2. Most modern systems have it by default so this isn't much of a concern. If, somehow, you don't have it installed, it can be downloaded [here](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472).
+
+[Download the latest release .msi](https://github.com/tgstation/tgstation-server/releases/latest). Executing it will take you through the process of installing and configuring your server.
+
+##### winget
+
+If you have [winget]() installed. You can easily install the latest version of tgstation-server (provided Microsoft has approved the most recent package manifest).
+
+Simply run the following command:
+```sh
+winget install tgstation-server
+```
+
+If you get an error like `This file does not have an app associated with it for performing this action.` run with the `--silent` flag:
+```sh
+winget install tgstation-server --silent
+```
+
+You won't be prompted to run the setup wizard. However, you can do so immediately after via the shortcut placed on your desktop.
+
+NOTE:
+
+`winget` should, theoretically, install the ASP .NET Core 6.0 Runtime as a pre-reqiusite. At the time of this writing, this functionality is untested (TODO). If the runtime isn't automatically installed for you, see above or below for steps on how to download and install it manually.
+
+##### Manual
+
+If you don't have it installed already, download and install the [ASP .NET Core Runtime (>= v6.0)](https://dotnet.microsoft.com/download/dotnet/6.0). Ensure that the `dotnet` executable file is in your system's `PATH` variable (or that of the user's that will be running the server). You can test this by opening a command prompt and running `dotnet --list-runtimes`.
+
+You should also ensure that your .NET Framework runtime version is >= v4.7.2. Most modern systems have it by default so this isn't much of a concern. If, somehow, you don't have it installed, it can be downloaded [here](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472).
[Download the latest release .zip](https://github.com/tgstation/tgstation-server/releases/latest). You probably want the `ServerService` package. Choose `ServerConsole` if you prefer not to use the Windows service.
@@ -36,7 +68,7 @@ If you wish to install the TGS as a service, run `Tgstation.Server.Host.Service.
Should you want a clean start, be sure to first uninstall the service by running `Tgstation.Server.Host.Service.exe -u` from the command line.
-If using the console version, run ./tgs.bat in the root of the installation directory. Ctrl+C will close the server, terminating all live game instances.
+If using the console version, run `./tgs.bat` in the root of the installation directory. Ctrl+C will close the server, terminating all live game instances.
#### Linux
diff --git a/src/Tgstation.Server.Host/manifest.xml b/build/manifest.xml
similarity index 97%
rename from src/Tgstation.Server.Host/manifest.xml
rename to build/manifest.xml
index 5173bf83318..05ddda9c2af 100644
--- a/src/Tgstation.Server.Host/manifest.xml
+++ b/build/manifest.xml
@@ -1,11 +1,11 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/package/deb/appsettings.Initial.yml b/build/package/appsettings.Initial.yml
similarity index 100%
rename from build/package/deb/appsettings.Initial.yml
rename to build/package/appsettings.Initial.yml
diff --git a/build/package/winget/Tgstation.Server.Host.Service.Configure/Program.cs b/build/package/winget/Tgstation.Server.Host.Service.Configure/Program.cs
new file mode 100644
index 00000000000..c55662074bc
--- /dev/null
+++ b/build/package/winget/Tgstation.Server.Host.Service.Configure/Program.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+
+using var process = new Process();
+
+var installDir = Path.GetDirectoryName(
+ Assembly.GetExecutingAssembly().Location)!;
+
+process.StartInfo.WorkingDirectory = installDir;
+process.StartInfo.FileName = Path.Combine(
+ process.StartInfo.WorkingDirectory,
+ "Tgstation.Server.Host.Service.exe");
+
+/*
+https://www.roelvanlisdonk.nl/2009/11/13/how-to-detect-unattended-installation-msiexec-quit-or-qn-in-youre-custom-action-with-c/
+msiUILevelNoChange 0 Does not change UI level.
+msiUILevelDefault 1 Uses default UI level.
+msiUILevelNone 2 Silent installation.
+msiUILevelBasic 3 Simple progress and error handling.
+msiUILevelReduced 4 Authored UI and wizard dialog boxes suppressed.
+msiUILevelFull 5 Authored UI with wizards, progress, and errors.
+msiUILevelHideCancel 32 If combined with the msiUILevelBasic value, the installer shows progress dialog boxes but does not display a Cancel button on the dialog box to prevent users from canceling the installation.
+msiUILevelProgressOnly 64 If combined with the msiUILevelBasic value, the installer displays progress dialog boxes but does not display any modal dialog boxes or error dialog boxes.
+msiUILevelEndDialog 128 If combined with any above value, the installer displays a modal dialog box at the end of a successful installation or if there has been an error. No dialog box is displayed if the user cancels.
+*/
+var uiLevel = Int32.Parse(args[0]);
+
+// leave it to MS to overcomplicate things
+var interactive = uiLevel switch
+{
+ 0 or 1 or 4 or 5 => true,
+ _ => false,
+};
+
+var silent = uiLevel == 2;
+
+var uninstall = args
+ .Any(arg => arg.Equals("--uninstall", StringComparison.OrdinalIgnoreCase));
+
+var shortcut = uiLevel == 42069;
+
+process.StartInfo.Arguments = uninstall
+ ? "-u"
+ : shortcut
+ ? "-c"
+ : $"-i -f {(interactive ? "-c" : String.Empty)} {(silent ? "-s" : String.Empty)}";
+
+process.Start();
+
+await process.WaitForExitAsync(CancellationToken.None); // DCT: None available
+
+foreach (var installLogFile in Directory.EnumerateFiles(installDir, "*.log"))
+ File.Delete(installLogFile);
+
+if (uninstall)
+{
+ Directory.Delete(
+ Path.Combine(installDir, "lib"),
+ true);
+}
+
+if(shortcut && process.ExitCode == 0)
+{
+ Console.WriteLine();
+ Console.Write("tgstation-server is now configured. Would you like to (re)start the service? (Y/n): ");
+ var keyInfo = Console.ReadKey();
+ Console.WriteLine();
+ if (keyInfo.Key == ConsoleKey.Y || keyInfo.Key == ConsoleKey.Enter)
+ {
+ using (var stopService = new Process())
+ {
+ stopService.StartInfo.FileName = "sc";
+ stopService.StartInfo.Arguments = "stop tgstation-server";
+ stopService.Start();
+ await stopService.WaitForExitAsync(CancellationToken.None); // DCT: None available
+ }
+
+ using var startService = new Process();
+ startService.StartInfo.FileName = "sc";
+ startService.StartInfo.Arguments = "start tgstation-server";
+ startService.Start();
+ await startService.WaitForExitAsync(CancellationToken.None); // DCT: None available
+ }
+
+ Console.WriteLine("Press any key to exit this program...");
+ Console.ReadKey();
+ Console.WriteLine();
+}
+
+// returning non-zero can make the installation uninstallable, no thanks
+return uninstall ? 0 : process.ExitCode;
diff --git a/build/package/winget/Tgstation.Server.Host.Service.Configure/Tgstation.Server.Host.Service.Configure.csproj b/build/package/winget/Tgstation.Server.Host.Service.Configure/Tgstation.Server.Host.Service.Configure.csproj
new file mode 100644
index 00000000000..15716db0842
--- /dev/null
+++ b/build/package/winget/Tgstation.Server.Host.Service.Configure/Tgstation.Server.Host.Service.Configure.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ ../../../manifest.xml
+ ../../../tgs.ico
+
+
+
+
+
+
diff --git a/build/package/winget/Tgstation.Server.Host.Service.Msi/Tgstation.Server.Host.Service.Msi.vdproj b/build/package/winget/Tgstation.Server.Host.Service.Msi/Tgstation.Server.Host.Service.Msi.vdproj
new file mode 100644
index 00000000000..8ea9bf88b6a
--- /dev/null
+++ b/build/package/winget/Tgstation.Server.Host.Service.Msi/Tgstation.Server.Host.Service.Msi.vdproj
@@ -0,0 +1,1042 @@
+"DeployProject"
+{
+"VSVersion" = "3:800"
+"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}"
+"IsWebType" = "8:FALSE"
+"ProjectName" = "8:Tgstation.Server.Host.Service.Msi"
+"LanguageId" = "3:1033"
+"CodePage" = "3:1252"
+"UILanguageId" = "3:1033"
+"SccProjectName" = "8:"
+"SccLocalPath" = "8:"
+"SccAuxPath" = "8:"
+"SccProvider" = "8:"
+ "Hierarchy"
+ {
+ "Entry"
+ {
+ "MsmKey" = "8:_11E0E9B45549402D92B039FCCD0783B8"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_137A5E0CCDBF4E4A9549C03C74D3988C"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_415514E8CEF94645B44E5665C5B9D8F5"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_4F14AB1FF9E24F9EBCC13DECAD76B526"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_8F775F391C394240882C33EF95C853E3"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_B0A2BC595A554F188D336702686A821E"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_E3B62CFD59F3484BACCB88E834824355"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ "Entry"
+ {
+ "MsmKey" = "8:_E9F7402DCE77463F9B7319647D3C16F2"
+ "OwnerKey" = "8:_UNDEFINED"
+ "MsmSig" = "8:_UNDEFINED"
+ }
+ }
+ "Configurations"
+ {
+ "Release"
+ {
+ "DisplayName" = "8:Release"
+ "IsDebugOnly" = "11:FALSE"
+ "IsReleaseOnly" = "11:TRUE"
+ "OutputFilename" = "8:Release\\tgstation-server.msi"
+ "PackageFilesAs" = "3:2"
+ "PackageFileSize" = "3:-2147483648"
+ "CabType" = "3:1"
+ "Compression" = "3:3"
+ "SignOutput" = "11:FALSE"
+ "CertificateFile" = "8:"
+ "PrivateKeyFile" = "8:"
+ "TimeStampServer" = "8:"
+ "InstallerBootstrapper" = "3:2"
+ "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
+ {
+ "Enabled" = "11:TRUE"
+ "PromptEnabled" = "11:TRUE"
+ "PrerequisitesLocation" = "2:1"
+ "Url" = "8:"
+ "ComponentsUrl" = "8:"
+ "Items"
+ {
+ "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2"
+ {
+ "Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)"
+ "ProductCode" = "8:.NETFramework,Version=v4.7.2"
+ }
+ "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.NetCore.CoreRuntime.6.0.x64"
+ {
+ "Name" = "8:.NET Runtime 6.0.18 (x64)"
+ "ProductCode" = "8:Microsoft.NetCore.CoreRuntime.6.0.x64"
+ }
+ }
+ }
+ }
+ }
+ "Deployable"
+ {
+ "CustomAction"
+ {
+ "{4AA51A2D-7D85-4A59-BA75-B0809FC8B380}:_A53906ED15374112AC84662B6F2E8041"
+ {
+ "Name" = "8:Publish Items from Tgstation.Server.Host.Service.Configure (Active)"
+ "Condition" = "8:"
+ "Object" = "8:_E9F7402DCE77463F9B7319647D3C16F2"
+ "FileType" = "3:2"
+ "InstallAction" = "3:1"
+ "Arguments" = "8:[UILevel]"
+ "EntryPoint" = "8:"
+ "Sequence" = "3:1"
+ "Identifier" = "8:_B09766E4_1B68_49DE_9726_68FD609D967B"
+ "InstallerClass" = "11:FALSE"
+ "CustomActionData" = "8:"
+ "Run64Bit" = "11:TRUE"
+ }
+ "{4AA51A2D-7D85-4A59-BA75-B0809FC8B380}:_A953E29077C84B36ADF6660A83C8B004"
+ {
+ "Name" = "8:Publish Items from Tgstation.Server.Host.Service.Configure (Active)"
+ "Condition" = "8:"
+ "Object" = "8:_E9F7402DCE77463F9B7319647D3C16F2"
+ "FileType" = "3:2"
+ "InstallAction" = "3:4"
+ "Arguments" = "8:[UILevel] --uninstall"
+ "EntryPoint" = "8:"
+ "Sequence" = "3:1"
+ "Identifier" = "8:_6B8510E1_5DAE_4023_AD93_B9DD1AC65C45"
+ "InstallerClass" = "11:FALSE"
+ "CustomActionData" = "8:"
+ "Run64Bit" = "11:TRUE"
+ }
+ }
+ "DefaultFeature"
+ {
+ "Name" = "8:DefaultFeature"
+ "Title" = "8:"
+ "Description" = "8:"
+ }
+ "ExternalPersistence"
+ {
+ "LaunchCondition"
+ {
+ "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_C5FA609714B64925A18859A195267F9F"
+ {
+ "Name" = "8:.NET Core"
+ "Message" = "8:[VSDNETCOREMSG]"
+ "AllowLaterVersions" = "11:FALSE"
+ "InstallUrl" = "8:https://dotnet.microsoft.com/download/dotnet-core/[NetCoreVerMajorDotMinor]"
+ "IsNETCore" = "11:TRUE"
+ "Architecture" = "2:0"
+ "Runtime" = "2:0"
+ }
+ }
+ }
+ "File"
+ {
+ "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_137A5E0CCDBF4E4A9549C03C74D3988C"
+ {
+ "SourcePath" = "8:..\\..\\..\\..\\src\\Tgstation.Server.Host\\appsettings.yml"
+ "TargetName" = "8:appsettings.yml"
+ "Tag" = "8:"
+ "Folder" = "8:_B28C4FD80D0245E08AEDCFEECACB6493"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ }
+ "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4F14AB1FF9E24F9EBCC13DECAD76B526"
+ {
+ "SourcePath" = "8:..\\install_banner.jpg"
+ "TargetName" = "8:install_banner.jpg"
+ "Tag" = "8:"
+ "Folder" = "8:_EB2DCEE6D3F74230A9827AC9B6F47F53"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ }
+ "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8F775F391C394240882C33EF95C853E3"
+ {
+ "SourcePath" = "8:..\\install_banner.jpg"
+ "TargetName" = "8:install_banner.jpg"
+ "Tag" = "8:"
+ "Folder" = "8:_EB2DCEE6D3F74230A9827AC9B6F47F53"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ }
+ "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B0A2BC595A554F188D336702686A821E"
+ {
+ "SourcePath" = "8:..\\..\\..\\..\\LICENSE"
+ "TargetName" = "8:LICENSE"
+ "Tag" = "8:"
+ "Folder" = "8:_B28C4FD80D0245E08AEDCFEECACB6493"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:TRUE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ }
+ "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E3B62CFD59F3484BACCB88E834824355"
+ {
+ "SourcePath" = "8:..\\..\\appsettings.Initial.yml"
+ "TargetName" = "8:appsettings.Production.yml"
+ "Tag" = "8:"
+ "Folder" = "8:_B28C4FD80D0245E08AEDCFEECACB6493"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ }
+ }
+ "FileType"
+ {
+ }
+ "Folder"
+ {
+ "{3C67513D-01DD-4637-8A68-80971EB9504F}:_B28C4FD80D0245E08AEDCFEECACB6493"
+ {
+ "DefaultLocation" = "8:[ProgramFiles64Folder][Manufacturer]\\[ProductName]"
+ "Name" = "8:#1925"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:TARGETDIR"
+ "Folders"
+ {
+ "{9EF0B969-E518-4E46-987F-47570745A589}:_D8FD06A5721D4746BD1D087E6329F3CF"
+ {
+ "Name" = "8:lib"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:_1760E07222D34C3ABECB83B8D17A7256"
+ "Folders"
+ {
+ "{9EF0B969-E518-4E46-987F-47570745A589}:_44E17B6EBB30432E9D4FBB976D7E029A"
+ {
+ "Name" = "8:Default"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:_40C981E76FB44E748278A84D5E727464"
+ "Folders"
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+ "{1525181F-901A-416C-8A58-119130FE478E}:_BD1E6451115645479FB57AD1F0BB6A8B"
+ {
+ "Name" = "8:#1916"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:DesktopFolder"
+ "Folders"
+ {
+ }
+ }
+ "{1525181F-901A-416C-8A58-119130FE478E}:_D53B13F517CB437C874C9E216C3F8F5F"
+ {
+ "Name" = "8:#1937"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:CommonFiles64Folder"
+ "Folders"
+ {
+ }
+ }
+ "{994432C3-9487-495D-8656-3E829A8DBDDE}:_EB2DCEE6D3F74230A9827AC9B6F47F53"
+ {
+ "DefaultLocation" = "8:[TARGETDIR]"
+ "Name" = "8:Install Resources"
+ "AlwaysCreate" = "11:FALSE"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Property" = "8:NEWPROPERTY1"
+ "Folders"
+ {
+ }
+ }
+ }
+ "LaunchCondition"
+ {
+ }
+ "Locator"
+ {
+ }
+ "MsiBootstrapper"
+ {
+ "LangId" = "3:1033"
+ "RequiresElevation" = "11:FALSE"
+ }
+ "Product"
+ {
+ "Name" = "8:Microsoft Visual Studio"
+ "ProductName" = "8:tgstation-server"
+ "ProductCode" = "8:{D24887FA-3228-4509-B5F3-4E07E349F278}"
+ "PackageCode" = "8:{5740BC0C-02EE-42AB-8B50-BCCAF4AF0322}"
+ "UpgradeCode" = "8:{151FE9F8-72CF-48D5-8E55-B7FB6BA9693E}"
+ "AspNetVersion" = "8:4.0.30319.0"
+ "RestartWWWService" = "11:FALSE"
+ "RemovePreviousVersions" = "11:TRUE"
+ "DetectNewerInstalledVersion" = "11:TRUE"
+ "InstallAllUsers" = "11:TRUE"
+ "ProductVersion" = "8:22.47.5"
+ "Manufacturer" = "8:tgstation"
+ "ARPHELPTELEPHONE" = "8:"
+ "ARPHELPLINK" = "8:"
+ "Title" = "8:Tgstation.Server.Host.Service.Setup"
+ "Subject" = "8:"
+ "ARPCONTACT" = "8:Dominon/Cyberboss"
+ "Keywords" = "8:"
+ "ARPCOMMENTS" = "8:"
+ "ARPURLINFOABOUT" = "8:https://tgstation13.org"
+ "ARPPRODUCTICON" = "8:"
+ "ARPIconIndex" = "3:0"
+ "SearchPath" = "8:"
+ "UseSystemSearchPath" = "11:TRUE"
+ "TargetPlatform" = "3:1"
+ "PreBuildEvent" = "8:"
+ "PostBuildEvent" = "8:"
+ "RunPostBuildEvent" = "3:0"
+ }
+ "Registry"
+ {
+ "HKLM"
+ {
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_BB4EE4F5EF8A4C1BA6BAA85FE34E56C4"
+ {
+ "Name" = "8:Software"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_05C235158E3A4664B285EA29511EF02D"
+ {
+ "Name" = "8:[Manufacturer]"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ }
+ "HKCU"
+ {
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_0379B7F8F5504CDA9DB9B9D546DB606D"
+ {
+ "Name" = "8:Software"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_6E60244E84834632A09C938ACAAC308D"
+ {
+ "Name" = "8:[Manufacturer]"
+ "Condition" = "8:"
+ "AlwaysCreate" = "11:FALSE"
+ "DeleteAtUninstall" = "11:FALSE"
+ "Transitive" = "11:FALSE"
+ "Keys"
+ {
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ "Values"
+ {
+ }
+ }
+ }
+ }
+ "HKCR"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKU"
+ {
+ "Keys"
+ {
+ }
+ }
+ "HKPU"
+ {
+ "Keys"
+ {
+ }
+ }
+ }
+ "Sequences"
+ {
+ }
+ "Shortcut"
+ {
+ "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_86C54A96871E40B6B517685DB09F223A"
+ {
+ "Name" = "8:Configure and Start tgstation-server"
+ "Arguments" = "8:42069 "
+ "Description" = "8:Runs the TGS setup wizard and optionally restarts the Windows service"
+ "ShowCmd" = "3:1"
+ "IconIndex" = "3:0"
+ "Transitive" = "11:FALSE"
+ "Target" = "8:_E9F7402DCE77463F9B7319647D3C16F2"
+ "Folder" = "8:_BD1E6451115645479FB57AD1F0BB6A8B"
+ "WorkingFolder" = "8:_B28C4FD80D0245E08AEDCFEECACB6493"
+ "Icon" = "8:"
+ "Feature" = "8:"
+ }
+ }
+ "UserInterface"
+ {
+ "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_0E30589D83D5457EA1590BDA4DB93D03"
+ {
+ "UseDynamicProperties" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdBasicDialogs.wim"
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_109A5A97F789460AB73CDF166664A916"
+ {
+ "Name" = "8:#1902"
+ "Sequence" = "3:2"
+ "Attributes" = "3:3"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_76284EF5FA104F46A0644EE9513C0A4D"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Finished"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdAdminFinishedDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:2"
+ "Value" = "8:_8F775F391C394240882C33EF95C853E3"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_278559DEB3E24BBCAA1C9B3F68673761"
+ {
+ "Name" = "8:#1900"
+ "Sequence" = "3:1"
+ "Attributes" = "3:1"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_7CD912AA05C244CB8A903FBFD33E29A8"
+ {
+ "Sequence" = "3:300"
+ "DisplayName" = "8:Confirm Installation"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdConfirmDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:2"
+ "Value" = "8:_8F775F391C394240882C33EF95C853E3"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_B3748469032C440CA8C833C645EF67F9"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Welcome"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdWelcomeDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:2"
+ "Value" = "8:_8F775F391C394240882C33EF95C853E3"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "CopyrightWarning"
+ {
+ "Name" = "8:CopyrightWarning"
+ "DisplayName" = "8:#1002"
+ "Description" = "8:#1102"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1202"
+ "DefaultValue" = "8:#1202"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "Welcome"
+ {
+ "Name" = "8:Welcome"
+ "DisplayName" = "8:#1003"
+ "Description" = "8:#1103"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1203"
+ "DefaultValue" = "8:#1203"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_BE9B710186F946AC828F528A90F9B1CA"
+ {
+ "Sequence" = "3:200"
+ "DisplayName" = "8:Installation Folder"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdFolderDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:2"
+ "Value" = "8:_8F775F391C394240882C33EF95C853E3"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "InstallAllUsersVisible"
+ {
+ "Name" = "8:InstallAllUsersVisible"
+ "DisplayName" = "8:#1059"
+ "Description" = "8:#1159"
+ "Type" = "3:5"
+ "ContextData" = "8:1;True=1;False=0"
+ "Attributes" = "3:0"
+ "Setting" = "3:0"
+ "Value" = "3:1"
+ "DefaultValue" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_2C7325D993884C978B1A4381E1143564"
+ {
+ "Name" = "8:#1901"
+ "Sequence" = "3:2"
+ "Attributes" = "3:2"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_FB014E47DC3540A2AA6B4B1B109BDA09"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Progress"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdAdminProgressDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:2"
+ "Value" = "8:_8F775F391C394240882C33EF95C853E3"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "ShowProgress"
+ {
+ "Name" = "8:ShowProgress"
+ "DisplayName" = "8:#1009"
+ "Description" = "8:#1109"
+ "Type" = "3:5"
+ "ContextData" = "8:1;True=1;False=0"
+ "Attributes" = "3:0"
+ "Setting" = "3:0"
+ "Value" = "3:1"
+ "DefaultValue" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_34AD1EE11A4C483C8F39A6F57C055D1C"
+ {
+ "Name" = "8:#1900"
+ "Sequence" = "3:2"
+ "Attributes" = "3:1"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_0C069DDECE324687A9F07480971F4EA1"
+ {
+ "Sequence" = "3:200"
+ "DisplayName" = "8:Installation Folder"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdAdminFolderDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:2"
+ "Value" = "8:_8F775F391C394240882C33EF95C853E3"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_566942A0B14E44D2ABECDB1CCA6B4229"
+ {
+ "Sequence" = "3:300"
+ "DisplayName" = "8:Confirm Installation"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdAdminConfirmDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:2"
+ "Value" = "8:_8F775F391C394240882C33EF95C853E3"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_CDECB4E7DDE84A4DB72B528A15D01E47"
+ {
+ "Sequence" = "3:110"
+ "DisplayName" = "8:Welcome"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:2"
+ "Value" = "8:_8F775F391C394240882C33EF95C853E3"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "CopyrightWarning"
+ {
+ "Name" = "8:CopyrightWarning"
+ "DisplayName" = "8:#1002"
+ "Description" = "8:#1102"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1202"
+ "DefaultValue" = "8:#1202"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "Welcome"
+ {
+ "Name" = "8:Welcome"
+ "DisplayName" = "8:#1003"
+ "Description" = "8:#1103"
+ "Type" = "3:3"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:1"
+ "Value" = "8:#1203"
+ "DefaultValue" = "8:#1203"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_C1FAAD9180D249AE930209CFFDE47E92"
+ {
+ "Name" = "8:#1902"
+ "Sequence" = "3:1"
+ "Attributes" = "3:3"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_F066076B6F3F439D9B70A2243DCC8D99"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Finished"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdFinishedDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:2"
+ "Value" = "8:_8F775F391C394240882C33EF95C853E3"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "UpdateText"
+ {
+ "Name" = "8:UpdateText"
+ "DisplayName" = "8:#1058"
+ "Description" = "8:#1158"
+ "Type" = "3:15"
+ "ContextData" = "8:"
+ "Attributes" = "3:0"
+ "Setting" = "3:2"
+ "Value" = "8:You can now start tgstation-server from your Services control panel. Press Win+R and enter 'services.msc' to access it. Then navigate to http://localhost: to manage your server."
+ "DefaultValue" = "8:#1258"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_CDC222C0F1734F22A35CE4BE55CD389D"
+ {
+ "UseDynamicProperties" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdUserInterface.wim"
+ }
+ "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_E2FF183010DC4AD5868B1B6BB4835C7F"
+ {
+ "Name" = "8:#1901"
+ "Sequence" = "3:1"
+ "Attributes" = "3:2"
+ "Dialogs"
+ {
+ "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_9C81E7707FD24FA98CE1C7DAAB793AB6"
+ {
+ "Sequence" = "3:100"
+ "DisplayName" = "8:Progress"
+ "UseDynamicProperties" = "11:TRUE"
+ "IsDependency" = "11:FALSE"
+ "SourcePath" = "8:\\VsdProgressDlg.wid"
+ "Properties"
+ {
+ "BannerBitmap"
+ {
+ "Name" = "8:BannerBitmap"
+ "DisplayName" = "8:#1001"
+ "Description" = "8:#1101"
+ "Type" = "3:8"
+ "ContextData" = "8:Bitmap"
+ "Attributes" = "3:4"
+ "Setting" = "3:2"
+ "Value" = "8:_8F775F391C394240882C33EF95C853E3"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ "ShowProgress"
+ {
+ "Name" = "8:ShowProgress"
+ "DisplayName" = "8:#1009"
+ "Description" = "8:#1109"
+ "Type" = "3:5"
+ "ContextData" = "8:1;True=1;False=0"
+ "Attributes" = "3:0"
+ "Setting" = "3:0"
+ "Value" = "3:1"
+ "DefaultValue" = "3:1"
+ "UsePlugInResources" = "11:TRUE"
+ }
+ }
+ }
+ }
+ }
+ }
+ "MergeModule"
+ {
+ }
+ "ProjectOutput"
+ {
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_11E0E9B45549402D92B039FCCD0783B8"
+ {
+ "SourcePath" = "8:..\\..\\..\\..\\src\\Tgstation.Server.Host\\obj\\Release\\net6.0\\apphost.exe"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_44E17B6EBB30432E9D4FBB976D7E029A"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:PublishItems"
+ "OutputProjectGuid" = "8:{2B69AD6D-2B5A-4023-8EAD-0BD1B18E028A}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ "ExcludeFilter" = "8:appsettings.yml"
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_415514E8CEF94645B44E5665C5B9D8F5"
+ {
+ "SourcePath" = "8:..\\..\\..\\..\\src\\Tgstation.Server.Api\\bin\\Release\\netstandard2.0\\Tgstation.Server.Api.xml"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_44E17B6EBB30432E9D4FBB976D7E029A"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:Documentation"
+ "OutputProjectGuid" = "8:{8B4A208D-A48A-4A5D-8B94-E2661138865D}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_5222E155071449818AC7AD899B0BD0EE"
+ {
+ "SourcePath" = "8:"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_44E17B6EBB30432E9D4FBB976D7E029A"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:ContentFiles"
+ "OutputProjectGuid" = "8:{2B69AD6D-2B5A-4023-8EAD-0BD1B18E028A}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ "ExcludeFilter" = "8:appsettings.yml"
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_B2B80DADC2EA4646A8E8E8E54F2AE2EE"
+ {
+ "SourcePath" = "8:"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_B28C4FD80D0245E08AEDCFEECACB6493"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:TRUE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:PublishItems"
+ "OutputProjectGuid" = "8:{29927416-3B78-49A7-A560-5CCAA638B6B4}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_E9F7402DCE77463F9B7319647D3C16F2"
+ {
+ "SourcePath" = "8:..\\Tgstation.Server.Host.Service.Configure\\obj\\Release\\net6.0\\apphost.exe"
+ "TargetName" = "8:"
+ "Tag" = "8:"
+ "Folder" = "8:_B28C4FD80D0245E08AEDCFEECACB6493"
+ "Condition" = "8:"
+ "Transitive" = "11:FALSE"
+ "Vital" = "11:TRUE"
+ "ReadOnly" = "11:FALSE"
+ "Hidden" = "11:FALSE"
+ "System" = "11:FALSE"
+ "Permanent" = "11:FALSE"
+ "SharedLegacy" = "11:FALSE"
+ "PackageAs" = "3:1"
+ "Register" = "3:1"
+ "Exclude" = "11:FALSE"
+ "IsDependency" = "11:FALSE"
+ "IsolateTo" = "8:"
+ "ProjectOutputGroupRegister" = "3:1"
+ "OutputConfiguration" = "8:"
+ "OutputGroupCanonicalName" = "8:PublishItems"
+ "OutputProjectGuid" = "8:{6CC73878-8C37-4ACC-ADAA-A60EBDBC2315}"
+ "ShowKeyOutput" = "11:TRUE"
+ "ExcludeFilters"
+ {
+ }
+ }
+ }
+ }
+}
diff --git a/build/package/winget/build_package.ps1 b/build/package/winget/build_package.ps1
new file mode 100644
index 00000000000..940d1aad621
--- /dev/null
+++ b/build/package/winget/build_package.ps1
@@ -0,0 +1,21 @@
+$currentCommit=git rev-parse HEAD
+
+Remove-Item -Recurse -Force packaging
+
+git worktree remove -f packaging
+
+$ErrorActionPreference="Stop"
+
+git worktree add -f packaging $currentCommit
+cd packaging
+Remove-Item -Recurse -Force .git
+
+[XML]$versionXML = Get-Content build/Version.props
+$tgsVersion = $versionXML.Project.PropertyGroup.TgsCoreVersion
+
+(Get-Content build/package/winget/Tgstation.Server.Host.Service.Msi/Tgstation.Server.Host.Service.Msi.vdproj).Replace('22.47.5', $tgsVersion) | Set-Content build/package/winget/Tgstation.Server.Host.Service.Msi/Tgstation.Server.Host.Service.Msi.vdproj
+
+# We make _some_ assumptions
+DevEnv tgstation-server.sln /Project build/package/winget/Tgstation.Server.Host.Service.Msi/Tgstation.Server.Host.Service.Msi.vdproj /build Release
+
+cd ..
diff --git a/build/package/winget/install_banner.jpg b/build/package/winget/install_banner.jpg
new file mode 100644
index 00000000000..4bbe3f134ca
Binary files /dev/null and b/build/package/winget/install_banner.jpg differ
diff --git a/build/package/winget/manifest/Tgstation.Server.installer.yaml b/build/package/winget/manifest/Tgstation.Server.installer.yaml
new file mode 100644
index 00000000000..b70a79ec822
--- /dev/null
+++ b/build/package/winget/manifest/Tgstation.Server.installer.yaml
@@ -0,0 +1,28 @@
+# Created using wingetcreate 1.2.6.0
+# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json
+
+PackageIdentifier: Tgstation.Server
+PackageVersion: 0.0.0 # Set before publish by wingetcreate
+Installers:
+- InstallerUrl: https://github.com/tgstation/tgstation-server/releases/download/tgstation-server-v0.0.0/tgstation-server.msi # Set before publish by wingetcreate
+ InstallerLocale: en-US
+ Architecture: x64
+ InstallerType: msi
+ Scope: machine
+ InstallerSha256: F749672C1BDBAC8CD8AEF7352B97E54C21CF389D798D0ED245CA75EC72521460
+ InstallModes:
+ - interactive
+ - silent
+ UpgradeBehavior: uninstallPrevious
+ ProductCode: '{D24887FA-3228-4509-B5F3-4E07E349F278}'
+ RequireExplicitUpgrade: true
+ UnsupportedOSArchitectures:
+ - arm
+ - arm64
+ ElevationRequirement: elevationRequired
+ Dependencies:
+ PackageDependencies:
+ - PackageIdentifier: Microsoft.DotNet.AspNetCore.6
+ ReleaseDate: 2023-06-24
+ManifestType: installer
+ManifestVersion: 1.4.0
diff --git a/build/package/winget/manifest/Tgstation.Server.locale.en-US.yaml b/build/package/winget/manifest/Tgstation.Server.locale.en-US.yaml
new file mode 100644
index 00000000000..827c431db89
--- /dev/null
+++ b/build/package/winget/manifest/Tgstation.Server.locale.en-US.yaml
@@ -0,0 +1,12 @@
+# Created using wingetcreate 1.2.6.0
+# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json
+
+PackageIdentifier: Tgstation.Server
+PackageVersion: 0.0.0 # Set before publish by wingetcreate
+PackageLocale: en-US
+Publisher: /tg/station 13
+PackageName: tgstation-server
+License: AGPL-3.0
+ShortDescription: A production scale tool for BYOND server management
+ManifestType: defaultLocale
+ManifestVersion: 1.4.0
diff --git a/build/package/winget/manifest/Tgstation.Server.yaml b/build/package/winget/manifest/Tgstation.Server.yaml
new file mode 100644
index 00000000000..e543e57585e
--- /dev/null
+++ b/build/package/winget/manifest/Tgstation.Server.yaml
@@ -0,0 +1,8 @@
+# Created using wingetcreate 1.2.6.0
+# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json
+
+PackageIdentifier: Tgstation.Server
+PackageVersion: 0.0.0 # Set before publish by wingetcreate
+DefaultLocale: en-US
+ManifestType: version
+ManifestVersion: 1.4.0
diff --git a/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj b/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj
index b32fe038fd4..851f31fb19c 100644
--- a/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj
+++ b/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj
@@ -9,6 +9,7 @@
true
../../build/analyzers.ruleset
bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml
+ ../../build/tgs.ico
diff --git a/src/Tgstation.Server.Host.Service/Program.cs b/src/Tgstation.Server.Host.Service/Program.cs
index e1e6e2f9929..f0e70eb10bf 100644
--- a/src/Tgstation.Server.Host.Service/Program.cs
+++ b/src/Tgstation.Server.Host.Service/Program.cs
@@ -43,6 +43,18 @@ sealed class Program
[Option(ShortName = "i")]
public bool Install { get; set; }
+ ///
+ /// The --force or -f option.
+ ///
+ [Option(ShortName = "f")]
+ public bool Force { get; set; }
+
+ ///
+ /// The --silent or -s option.
+ ///
+ [Option(ShortName = "s")]
+ public bool Silent { get; set; }
+
///
/// The --configure or -c option.
///
@@ -82,14 +94,16 @@ static bool IsAdministrator()
///
/// Attempt to install the TGS Service.
///
- static void RunServiceInstall()
+ void RunServiceInstall()
{
// First check if the service already exists
- if (Environment.UserInteractive)
+ if (Force || Environment.UserInteractive)
foreach (ServiceController sc in ServiceController.GetServices())
if (sc.ServiceName == "tgstation-server" || sc.ServiceName == "tgstation-server-4")
{
- DialogResult result = MessageBox.Show($"You already have another TGS service installed ({sc.ServiceName}). Would you like to uninstall it now? Pressing \"No\" will cancel this install.", "TGS Service", MessageBoxButtons.YesNo);
+ DialogResult result = !Force
+ ? MessageBox.Show($"You already have another TGS service installed ({sc.ServiceName}). Would you like to uninstall it now? Pressing \"No\" will cancel this install.", "TGS Service", MessageBoxButtons.YesNo)
+ : DialogResult.Yes;
if (result != DialogResult.Yes)
return; // is this needed after exit?
@@ -103,6 +117,10 @@ static void RunServiceInstall()
// And remove it
using var serviceInstaller = new ServiceInstaller();
serviceInstaller.Context = new InstallContext($"old-{sc.ServiceName}-uninstall.log", null);
+
+ if (Silent)
+ serviceInstaller.Context.Parameters["LogToConsole"] = false.ToString();
+
serviceInstaller.ServiceName = sc.ServiceName;
serviceInstaller.Uninstall(null);
}
@@ -112,8 +130,10 @@ static void RunServiceInstall()
processInstaller.Account = ServiceAccount.LocalSystem;
installer.Context = new InstallContext("tgs-install.log", new string[] { String.Format(CultureInfo.InvariantCulture, "/assemblypath={0}", Assembly.GetEntryAssembly().Location) });
- installer.Description = "/tg/station 13 server running as a windows service";
- installer.DisplayName = "/tg/station server";
+ if (Silent)
+ installer.Context.Parameters["LogToConsole"] = false.ToString();
+ installer.Description = "tgstation-server running as a windows service";
+ installer.DisplayName = "tgstation-server";
installer.StartType = ServiceStartMode.Automatic;
installer.ServicesDependedOn = new string[] { "Tcpip", "Dhcp", "Dnscache" };
installer.ServiceName = ServerService.Name;
@@ -149,7 +169,7 @@ public async Task OnExecuteAsync()
{
UseShellExecute = true,
Verb = "runas",
- Arguments = String.Format(CultureInfo.InvariantCulture, "{0} {1}", Install ? "-i" : Uninstall ? "-u" : String.Empty, Configure ? "-c" : String.Empty),
+ Arguments = $"{(Install ? "-i" : Uninstall ? "-u" : String.Empty)} {(Configure ? "-c" : String.Empty)} {(Force ? "-f" : String.Empty)}",
FileName = exe,
WorkingDirectory = Environment.CurrentDirectory,
};
@@ -165,16 +185,16 @@ public async Task OnExecuteAsync()
RunServiceInstall();
- if (Configure)
- {
+ if (Configure && !Silent)
Console.WriteLine("For this first run we'll launch the console runner so you may use the setup wizard.");
- Console.WriteLine("If it starts successfully, feel free to close it and then start the service from the Windows control panel.");
- }
}
else if (Uninstall)
using (var installer = new ServiceInstaller())
{
installer.Context = new InstallContext("tgs-uninstall.log", null);
+ if (Silent)
+ installer.Context.Parameters["LogToConsole"] = false.ToString();
+
installer.ServiceName = ServerService.Name;
installer.Uninstall(null);
}
@@ -185,11 +205,23 @@ public async Task OnExecuteAsync()
}
if (Configure)
+ await RunConfigure(CancellationToken.None); // DCT: None available
+ }
+
+ ///
+ /// Runs the host application with the setup wizard.
+ ///
+ /// The for the operation.
+ /// A representing the running operation.
+ async Task RunConfigure(CancellationToken cancellationToken)
+ {
+ using var loggerFactory = LoggerFactory.Create(builder =>
{
- using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
- await WatchdogFactory.CreateWatchdog(loggerFactory)
- .RunAsync(true, Array.Empty(), CancellationToken.None); // DCT: None available
- }
+ if (!Silent)
+ builder.AddConsole();
+ });
+ await WatchdogFactory.CreateWatchdog(loggerFactory)
+ .RunAsync(true, Array.Empty(), cancellationToken);
}
}
}
diff --git a/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj b/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj
index 83630ddc2e0..d8200f9ecc1 100644
--- a/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj
+++ b/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj
@@ -9,6 +9,7 @@
true
../../build/analyzers.ruleset
bin/$(Configuration)/$(TargetFramework)/$(RuntimeIdentifier)/$(AssemblyName).xml
+ ../../build/tgs.ico
diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
index a9e8b356526..6c63de35d2d 100644
--- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
+++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
@@ -9,6 +9,11 @@
../../build/analyzers.ruleset
bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).xml
API1000
+ ClientApp/node_modules
+ ClientApp/node_modules/.install-stamp
+ Linux
+ ..\..
+ ../../build/manifest.xml
@@ -16,14 +21,6 @@
-
- ClientApp/node_modules
- ClientApp/node_modules/.install-stamp
- Linux
- ..\..
- manifest.xml
-
-
$(DefineConstants);WATCHDOG_FREE_RESTART
@@ -86,7 +83,6 @@
- all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -117,7 +113,6 @@
- all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -143,15 +138,11 @@
-
-
-
-
-
-
-
+
+
+
diff --git a/tgstation-server.sln b/tgstation-server.sln
index 8c700d5f296..807b3e708e1 100644
--- a/tgstation-server.sln
+++ b/tgstation-server.sln
@@ -30,6 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{6FF654E6
build\coverlet.runsettings = build\coverlet.runsettings
build\Dockerfile = build\Dockerfile
build\GenerateMigrations.sh = build\GenerateMigrations.sh
+ build\manifest.xml = build\manifest.xml
build\NugetCommon.props = build\NugetCommon.props
build\OpenApiValidationSettings.json = build\OpenApiValidationSettings.json
build\stylecop.json = build\stylecop.json
@@ -201,11 +202,14 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tgstation.Server.Common", "src\Tgstation.Server.Common\Tgstation.Server.Common.csproj", "{70CD9A98-D31A-44A4-81D1-D02764CEEEFD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "package", "package", "{2648A85F-61AE-428E-95E1-66D06C7A3768}"
+ ProjectSection(SolutionItems) = preProject
+ build\package\appsettings.Initial.yml = build\package\appsettings.Initial.yml
+ EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deb", "deb", "{457A1F89-6201-4430-BCC6-2F4438A54B9E}"
ProjectSection(SolutionItems) = preProject
- build\package\deb\appsettings.Initial.yml = build\package\deb\appsettings.Initial.yml
build\package\deb\build_package.sh = build\package\deb\build_package.sh
+ build\package\deb\install_artifacts.sh = build\package\deb\install_artifacts.sh
build\package\deb\MakeInstall = build\package\deb\MakeInstall
build\package\deb\tgs-configure = build\package\deb\tgs-configure
build\package\deb\wrap_gpg.sh = build\package\deb\wrap_gpg.sh
@@ -216,6 +220,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "debian", "debian", "{08E7C6
build\package\deb\debian\changelog = build\package\deb\debian\changelog
build\package\deb\debian\control = build\package\deb\debian\control
build\package\deb\debian\copyright = build\package\deb\debian\copyright
+ build\package\deb\install_artifacts.sh = build\package\deb\install_artifacts.sh
build\package\deb\debian\links = build\package\deb\debian\links
build\package\deb\debian\postinst = build\package\deb\debian\postinst
build\package\deb\debian\prerm = build\package\deb\debian\prerm
@@ -227,6 +232,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "upstream", "upstream", "{B4
build\package\deb\debian\upstream\metadata = build\package\deb\debian\upstream\metadata
EndProjectSection
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "winget", "winget", "{506B9092-AF88-4DA2-84FD-C11646B695B0}"
+ ProjectSection(SolutionItems) = preProject
+ build\package\winget\build_package.ps1 = build\package\winget\build_package.ps1
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tgstation.Server.Host.Service.Configure", "build\package\winget\Tgstation.Server.Host.Service.Configure\Tgstation.Server.Host.Service.Configure.csproj", "{6CC73878-8C37-4ACC-ADAA-A60EBDBC2315}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "manifest", "manifest", "{3F141E03-6ABB-46A8-AA24-1B4B6814E58F}"
+ ProjectSection(SolutionItems) = preProject
+ build\package\winget\manifest\Tgstation.Server.installer.yaml = build\package\winget\manifest\Tgstation.Server.installer.yaml
+ build\package\winget\manifest\Tgstation.Server.locale.en-US.yaml = build\package\winget\manifest\Tgstation.Server.locale.en-US.yaml
+ build\package\winget\manifest\Tgstation.Server.yaml = build\package\winget\manifest\Tgstation.Server.yaml
+ EndProjectSection
+EndProject
+Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Tgstation.Server.Host.Service.Msi", "build\package\winget\Tgstation.Server.Host.Service.Msi\Tgstation.Server.Host.Service.Msi.vdproj", "{73F75AAF-7885-490A-8262-B5C852AC8A47}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -383,6 +404,19 @@ Global
{70CD9A98-D31A-44A4-81D1-D02764CEEEFD}.Release|Any CPU.Build.0 = Release|Any CPU
{70CD9A98-D31A-44A4-81D1-D02764CEEEFD}.ReleaseNoService|Any CPU.ActiveCfg = Release|Any CPU
{70CD9A98-D31A-44A4-81D1-D02764CEEEFD}.ReleaseNoService|Any CPU.Build.0 = Release|Any CPU
+ {6CC73878-8C37-4ACC-ADAA-A60EBDBC2315}.Debug|Any CPU.ActiveCfg = Release|Any CPU
+ {6CC73878-8C37-4ACC-ADAA-A60EBDBC2315}.DebugNoService|Any CPU.ActiveCfg = Release|Any CPU
+ {6CC73878-8C37-4ACC-ADAA-A60EBDBC2315}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CC73878-8C37-4ACC-ADAA-A60EBDBC2315}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6CC73878-8C37-4ACC-ADAA-A60EBDBC2315}.ReleaseNoService|Any CPU.ActiveCfg = Release|Any CPU
+ {73F75AAF-7885-490A-8262-B5C852AC8A47}.Debug|Any CPU.ActiveCfg = Release
+ {73F75AAF-7885-490A-8262-B5C852AC8A47}.Debug|Any CPU.Build.0 = Release
+ {73F75AAF-7885-490A-8262-B5C852AC8A47}.DebugNoService|Any CPU.ActiveCfg = Release
+ {73F75AAF-7885-490A-8262-B5C852AC8A47}.DebugNoService|Any CPU.Build.0 = Release
+ {73F75AAF-7885-490A-8262-B5C852AC8A47}.Release|Any CPU.ActiveCfg = Release
+ {73F75AAF-7885-490A-8262-B5C852AC8A47}.Release|Any CPU.Build.0 = Release
+ {73F75AAF-7885-490A-8262-B5C852AC8A47}.ReleaseNoService|Any CPU.ActiveCfg = Release
+ {73F75AAF-7885-490A-8262-B5C852AC8A47}.ReleaseNoService|Any CPU.Build.0 = Release
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -415,6 +449,10 @@ Global
{457A1F89-6201-4430-BCC6-2F4438A54B9E} = {2648A85F-61AE-428E-95E1-66D06C7A3768}
{08E7C650-A447-4DE2-974E-ED123B50F8D6} = {457A1F89-6201-4430-BCC6-2F4438A54B9E}
{B4B5570C-8071-46DE-BB55-64C13480C606} = {08E7C650-A447-4DE2-974E-ED123B50F8D6}
+ {506B9092-AF88-4DA2-84FD-C11646B695B0} = {2648A85F-61AE-428E-95E1-66D06C7A3768}
+ {6CC73878-8C37-4ACC-ADAA-A60EBDBC2315} = {506B9092-AF88-4DA2-84FD-C11646B695B0}
+ {3F141E03-6ABB-46A8-AA24-1B4B6814E58F} = {506B9092-AF88-4DA2-84FD-C11646B695B0}
+ {73F75AAF-7885-490A-8262-B5C852AC8A47} = {506B9092-AF88-4DA2-84FD-C11646B695B0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DFD36C95-3E49-41C7-ACDB-86BAF5B18A79}