From b3951a46fb5ca75d152cd6942e66d57eab6b87c4 Mon Sep 17 00:00:00 2001
From: Scott Darnell <20483794+aeloros@users.noreply.github.com>
Date: Fri, 30 Oct 2020 20:50:59 -0700
Subject: [PATCH] User/aeloros/get args (#268)
* Initial template for the AppLifecycle object and it's tests.
* Initial set of components
* Basic Launch and Protocol support
* Move registration methods to new runtimeclass. Stub out new ancillary interfaces on the event args classes.
* Remove samples from the project dll.
* Remove work for file type associations for now.
Remove shared samples completely.
* Block registration for packaged apps (they should use their manifest for v1). Make GetActivatedEventArgs defer to the platform for packaged apps.
* Add LaunchActivatedEventArgs test.
* Remove unneeded interfaces.
* use a static const wstring instead of a C define for comparison.
* PR feedback around default constructor.
* PR feedback
* PR feedback
* PR Feedback
* PR Feedback
---
ProjectReunion.sln | 27 ++---
build/CopyFilesToStagingDir.ps1 | 1 -
.../ProjectReunionFrameworkPackage.nuspec | 1 -
dev/AppLifecycle/ActivatedEventArgsBase.h | 37 +++++++
.../ActivationRegistrationManager.cpp | 76 +++++++++++++
.../ActivationRegistrationManager.h | 33 ++++++
dev/AppLifecycle/AppLifecycle.cpp | 62 +++++++++++
dev/AppLifecycle/AppLifecycle.h | 22 ++++
dev/AppLifecycle/AppLifecycle.idl | 23 ++++
dev/AppLifecycle/AppLifecycle.vcxitems | 29 +++++
dev/AppLifecycle/LaunchActivatedEventArgs.h | 36 +++++++
dev/AppLifecycle/ProtocolActivatedEventArgs.h | 31 ++++++
dev/AppLifecycle/Shared.cpp | 101 ++++++++++++++++++
dev/AppLifecycle/Shared.h | 16 +++
dev/ProjectReunion_DLL/ProjectReunion.def | 4 -
.../ProjectReunion_DLL.vcxproj | 3 +-
dev/ProjectReunion_DLL/pch.h | 7 +-
dev/SampleFlatC/README.md | 59 ----------
dev/SampleFlatC/SampleFlatC.cpp | 41 -------
dev/SampleFlatC/SampleFlatC.h | 30 ------
dev/SampleWinRT/README.md | 52 ---------
dev/SampleWinRT/SampleWinRT.cpp | 6 --
dev/SampleWinRT/SampleWinRT.h | 54 ----------
dev/SampleWinRT/SampleWinRT.idl | 15 ---
dev/SampleWinRT/SampleWinRT.vcxitems | 29 -----
test/AppLifecycle/ApiTests.cpp | 38 +++++++
.../AppLifecycle/AppLifecycle.vcxitems | 14 +--
test/CppShared/TestMany.cpp | 45 --------
test/CppTest/CppTest.vcxproj | 3 +
test/CppTest/pch.h | 3 +-
test/CppTest_UWP/CppTest_UWP.vcxproj | 3 +
test/CppTest_UWP/pch.h | 3 +-
32 files changed, 534 insertions(+), 370 deletions(-)
create mode 100644 dev/AppLifecycle/ActivatedEventArgsBase.h
create mode 100644 dev/AppLifecycle/ActivationRegistrationManager.cpp
create mode 100644 dev/AppLifecycle/ActivationRegistrationManager.h
create mode 100644 dev/AppLifecycle/AppLifecycle.cpp
create mode 100644 dev/AppLifecycle/AppLifecycle.h
create mode 100644 dev/AppLifecycle/AppLifecycle.idl
create mode 100644 dev/AppLifecycle/AppLifecycle.vcxitems
create mode 100644 dev/AppLifecycle/LaunchActivatedEventArgs.h
create mode 100644 dev/AppLifecycle/ProtocolActivatedEventArgs.h
create mode 100644 dev/AppLifecycle/Shared.cpp
create mode 100644 dev/AppLifecycle/Shared.h
delete mode 100644 dev/SampleFlatC/README.md
delete mode 100644 dev/SampleFlatC/SampleFlatC.cpp
delete mode 100644 dev/SampleFlatC/SampleFlatC.h
delete mode 100644 dev/SampleWinRT/README.md
delete mode 100644 dev/SampleWinRT/SampleWinRT.cpp
delete mode 100644 dev/SampleWinRT/SampleWinRT.h
delete mode 100644 dev/SampleWinRT/SampleWinRT.idl
delete mode 100644 dev/SampleWinRT/SampleWinRT.vcxitems
create mode 100644 test/AppLifecycle/ApiTests.cpp
rename dev/SampleFlatC/SampleFlatC.vcxitems => test/AppLifecycle/AppLifecycle.vcxitems (59%)
diff --git a/ProjectReunion.sln b/ProjectReunion.sln
index a2d3cb271..ae24d870b 100644
--- a/ProjectReunion.sln
+++ b/ProjectReunion.sln
@@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.30011.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dev", "dev", "{448ED2E5-0B37-4D97-9E6B-8C10A507976A}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SampleWinRT", "SampleWinRT", "{428CCA9E-ADC5-4917-B51B-7D13E35950C5}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{F3659DFF-232D-46E0-967E-61FCC9A1132F}"
ProjectSection(SolutionItems) = preProject
docs\contributor-guide.md = docs\contributor-guide.md
@@ -15,12 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{F3659DFF-2
docs\roadmap.md = docs\roadmap.md
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleWinRT", "dev\SampleWinRT\SampleWinRT.vcxitems", "{0DE4FEFE-5471-4B50-B74B-D817A02B7F0D}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SampleFlatC", "SampleFlatC", "{8A5C2FE6-86D7-4AAA-BE2E-924B8E03B888}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleFlatC", "dev\SampleFlatC\SampleFlatC.vcxitems", "{CDCE22EC-F7BF-43D4-95D8-2E786229A4E5}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8630F7AA-2969-4DC9-8700-9B468C1DC21D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppShared", "test\CppShared\CppShared.vcxitems", "{682DED8C-3A27-48CD-866D-E853EA2024DE}"
@@ -31,15 +23,19 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppTest_Win32", "test\CppTe
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppTest_UWP", "test\CppTest_UWP\CppTest_UWP.vcxproj", "{B1A6F5EC-5418-4354-BACF-F7D998EE960D}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AppLifecycle", "AppLifecycle", "{3DE93B2F-F887-437D-B512-6B1024ABA290}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppLifecycle", "dev\AppLifecycle\AppLifecycle.vcxitems", "{E3A522A3-6635-4A42-BDED-1AF46A15F63C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppLifecycle", "test\AppLifecycle\AppLifecycle.vcxitems", "{80E07022-9E99-44FE-B875-901FB6C82F52}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
- dev\SampleWinRT\SampleWinRT.vcxitems*{0de4fefe-5471-4b50-b74b-d817a02b7f0d}*SharedItemsImports = 9
test\CppShared\CppShared.vcxitems*{682ded8c-3a27-48cd-866d-e853ea2024de}*SharedItemsImports = 9
+ test\AppLifecycle\AppLifecycle.vcxitems*{80e07022-9e99-44fe-b875-901fb6c82f52}*SharedItemsImports = 9
test\CppShared\CppShared.vcxitems*{b1a6f5ec-5418-4354-bacf-f7d998ee960d}*SharedItemsImports = 4
- dev\SampleFlatC\SampleFlatC.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
- dev\SampleWinRT\SampleWinRT.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
test\CppShared\CppShared.vcxitems*{c62688a1-16a0-4729-b6ed-842f4faa29f3}*SharedItemsImports = 4
- dev\SampleFlatC\SampleFlatC.vcxitems*{cdce22ec-f7bf-43d4-95d8-2e786229a4e5}*SharedItemsImports = 9
+ dev\AppLifecycle\AppLifecycle.vcxitems*{e3a522a3-6635-4a42-bded-1af46a15f63c}*SharedItemsImports = 9
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug_test|Any CPU = Debug_test|Any CPU
@@ -157,14 +153,13 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {428CCA9E-ADC5-4917-B51B-7D13E35950C5} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A}
- {0DE4FEFE-5471-4B50-B74B-D817A02B7F0D} = {428CCA9E-ADC5-4917-B51B-7D13E35950C5}
- {8A5C2FE6-86D7-4AAA-BE2E-924B8E03B888} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A}
- {CDCE22EC-F7BF-43D4-95D8-2E786229A4E5} = {8A5C2FE6-86D7-4AAA-BE2E-924B8E03B888}
{682DED8C-3A27-48CD-866D-E853EA2024DE} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
{B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A}
{C62688A1-16A0-4729-B6ED-842F4FAA29F3} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
{B1A6F5EC-5418-4354-BACF-F7D998EE960D} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
+ {3DE93B2F-F887-437D-B512-6B1024ABA290} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A}
+ {E3A522A3-6635-4A42-BDED-1AF46A15F63C} = {3DE93B2F-F887-437D-B512-6B1024ABA290}
+ {80E07022-9E99-44FE-B875-901FB6C82F52} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77}
diff --git a/build/CopyFilesToStagingDir.ps1 b/build/CopyFilesToStagingDir.ps1
index e6c45adf8..d53a6fe61 100644
--- a/build/CopyFilesToStagingDir.ps1
+++ b/build/CopyFilesToStagingDir.ps1
@@ -33,7 +33,6 @@ function PublishFile {
PublishFile -IfExists $FullBuildOutput\projectreunion_dll\Microsoft.ProjectReunion.dll $FullPublishDir\Microsoft.ProjectReunion\
PublishFile -IfExists $FullBuildOutput\projectreunion_dll\Microsoft.ProjectReunion.lib $FullPublishDir\Microsoft.ProjectReunion\
-PublishFile -IfExists $FullBuildOutput\projectreunion_dll\SampleFlatC.h $FullPublishDir\Microsoft.ProjectReunion\
#PublishFile -IfExists $FullBuildOutput\projectreunion_dll\Microsoft.ProjectReunion.pri $FullPublishDir\Microsoft.ProjectReunion\
#UNDONE - xaml vcxproj re-runs an mdmerge into the sdk node, we are skipping this for now and leaving the winmd in its normal outdir
#PublishFile -IfExists $FullBuildOutput\projectreunion_dll\sdk\Microsoft.ProjectReunion.winmd $FullPublishDir\Microsoft.ProjectReunion\sdk\
diff --git a/build/NuSpecs/ProjectReunionFrameworkPackage.nuspec b/build/NuSpecs/ProjectReunionFrameworkPackage.nuspec
index 8a8296aa7..b9dc6dc1a 100644
--- a/build/NuSpecs/ProjectReunionFrameworkPackage.nuspec
+++ b/build/NuSpecs/ProjectReunionFrameworkPackage.nuspec
@@ -25,7 +25,6 @@
-
diff --git a/dev/AppLifecycle/ActivatedEventArgsBase.h b/dev/AppLifecycle/ActivatedEventArgsBase.h
new file mode 100644
index 000000000..7ee52c346
--- /dev/null
+++ b/dev/AppLifecycle/ActivatedEventArgsBase.h
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#pragma once
+
+namespace winrt::Microsoft::ProjectReunion::implementation
+{
+ using namespace winrt::Windows::ApplicationModel::Activation;
+
+ class ActivatedEventArgsBase : public winrt::implements
+ {
+ public:
+ // IActivatedEventArgs
+ ActivationKind Kind()
+ {
+ return m_kind;
+ }
+
+ ApplicationExecutionState PreviousExecutionState()
+ {
+ return m_previousState;
+ }
+
+ SplashScreen SplashScreen()
+ {
+ return m_splashScreen;
+ }
+
+ protected:
+ ActivatedEventArgsBase() = default;
+
+ ActivationKind m_kind = ActivationKind::Launch;
+ ApplicationExecutionState m_previousState;
+ winrt::Windows::ApplicationModel::Activation::SplashScreen m_splashScreen{ nullptr };
+ };
+}
+
diff --git a/dev/AppLifecycle/ActivationRegistrationManager.cpp b/dev/AppLifecycle/ActivationRegistrationManager.cpp
new file mode 100644
index 000000000..e53806410
--- /dev/null
+++ b/dev/AppLifecycle/ActivationRegistrationManager.cpp
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#include
+#include
+#include
+
+#include "LaunchActivatedEventArgs.h"
+#include "ProtocolActivatedEventArgs.h"
+#include "Shared.h"
+
+namespace winrt::Microsoft::ProjectReunion::implementation
+{
+ void ActivationRegistrationManager::RegisterForFileTypeActivation(hstring const& groupName,
+ hstring const& logo, array_view supportedFileTypes,
+ array_view supportedVerbs)
+ {
+ throw hresult_not_implemented();
+ }
+
+ void ActivationRegistrationManager::RegisterForProtocolActivation(hstring const& scheme,
+ hstring const& displayName)
+ {
+ if (scheme.empty() || displayName.empty())
+ {
+ throw winrt::hresult_invalid_argument();
+ }
+
+ if (HasIdentity())
+ {
+ throw hresult_not_implemented();
+ }
+
+ RegisterProtocol(scheme.c_str(), displayName.c_str());
+ }
+
+ void ActivationRegistrationManager::RegisterForStartupActivation(hstring const& taskId,
+ bool isEnabled, hstring const& displayName)
+ {
+ throw hresult_not_implemented();
+ }
+
+ void ActivationRegistrationManager::RegisterForToastActivation(hstring const& displayName)
+ {
+ throw hresult_not_implemented();
+ }
+
+ void ActivationRegistrationManager::UnregisterForFileTypeActivation(hstring const& groupName)
+ {
+ throw hresult_not_implemented();
+ }
+
+ void ActivationRegistrationManager::UnregisterForProtocolActivation(hstring const& scheme)
+ {
+ if (scheme.empty())
+ {
+ throw winrt::hresult_invalid_argument();
+ }
+
+ if (HasIdentity())
+ {
+ throw hresult_not_implemented();
+ }
+
+ UnregisterProtocol(scheme.c_str());
+ }
+
+ void ActivationRegistrationManager::UnregisterForStartupActivation()
+ {
+ throw hresult_not_implemented();
+ }
+
+ void ActivationRegistrationManager::UnregisterForToastActivation()
+ {
+ throw hresult_not_implemented();
+ }
+}
diff --git a/dev/AppLifecycle/ActivationRegistrationManager.h b/dev/AppLifecycle/ActivationRegistrationManager.h
new file mode 100644
index 000000000..1466f246e
--- /dev/null
+++ b/dev/AppLifecycle/ActivationRegistrationManager.h
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#pragma once
+
+#include
+
+namespace winrt::Microsoft::ProjectReunion::implementation
+{
+ struct ActivationRegistrationManager
+ {
+ ActivationRegistrationManager() = default;
+
+ static void RegisterForFileTypeActivation(hstring const& groupName, hstring const& logo,
+ array_view supportedFileTypes, array_view supportedVerbs);
+ static void RegisterForProtocolActivation(hstring const& scheme, hstring const& displayName);
+ static void RegisterForStartupActivation(hstring const& taskId, bool isEnabled,
+ hstring const& displayName);
+ static void RegisterForToastActivation(hstring const& displayName);
+
+ static void UnregisterForFileTypeActivation(hstring const& groupName);
+ static void UnregisterForProtocolActivation(hstring const& scheme);
+ static void UnregisterForStartupActivation();
+ static void UnregisterForToastActivation();
+ };
+}
+
+namespace winrt::Microsoft::ProjectReunion::factory_implementation
+{
+ struct ActivationRegistrationManager : ActivationRegistrationManagerT
+ {
+ };
+}
diff --git a/dev/AppLifecycle/AppLifecycle.cpp b/dev/AppLifecycle/AppLifecycle.cpp
new file mode 100644
index 000000000..b620ee58e
--- /dev/null
+++ b/dev/AppLifecycle/AppLifecycle.cpp
@@ -0,0 +1,62 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+#include
+#include
+#include
+
+#include "LaunchActivatedEventArgs.h"
+#include "ProtocolActivatedEventArgs.h"
+#include "Shared.h"
+
+namespace winrt::Microsoft::ProjectReunion::implementation
+{
+ std::tuple ParseCommandLine(std::wstring commandLine)
+ {
+ auto argsStart = commandLine.rfind(L"----") + 4;
+ if (argsStart == std::wstring::npos)
+ {
+ return {L"", L""};
+ }
+
+ // We explicitly use find_first_of here, so that the resulting data may contain : as a valid character.
+ auto argsEnd = commandLine.find_first_of(L":", argsStart);
+ if (argsEnd == std::wstring::npos)
+ {
+ return {L"", L""};
+ }
+
+ if (argsStart > argsEnd)
+ {
+ throw std::overflow_error("commandLine");
+ }
+
+ auto argsLength = argsEnd - argsStart;
+ auto dataStart = argsEnd + 1;
+
+ return {commandLine.substr(argsStart, argsLength), commandLine.substr(dataStart)};
+ }
+
+ Windows::ApplicationModel::Activation::IActivatedEventArgs AppLifecycle::GetActivatedEventArgs()
+ {
+ if (HasIdentity())
+ {
+ return Windows::ApplicationModel::AppInstance::GetActivatedEventArgs();
+ }
+ else
+ {
+ // Generate IActivatedEventArgs for non-Packaged applications.
+ std::wstring contractId;
+ std::wstring contractData;
+ auto commandLine = std::wstring(GetCommandLine());
+ std::tie(contractId, contractData) = ParseCommandLine(commandLine);
+
+ if (!contractId.empty() && contractId == c_protocolArgumentString)
+ {
+ return winrt::make(contractData);
+ }
+
+ return winrt::make(commandLine);
+ }
+ }
+}
diff --git a/dev/AppLifecycle/AppLifecycle.h b/dev/AppLifecycle/AppLifecycle.h
new file mode 100644
index 000000000..636ed0a5c
--- /dev/null
+++ b/dev/AppLifecycle/AppLifecycle.h
@@ -0,0 +1,22 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#pragma once
+
+#include
+
+namespace winrt::Microsoft::ProjectReunion::implementation
+{
+ struct AppLifecycle
+ {
+ AppLifecycle() = default;
+
+ static Windows::ApplicationModel::Activation::IActivatedEventArgs GetActivatedEventArgs();
+ };
+}
+
+namespace winrt::Microsoft::ProjectReunion::factory_implementation
+{
+ struct AppLifecycle : AppLifecycleT
+ {
+ };
+}
diff --git a/dev/AppLifecycle/AppLifecycle.idl b/dev/AppLifecycle/AppLifecycle.idl
new file mode 100644
index 000000000..c4fe3383f
--- /dev/null
+++ b/dev/AppLifecycle/AppLifecycle.idl
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+namespace Microsoft.ProjectReunion
+{
+ static runtimeclass AppLifecycle
+ {
+ static Windows.ApplicationModel.Activation.IActivatedEventArgs GetActivatedEventArgs();
+ }
+
+ static runtimeclass ActivationRegistrationManager
+ {
+ static void RegisterForFileTypeActivation(String groupName, String logo, String[] supportedFileTypes, String[] supportedVerbs);
+ static void RegisterForProtocolActivation(String scheme, String displayName);
+ static void RegisterForStartupActivation(String taskId, Boolean isEnabled, String displayName);
+ static void RegisterForToastActivation(String displayName);
+
+ static void UnregisterForFileTypeActivation(String groupName);
+ static void UnregisterForProtocolActivation(String scheme);
+ static void UnregisterForStartupActivation();
+ static void UnregisterForToastActivation();
+ };
+}
diff --git a/dev/AppLifecycle/AppLifecycle.vcxitems b/dev/AppLifecycle/AppLifecycle.vcxitems
new file mode 100644
index 000000000..956f3789d
--- /dev/null
+++ b/dev/AppLifecycle/AppLifecycle.vcxitems
@@ -0,0 +1,29 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ {E3A522A3-6635-4A42-BDED-1AF46A15F63C}
+ AppLifecycle
+
+
+
+ %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dev/AppLifecycle/LaunchActivatedEventArgs.h b/dev/AppLifecycle/LaunchActivatedEventArgs.h
new file mode 100644
index 000000000..b70ca645a
--- /dev/null
+++ b/dev/AppLifecycle/LaunchActivatedEventArgs.h
@@ -0,0 +1,36 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#pragma once
+
+#include "ActivatedEventArgsBase.h"
+
+namespace winrt::Microsoft::ProjectReunion::implementation
+{
+ using namespace winrt::Windows::ApplicationModel::Activation;
+
+ class LaunchActivatedEventArgs : public winrt::implements
+ {
+ public:
+ LaunchActivatedEventArgs(const std::wstring& args) :
+ m_args(args)
+ {
+ m_kind = ActivationKind::Launch;
+ }
+
+ // ILaunchActivatedEventArgs
+ winrt::hstring Arguments()
+ {
+ return m_args.c_str();
+ }
+
+ winrt::hstring TileId()
+ {
+ // This implementation is only used for Win32 which don't support secondary tiles.
+ return L"";
+ }
+
+ private:
+ std::wstring m_args;
+ };
+}
diff --git a/dev/AppLifecycle/ProtocolActivatedEventArgs.h b/dev/AppLifecycle/ProtocolActivatedEventArgs.h
new file mode 100644
index 000000000..d53eaa3cc
--- /dev/null
+++ b/dev/AppLifecycle/ProtocolActivatedEventArgs.h
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#pragma once
+
+#include
+#include "ActivatedEventArgsBase.h"
+
+namespace winrt::Microsoft::ProjectReunion::implementation
+{
+ using namespace winrt::Windows::Foundation::Collections;
+ using namespace winrt::Windows::ApplicationModel::Activation;
+
+ class ProtocolActivatedEventArgs : public winrt::implements
+ {
+ public:
+ ProtocolActivatedEventArgs(const std::wstring& uri) : m_uri(winrt::Windows::Foundation::Uri(uri))
+ {
+ m_kind = ActivationKind::Protocol;
+ }
+
+ // IProtocolActivatedEventArgs
+ winrt::Windows::Foundation::Uri Uri()
+ {
+ return m_uri;
+ }
+
+ private:
+ winrt::Windows::Foundation::Uri m_uri{nullptr};
+ };
+}
diff --git a/dev/AppLifecycle/Shared.cpp b/dev/AppLifecycle/Shared.cpp
new file mode 100644
index 000000000..ed0cb51f7
--- /dev/null
+++ b/dev/AppLifecycle/Shared.cpp
@@ -0,0 +1,101 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#include
+#include "Shared.h"
+
+namespace winrt::Microsoft::ProjectReunion::implementation
+{
+ std::wstring GetFullIdentityString()
+ {
+ std::wstring identityString;
+ WCHAR idNameBuffer[PACKAGE_FULL_NAME_MAX_LENGTH+1];
+ UINT32 idNameBufferLen = ARRAYSIZE(idNameBuffer);
+ if (::GetCurrentPackageFullName(&idNameBufferLen, idNameBuffer) == ERROR_SUCCESS)
+ {
+ identityString = idNameBuffer;
+ }
+
+ return identityString;
+ }
+
+ bool HasIdentity()
+ {
+ return !(GetFullIdentityString()).empty();
+ }
+
+ std::wstring GetModulePath()
+ {
+ std::wstring path(100, L'?');
+ uint32_t path_size{};
+ DWORD actual_size{};
+
+ do
+ {
+ path_size = static_cast(path.size());
+ actual_size = ::GetModuleFileName(nullptr, path.data(), path_size);
+
+ if (actual_size + 1 > path_size)
+ {
+ path.resize(path_size * 2, L'?');
+ }
+ } while (actual_size + 1 > path_size);
+
+ path.resize(actual_size);
+ return path;
+ }
+
+ std::wstring CreateAssocKeyPath(PCWSTR assocName)
+ {
+ std::wstring path{ LR"(SOFTWARE\Classes\)" };
+ path += assocName;
+ return path;
+ }
+
+ void RegisterProtocol(PCWSTR scheme, PCWSTR displayName, _In_opt_ const GUID* delegateExecute)
+ {
+ std::wstring key_path{ CreateAssocKeyPath(scheme) };
+ wil::unique_hkey key;
+
+ THROW_IF_WIN32_ERROR(::RegCreateKeyEx(HKEY_CURRENT_USER, key_path.c_str(), 0, nullptr, 0,
+ KEY_WRITE, nullptr, key.put(), nullptr));
+
+ std::wstring defaultValue{ L"URL:" };
+ defaultValue += displayName;
+ THROW_IF_WIN32_ERROR(::RegSetValueEx(key.get(), nullptr, 0, REG_SZ,
+ reinterpret_cast(defaultValue.c_str()),
+ static_cast((defaultValue.size() + 1) * sizeof(wchar_t))));
+
+ std::wstring urlProtocolValue{ L"" };
+ defaultValue += displayName;
+ THROW_IF_WIN32_ERROR(::RegSetValueEx(key.get(), L"URL Protocol", 0, REG_SZ,
+ reinterpret_cast(urlProtocolValue.c_str()),
+ static_cast((urlProtocolValue.size() + 1) * sizeof(wchar_t))));
+
+ key_path += LR"(\shell\open\command)";
+ key.reset();
+ THROW_IF_WIN32_ERROR(::RegCreateKeyEx(HKEY_CURRENT_USER, key_path.c_str(), 0, nullptr, 0,
+ KEY_WRITE, nullptr, key.put(), nullptr));
+
+ auto command = GetModulePath();
+ command += L" ----" + c_protocolArgumentString + L":%1";
+ THROW_IF_WIN32_ERROR(::RegSetValueEx(key.get(), nullptr, 0, REG_SZ,
+ reinterpret_cast(command.c_str()),
+ static_cast((command.size() + 1) * sizeof(wchar_t))));
+
+ if (delegateExecute)
+ {
+ std::wstring delegateClsid{ LR"({????????-????-????-????-????????????})" };
+ ::StringFromGUID2(*delegateExecute, delegateClsid.data(), 39);
+
+ THROW_IF_WIN32_ERROR(::RegSetValueEx(key.get(), L"DelegateExecute", 0, REG_SZ,
+ reinterpret_cast(delegateClsid.c_str()),
+ static_cast((delegateClsid.size() + 1) * sizeof(wchar_t))));
+ }
+ }
+
+ void UnregisterProtocol(PCWSTR scheme)
+ {
+ std::wstring key_path{ CreateAssocKeyPath(scheme) };
+ ::RegDeleteTree(HKEY_CURRENT_USER, key_path.c_str());
+ }
+}
diff --git a/dev/AppLifecycle/Shared.h b/dev/AppLifecycle/Shared.h
new file mode 100644
index 000000000..3ab0800bc
--- /dev/null
+++ b/dev/AppLifecycle/Shared.h
@@ -0,0 +1,16 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#pragma once
+
+namespace winrt::Microsoft::ProjectReunion::implementation
+{
+
+ static const std::wstring c_protocolArgumentString = L"ms-protocol"; //L"ms-protocol"
+
+ std::wstring GetFullIdentityString();
+ bool HasIdentity();
+ std::wstring GetModulePath();
+ std::wstring CreateAssocKeyPath(PCWSTR assocName);
+ void RegisterProtocol(PCWSTR scheme, PCWSTR displayName, _In_opt_ const GUID* delegateExecute = nullptr);
+ void UnregisterProtocol(PCWSTR scheme);
+}
diff --git a/dev/ProjectReunion_DLL/ProjectReunion.def b/dev/ProjectReunion_DLL/ProjectReunion.def
index 12f33c35a..aa57cf658 100644
--- a/dev/ProjectReunion_DLL/ProjectReunion.def
+++ b/dev/ProjectReunion_DLL/ProjectReunion.def
@@ -1,7 +1,3 @@
EXPORTS
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
-
- SampleFlatApiCreate
- CloseSampleFlatApi
- GetSampleFlatApiString
diff --git a/dev/ProjectReunion_DLL/ProjectReunion_DLL.vcxproj b/dev/ProjectReunion_DLL/ProjectReunion_DLL.vcxproj
index c5279f24a..0cd37932e 100644
--- a/dev/ProjectReunion_DLL/ProjectReunion_DLL.vcxproj
+++ b/dev/ProjectReunion_DLL/ProjectReunion_DLL.vcxproj
@@ -104,8 +104,7 @@
-
-
+
diff --git a/dev/ProjectReunion_DLL/pch.h b/dev/ProjectReunion_DLL/pch.h
index 9b50d2c27..c31e10ef3 100644
--- a/dev/ProjectReunion_DLL/pch.h
+++ b/dev/ProjectReunion_DLL/pch.h
@@ -1,7 +1,10 @@
#pragma once
#include
+#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -9,4 +12,6 @@
#include
#include
#include
-
+#include
+#include
+#include
diff --git a/dev/SampleFlatC/README.md b/dev/SampleFlatC/README.md
deleted file mode 100644
index 12c3c3556..000000000
--- a/dev/SampleFlatC/README.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# Adding a new Flat C API Component
-
-This directory is a sample of adding an API with a "flat C" style to Project Reunion.
-Flat C APIs define an ABI using C-based headers exported from a DLL. Apps can use the
-APIs from an import library or through a projection that applies a wrapper.
-
-## Adding the shared project
-
-1. In Visual Studio, right-click the `dev` node in the Solution and choose "New Solution Folder"
-2. Pick a name for your new project (the rest of this example uses `Muffins`)
-3. Right-click the `Muffins` solution folder and use "Add > New Project"
-4. Use the "Shared Items Project", set the name (`Muffins`)
-4. For path use the solution root plus `\\dev` - the final path will be in `\\dev\\Muffins`
-
-## Reference the project
-
-1. Right-click the **ProjectReunion** project, use "Add > Reference"
-2. Choose `Muffins` from the list of "Shared" items
-
-## Add public header
-
-1. Right-click the shared project and use "Add > New Item"
-2. From the "Installed > Visual C++ > Code" list, select "Header (.h)"
-3. Pick a good name (for the rest of this example, we'll use `Muffins` again, so "muffins.h")
-5. Define the ABI for the implementation
-
-Follow the example of [SampleFlatC](./SampleFlatC.h):
-
-* Use `STDAPI` and `STDAPI_(type)` to define entrypoints
-* Use scoped enumerations (like `enum class`) instead of preprocessor definitions
-
-## Add implementation
-
-1. Add `.cpp` files that implement the APIs in the usual way
-2. For code using C++-with-exceptions use an appropriate exception guard
-
-## Publish header
-
-1. In the `.vcxitems` for the new project, manually add something like this, per [SampleFlatC.vcxitems](./SampleFlatC.vcxitems)
-
-```xml
-
-
-
-
-```
-
-## Adding exports
-
-1. In [ProjectReunion.def](../dll/ProjectReunion.def) add the list of exported methods
-
-## Other notes
-
-Be sure to add the copyright and license marker to all source files:
-
-```c++
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See LICENSE in the project root for license information.
-```
\ No newline at end of file
diff --git a/dev/SampleFlatC/SampleFlatC.cpp b/dev/SampleFlatC/SampleFlatC.cpp
deleted file mode 100644
index 34408aeaf..000000000
--- a/dev/SampleFlatC/SampleFlatC.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See LICENSE in the project root for license information.
-
-#include "pch.h"
-#include "SampleFlatC.h"
-#include
-
-struct MyRealType
-{
- std::wstring theString;
-};
-
-STDAPI SampleFlatApiCreate(
- _In_ LPCWSTR theString,
- _Outptr_ HSAMPLEFLATAPI* sampleFlat) try
-{
- RETURN_HR_IF(E_INVALIDARG, !theString);
- auto real = std::make_unique();
- real->theString = theString;
- *sampleFlat = reinterpret_cast(real.release());
- return S_OK;
-}
-CATCH_RETURN();
-
-STDAPI_(VOID) CloseSampleFlatApi(HSAMPLEFLATAPI sampleFlat) try
-{
- auto real = std::unique_ptr(reinterpret_cast(sampleFlat));
- // Do something with 'real', the destructor will clean it up
-}
-CATCH_LOG();
-
-STDAPI GetSampleFlatApiString(
- _In_ HSAMPLEFLATAPI sampleFlat,
- _Outptr_ LPWSTR* theString) try
-{
- auto real = reinterpret_cast(sampleFlat);
- auto cloned = wil::make_cotaskmem_string(real->theString.data());
- *theString = cloned.release();
- return S_OK;
-}
-CATCH_RETURN();
diff --git a/dev/SampleFlatC/SampleFlatC.h b/dev/SampleFlatC/SampleFlatC.h
deleted file mode 100644
index c57ebcf7d..000000000
--- a/dev/SampleFlatC/SampleFlatC.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See LICENSE in the project root for license information.
-
-#pragma once
-#include
-
-DECLARE_HANDLE(HSAMPLEFLATAPI);
-
-STDAPI SampleFlatApiCreate(
- _In_ LPCWSTR theString,
- _Outptr_ HSAMPLEFLATAPI* sampleFlat);
-
-STDAPI_(VOID) CloseSampleFlatApi(
- HSAMPLEFLATAPI sampleFlat);
-
-STDAPI GetSampleFlatApiString(
- _In_ HSAMPLEFLATAPI sampleFlat,
- _Outptr_ LPWSTR* theString);
-
-// Include from the NuGet package Microsoft.Windows.ImplementationLibrary
-// before this file to have this handy lifecycle helper for C++ light up
-
-#ifdef __WIL_RESOURCE
-
-namespace wil
-{
- using unique_sampleflat_handle = unique_any;
-}
-
-#endif
diff --git a/dev/SampleWinRT/README.md b/dev/SampleWinRT/README.md
deleted file mode 100644
index 0d2573f56..000000000
--- a/dev/SampleWinRT/README.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# Adding a new WinRT Component
-
-This directory is a sample of adding a WinRT component to Project Reunion.
-WinRT-based APIs are defined using [MIDL3](https://docs.microsoft.com/en-us/uwp/midl-3/)
-and typically [implemented with C++/WinRT](https://github.com/Microsoft/cppwinrt). It's
-straightforward to add a new component in this manner.
-
-## Adding the shared project
-
-1. In Visual Studio, right-click the `dev` node in the Solution and choose "New Solution Folder"
-2. Pick a name for your new project (the rest of this example uses `Muffins`)
-3. Right-click the `Muffins` solution folder and use "Add > New Project"
-4. Use the "Shared Items Project", set the name (`Muffins`)
-4. For path use the solution root plus `\\dev` - the final path will be in `\\dev\\Muffins`
-
-## Reference the project
-
-1. Right-click the **ProjectReunion** project, use "Add > Reference"
-2. Choose `Muffins` from the list of "Shared" items
-
-## Add IDL and implementation
-
-1. Right-click the shared project and use "Add > New Item"
-2. From the Installed > Visual C++ > Code list, select "Midl File (.idl)"
-3. Pick a good name (for the rest of this example, we'll use `Muffins` again, so "muffins.idl")
-4. Remove the default `import ...` statements that visual studio generates
-
-Follow the example of [SampleWinRT](./SampleWinRT.idl):
-
-* Use `Microsoft.Muffins` as the namespace
-* Add types and classes as necessary
-
-Add a header and `.cpp` file and an implementation.
-
-Be sure to add the copyright and license marker to all source files:
-
-```c++
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See LICENSE in the project root for license information.
-```
-
-Add any C++/WinRT projected headers used by the implementation to
-the [pch.h](../ProjectReunion_DLL/pch.h) to reduce compilation times.
-
-## Testing
-
-1. Add a new file to the [CppShared](../../test/CppShared/CppShared.vcxitems)
-2. Follow the existing pattern of adding a `TEST_CLASS` with `TEST_METHOD` for facets of your implementation
-3. Build the project and use the Visual Studio Test Explorer to run all tests
-
-For very large surfaces with lots of tests, add a new directory under `test`
-with its own shared items project.
diff --git a/dev/SampleWinRT/SampleWinRT.cpp b/dev/SampleWinRT/SampleWinRT.cpp
deleted file mode 100644
index 8c9e9f6d1..000000000
--- a/dev/SampleWinRT/SampleWinRT.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See LICENSE in the project root for license information.
-
-#include
-#include
-#include
diff --git a/dev/SampleWinRT/SampleWinRT.h b/dev/SampleWinRT/SampleWinRT.h
deleted file mode 100644
index 59498bbf5..000000000
--- a/dev/SampleWinRT/SampleWinRT.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See LICENSE in the project root for license information.
-
-#pragma once
-
-#include
-
-namespace winrt::Microsoft::ProjectReunion::implementation
-{
- struct Common
- {
- Common() = default;
-
- static void Initialize()
- {
- }
-
- static hstring AppIdentity()
- {
- static winrt::hstring fullName = GetFullIdentityString();
- return fullName;
- }
-
- static bool IsAppContainer()
- {
- static bool isAppContainer = wil::get_token_is_app_container();
- return isAppContainer;
- }
-
- static bool HasIdentity()
- {
- return !AppIdentity().empty();
- }
-
- static winrt::hstring GetFullIdentityString()
- {
- winrt::hstring identityString;
- WCHAR idNameBuffer[PACKAGE_FULL_NAME_MAX_LENGTH];
- UINT32 idNameBufferLen = ARRAYSIZE(idNameBuffer);
- if (::GetCurrentPackageFullName(&idNameBufferLen, idNameBuffer) == ERROR_SUCCESS)
- {
- identityString = idNameBuffer;
- }
-
- return identityString;
- }
- };
-}
-namespace winrt::Microsoft::ProjectReunion::factory_implementation
-{
- struct Common : CommonT
- {
- };
-}
diff --git a/dev/SampleWinRT/SampleWinRT.idl b/dev/SampleWinRT/SampleWinRT.idl
deleted file mode 100644
index dfd83fd96..000000000
--- a/dev/SampleWinRT/SampleWinRT.idl
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See LICENSE in the project root for license information.
-
-namespace Microsoft.ProjectReunion
-{
- static runtimeclass Common
- {
- static void Initialize();
-
- static String AppIdentity { get; };
-
- static Boolean IsAppContainer{ get; };
- static Boolean HasIdentity{ get; };
- };
-}
diff --git a/dev/SampleWinRT/SampleWinRT.vcxitems b/dev/SampleWinRT/SampleWinRT.vcxitems
deleted file mode 100644
index c1a254ef2..000000000
--- a/dev/SampleWinRT/SampleWinRT.vcxitems
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
- $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
- true
- {0de4fefe-5471-4b50-b74b-d817a02b7f0d}
- SampleWinRT
-
-
-
- %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/AppLifecycle/ApiTests.cpp b/test/AppLifecycle/ApiTests.cpp
new file mode 100644
index 000000000..53c0f27db
--- /dev/null
+++ b/test/AppLifecycle/ApiTests.cpp
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+#include "pch.h"
+
+using namespace winrt::Windows::ApplicationModel;
+using namespace winrt::Windows::ApplicationModel::Activation;
+using namespace winrt::Microsoft::ProjectReunion;
+using namespace Microsoft::VisualStudio::CppUnitTestFramework;
+
+namespace ProjectReunionCppTest
+{
+ TEST_CLASS(AppLifecycleApiTests)
+ {
+#if PRTEST_MODE_UWP
+ // UWP currently is not supported by these tests.
+ TEST_METHOD(GetActivatedEventArgsIsNull)
+ {
+ Assert::IsTrue(winrt::Microsoft::ProjectReunion::AppLifecycle::GetActivatedEventArgs() == nullptr);
+ }
+#else
+ TEST_METHOD(GetActivatedEventArgsIsNotNull)
+ {
+ Assert::IsTrue(winrt::Microsoft::ProjectReunion::AppLifecycle::GetActivatedEventArgs() != nullptr);
+ }
+
+ TEST_METHOD(GetActivatedEventArgsForLaunch)
+ {
+ auto args = winrt::Microsoft::ProjectReunion::AppLifecycle::GetActivatedEventArgs();
+ Assert::IsTrue(args != nullptr);
+ Assert::IsTrue(args.Kind() == ActivationKind::Launch);
+
+ auto launchArgs = args.as();
+ Assert::IsTrue(launchArgs != nullptr);
+ }
+#endif
+ };
+}
diff --git a/dev/SampleFlatC/SampleFlatC.vcxitems b/test/AppLifecycle/AppLifecycle.vcxitems
similarity index 59%
rename from dev/SampleFlatC/SampleFlatC.vcxitems
rename to test/AppLifecycle/AppLifecycle.vcxitems
index 3a78bbcd6..c024f29dd 100644
--- a/dev/SampleFlatC/SampleFlatC.vcxitems
+++ b/test/AppLifecycle/AppLifecycle.vcxitems
@@ -3,7 +3,7 @@
$(MSBuildAllProjects);$(MSBuildThisFileFullPath)
true
- {cdce22ec-f7bf-43d4-95d8-2e786229a4e5}
+ {80E07022-9E99-44FE-B875-901FB6C82F52}
@@ -14,16 +14,6 @@
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/test/CppShared/TestMany.cpp b/test/CppShared/TestMany.cpp
index 95eecf18e..660f7ae20 100644
--- a/test/CppShared/TestMany.cpp
+++ b/test/CppShared/TestMany.cpp
@@ -7,49 +7,4 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace ProjectReunionCppTest
{
- TEST_CLASS(FlatApiTests)
- {
- public:
-
- TEST_METHOD(Creates)
- {
- wil::unique_sampleflat_handle temp;
- Assert::IsTrue(SUCCEEDED(::SampleFlatApiCreate(L"kittens", &temp)));
- Assert::IsTrue(SUCCEEDED(::SampleFlatApiCreate(L"puppies", &temp)));
- Assert::IsTrue(FAILED(::SampleFlatApiCreate(nullptr, &temp)));
- }
-
- TEST_METHOD(CloseNullOk)
- {
- CloseSampleFlatApi(nullptr);
- }
-
- TEST_METHOD(StringRoundTrip)
- {
- const wchar_t* tasty = L"muffins";
- wil::unique_sampleflat_handle temp;
- THROW_IF_FAILED(::SampleFlatApiCreate(tasty, &temp));
- wil::unique_cotaskmem_string stored;
- Assert::IsTrue(SUCCEEDED(::GetSampleFlatApiString(temp.get(), &stored)));
- Assert::IsNotNull(stored.get());
- Assert::AreEqual(tasty, stored.get());
- }
- };
-
- TEST_CLASS(WinRtApiTests)
- {
-#if PRTEST_MODE_UWP
- TEST_METHOD(ContainerTests)
- {
- Assert::IsTrue(winrt::Microsoft::ProjectReunion::Common::IsAppContainer());
- Assert::IsTrue(winrt::Microsoft::ProjectReunion::Common::HasIdentity());
- }
-#else
- TEST_METHOD(ContainerTests)
- {
- Assert::IsFalse(winrt::Microsoft::ProjectReunion::Common::IsAppContainer());
- Assert::IsFalse(winrt::Microsoft::ProjectReunion::Common::HasIdentity());
- }
-#endif
- };
}
diff --git a/test/CppTest/CppTest.vcxproj b/test/CppTest/CppTest.vcxproj
index bea22d152..232905afb 100644
--- a/test/CppTest/CppTest.vcxproj
+++ b/test/CppTest/CppTest.vcxproj
@@ -111,6 +111,9 @@
+
+
+
diff --git a/test/CppTest/pch.h b/test/CppTest/pch.h
index 7e0c18c51..29e5aaf01 100644
--- a/test/CppTest/pch.h
+++ b/test/CppTest/pch.h
@@ -10,6 +10,7 @@
#include
#include "CppUnitTest.h"
+#include
+
// Test-specific headers, lifted here
-#include
#include
diff --git a/test/CppTest_UWP/CppTest_UWP.vcxproj b/test/CppTest_UWP/CppTest_UWP.vcxproj
index 40f501ffb..edf8424bd 100644
--- a/test/CppTest_UWP/CppTest_UWP.vcxproj
+++ b/test/CppTest_UWP/CppTest_UWP.vcxproj
@@ -75,6 +75,9 @@
+
+
+
diff --git a/test/CppTest_UWP/pch.h b/test/CppTest_UWP/pch.h
index 1d1c4d158..d8939e108 100644
--- a/test/CppTest_UWP/pch.h
+++ b/test/CppTest_UWP/pch.h
@@ -19,6 +19,7 @@
#include
#include
+#include
+
// Test-specific headers, lifted here
-#include
#include