Skip to content

Commit

Permalink
Add initial Protobuf support (microsoft#3448)
Browse files Browse the repository at this point in the history
**Add support for Google's [Protocol Buffers](https://protobuf.dev/) (aka protobuf)**

Using protobuf requires 3 components:

1. protoc.exe -- 'Compiles' *.proto files generating *.pb.cc and *.pb.h code
2. headers -- Needed to compile generated *.pb.cc
3. libs -- Needed to link compiled bits from 2

Google provides a nuget containing a compiled protoc.exe but doesn't make headers or libs available via nuget. TL;DR we create a nuget for our use (Microsoft.WindowsAppSDK.Protobuf.3.21.12.nupkg). Details of what, why and how are in `tools\nuget\protobuf\README.md`.

TL;DR Developers working in WinAppSDK only need to know there's a nuget providing protobuf support. The messy details how to create that are only relevant to the developer creating the nuget (moi) or future devs if/when a new version is needed.

**Added `KozaniProtocol`** containing Kozani's protobuf messages and related definitions. The purpose of KozaniManageProtocol project is to contain all of Kozani's protobuf definitions and compile them to produce the generated code for use by other projects.

**Updated `KozaniManager`** to consume the protobuf code from KozaniProtocol and added wrappers showing how to use it.

**Updated `KozaniRemoteManager`** to reference to consume the protobuf code from KozaniProtocol.

General structure of our protobuf usage:

1. **Define a message in KozaniProtocol**. 
 * Split up by functional roles across *.proto files e.g. Kozani.Activation.proto for activation, Kozani.Process.proto for process management (e.g. if TaskManager kills local KozaniHostRuntime.exe we need to send message to server to terminate the associated back end process), etc.
  * Any sort of 'synchronous communication' would involve a pair of request+response messages. KozaniManager sends 'request' to server and KozaniRemoteManager sends a related 'response'.
  * The 'cookie' field is an example of a correlating id to match a request with a response. A 'conversionid', 'channelid', etc are other examples how to xref 2+ messages together into a larger context.
2. **Define a namespace with functions that internally use protobuf messages**
  * Keep all protobuf usage internal to code using them. Protobuf is an implementation detail. Provide appropriate strongly typed functions for callers to drive activity which internally happen to use the protobuf generated code.
  * If you need context spanning multiple messages you can create a class with methods which internally use protobuf messages, plus additional attributes for any additional data needed for the context.
3. Serialize messages to `std::string`
  * Protobuf can serialize messages to `std::string` or `std::ostream`. NOTE: The serialized data's just bytes, `string` is just a convenient container to pass the data around.
  * `std::string` is recommend when serializing a message to bytes.
  * `std::string` or `std::istream` is recommended when deserializing a message from bytes. Large messages may be more efficient via `std::istream`; either works well enough for small messages so use whichever is more convenient.
4. Always encode strings as UTF8 before serialization.
  * Protobuf expresses message `string` fields as `std::string`. It does not do wide<->narrow conversions for you (unlike, say, SQLite) - that's the developer's responsibility. If you have a wide string (`std::wstring`, `PCWSTR`, `HSTRING`, etc) convert it to a UTF-8 string before assigning it to a protobuf field. Use functions in `\dev\common\Microsoft.Utf8.h` to convert wide->utf8 e.g.

```c++
PCWSTR appUserModelId{ L"LolzCatzVidz" };
const std::string appUserModelIdUtf8{ ::Microsoft::Utf8::ToUtf8(appUserModelId) };
```

  * When deserializing wide strings from protobuf serialized bytes don't forget to convert the UTF-8 bytes to a wide string. Use functions in `\dev\common\Microsoft.Utf8.h` to do this e.g.

```
Some::Protobuf::Message::Kitteh kitteh;
kitteh.ParseFromString(stream_containing_serialized_bytes);
const std::wstring name{ kitten.get_name() };
```

5. Avoid making classes inherit from protobuf's generated classes.
  * Protobuf docs counsel against against inheriting and extending the generated classes. Treat protobuf's generated classes as structs of data you can access but not extend (use composition esp private composition, not inheritance).

6. We use protobuf as a static library.
  * Protobuf can provide support code via libprotobuf.dll but recommends against it as that must have a compatible version as the generated code. To minimize complications we use protobuf as a static lib. This may be revisited in the future.


Everything compiles and links. `dev\Kozani\KozaniManager\main.cpp` has an example serializing a protobuf message to bytes (as a `std::string`). Changing and extending that for all the rest of our functionality and likewise parsing bytes to protobuf messages in KozaniRemoteManager (or vice versa) is left as an exercise for the reader :-)
  • Loading branch information
DrusTheAxe authored Feb 17, 2023
1 parent 03881f8 commit bdafab1
Show file tree
Hide file tree
Showing 37 changed files with 938 additions and 26 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ PublishScripts/
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# except our intentionally checked in local repository
!tools/nuget/*.nupkg

# Microsoft Azure Build Output
csx/
Expand Down
6 changes: 3 additions & 3 deletions DevCheck.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ function Get-VSWhere
{
$global:vswhere = Get-VSWhereOnline
}
}
}
if ([string]::IsNullOrEmpty($global:vswhere))
{
Write-Host "ERROR: vswhere.exe not found" -ForegroundColor Red -BackgroundColor Black
Expand Down Expand Up @@ -1010,8 +1010,8 @@ function Test-PackagesConfig
else
{
Write-Host "ERROR: Unknown version $name=$version in $filename" -ForegroundColor Red -BackgroundColor Black
$global:issues++
}
$global:issues++
}
}

if (-not($package.HasAttribute("targetFramework")))
Expand Down
8 changes: 6 additions & 2 deletions HybridCRT.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<PropertyGroup Condition="'$(HybridCrtConfiguration)'==''">
<HybridCrtConfiguration>$(Configuration)</HybridCrtConfiguration>
</PropertyGroup>

<ItemDefinitionGroup Condition="'$(HybridCrtConfiguration)'=='Debug'">
<ClCompile>
<!-- We use MultiThreadedDebug, rather than MultiThreadedDebugDLL, to avoid DLL dependencies on VCRUNTIME140d.dll and MSVCP140d.dll. -->
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
Expand All @@ -16,7 +20,7 @@
<AdditionalOptions>%(AdditionalOptions) /defaultlib:ucrtd.lib</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ItemDefinitionGroup Condition="'$(HybridCrtConfiguration)'=='Release'">
<ClCompile>
<!-- We use MultiThreaded, rather than MultiThreadedDLL, to avoid DLL dependencies on VCRUNTIME140.dll and MSVCP140.dll. -->
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
Expand Down
15 changes: 15 additions & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,23 @@
<packageSources>
<clear />
<add key="ProjectReunion internal" value="https://microsoft.pkgs.visualstudio.com/ProjectReunion/_packaging/Project.Reunion.nuget.internal/nuget/v3/index.json" />
<add key="WindowsAppSDK Protobuf" value="tools/nuget" />
</packageSources>

<disabledPackageSources>
<clear />
</disabledPackageSources>

<!--
<packageSourceMapping>
<packageSource key="WindowsAppSDK Protobuf">
<package pattern="Microsoft.WindowsAppSDK.Protobuf.*" />
</packageSource>
</packageSourceMapping>
<packageSourceMapping>
<packageSource key="ProjectReunion internal">
<package pattern="*" />
</packageSource>
</packageSourceMapping>
-->
</configuration>
24 changes: 24 additions & 0 deletions WindowsAppRuntime.sln
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KozaniManager", "dev\Kozani\KozaniManager\KozaniManager.vcxproj", "{829CDB09-EEFE-4188-A045-3FC6BE7BD96B}"
ProjectSection(ProjectDependencies) = postProject
{22747850-42DE-489B-BD0D-F59DB3DE25AD} = {22747850-42DE-489B-BD0D-F59DB3DE25AD}
{3F28C3ED-2548-4530-8B6C-832FAE0E993D} = {3F28C3ED-2548-4530-8B6C-832FAE0E993D}
{5C0E77FA-B6F4-4B3F-AAE5-AB85CF97816F} = {5C0E77FA-B6F4-4B3F-AAE5-AB85CF97816F}
{B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1}
{CFC67AC3-3DC3-4981-A9BB-BC5ED06542D4} = {CFC67AC3-3DC3-4981-A9BB-BC5ED06542D4}
Expand All @@ -485,6 +486,7 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KozaniRemoteManager", "dev\Kozani\KozaniRemoteManager\KozaniRemoteManager.vcxproj", "{A11C6664-F26A-4E71-B440-2E4E1BA09A93}"
ProjectSection(ProjectDependencies) = postProject
{133BFD48-FD50-4B35-9E0C-C6B362E13027} = {133BFD48-FD50-4B35-9E0C-C6B362E13027}
{3F28C3ED-2548-4530-8B6C-832FAE0E993D} = {3F28C3ED-2548-4530-8B6C-832FAE0E993D}
{B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1}
{B9933E40-5A7C-482E-9FF3-FC06C1A7B37E} = {B9933E40-5A7C-482E-9FF3-FC06C1A7B37E}
{EAFEF760-EB96-436D-BDD0-C00B3C8BC8E7} = {EAFEF760-EB96-436D-BDD0-C00B3C8BC8E7}
Expand Down Expand Up @@ -617,6 +619,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{9CE0ED94-0
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KozaniManager.Msix", "test\Kozani\data\KozaniManager.Msix\KozaniManager.Msix.vcxproj", "{D4D29026-C15C-49A3-BEC5-4D477028962C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "KozaniProtocol", "KozaniProtocol", "{82197F64-3A88-4C48-AEF9-7E62E71D75BB}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KozaniProtocol", "dev\Kozani\KozaniProtocol\KozaniProtocol.vcxproj", "{3F28C3ED-2548-4530-8B6C-832FAE0E993D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -2180,6 +2186,22 @@ Global
{D4D29026-C15C-49A3-BEC5-4D477028962C}.Release|x64.Build.0 = Release|x64
{D4D29026-C15C-49A3-BEC5-4D477028962C}.Release|x86.ActiveCfg = Release|Win32
{D4D29026-C15C-49A3-BEC5-4D477028962C}.Release|x86.Build.0 = Release|Win32
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Debug|Any CPU.ActiveCfg = Debug|x64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Debug|Any CPU.Build.0 = Debug|x64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Debug|ARM64.Build.0 = Debug|ARM64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Debug|x64.ActiveCfg = Debug|x64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Debug|x64.Build.0 = Debug|x64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Debug|x86.ActiveCfg = Debug|Win32
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Debug|x86.Build.0 = Debug|Win32
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Release|Any CPU.ActiveCfg = Release|x64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Release|Any CPU.Build.0 = Release|x64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Release|ARM64.ActiveCfg = Release|ARM64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Release|ARM64.Build.0 = Release|ARM64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Release|x64.ActiveCfg = Release|x64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Release|x64.Build.0 = Release|x64
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Release|x86.ActiveCfg = Release|Win32
{3F28C3ED-2548-4530-8B6C-832FAE0E993D}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -2366,6 +2388,8 @@ Global
{400ED5EC-4530-4ADB-8DCE-9D1E6708A1F5} = {49CF5AB7-304F-4C78-A098-A77B2931F64E}
{9CE0ED94-078A-405F-8599-BFC2D8D6E537} = {9164C50F-E9CA-41BD-BCA9-5F30845FA257}
{D4D29026-C15C-49A3-BEC5-4D477028962C} = {9CE0ED94-078A-405F-8599-BFC2D8D6E537}
{82197F64-3A88-4C48-AEF9-7E62E71D75BB} = {84F66485-4391-41C7-89CB-D5006EDF1383}
{3F28C3ED-2548-4530-8B6C-832FAE0E993D} = {82197F64-3A88-4C48-AEF9-7E62E71D75BB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77}
Expand Down
21 changes: 17 additions & 4 deletions dev/Kozani/KozaniManager/KozaniManager.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<Import Project="$(NugetPackageDirectory)\Microsoft.Build.Tasks.Git.$(MicrosoftBuildTasksGitVersion)\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('$(NugetPackageDirectory)\Microsoft.Build.Tasks.Git.$(MicrosoftBuildTasksGitVersion)\build\Microsoft.Build.Tasks.Git.props')" />
<Import Project="$(NugetPackageDirectory)\Microsoft.SourceLink.Common.$(MicrosoftSourceLinkCommonVersion)\build\Microsoft.SourceLink.Common.props" Condition="Exists('$(NugetPackageDirectory)\Microsoft.SourceLink.Common.$(MicrosoftSourceLinkCommonVersion)\build\Microsoft.SourceLink.Common.props')" />
<Import Project="$(NugetPackageDirectory)\Microsoft.Windows.CppWinRT.$(MicrosoftWindowsCppWinRTVersion)\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(NugetPackageDirectory)\Microsoft.Windows.CppWinRT.$(MicrosoftWindowsCppWinRTVersion)\build\native\Microsoft.Windows.CppWinRT.props')" />
<Import Project="$(NugetPackageDirectory)\Microsoft.WindowsAppSDK.Protobuf.$(MicrosoftWindowsAppSDKProtobufVersion)\build\native\Microsoft.WindowsAppSDK.Protobuf.props" Condition="Exists('$(NugetPackageDirectory)\Microsoft.WindowsAppSDK.Protobuf.$(MicrosoftWindowsAppSDKProtobufVersion)\build\native\Microsoft.WindowsAppSDK.Protobuf.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
Expand Down Expand Up @@ -47,6 +48,8 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<UseDebugLibraries>true</UseDebugLibraries>
<!-- We only use protobuf Release builds so make sure HybridCRT uses the Release CRT if you use protobufs (for now) -->
<HybridCrtConfiguration>Release</HybridCrtConfiguration>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<UseDebugLibraries>false</UseDebugLibraries>
Expand Down Expand Up @@ -88,14 +91,15 @@
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>(MSBuildThisFileDirectory);$(OutDir)..\KozaniManagerProxyStub;$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\dev\WindowsAppRuntime_Insights;$(RepoRoot)\dev\common;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>(MSBuildThisFileDirectory);$(OutDir)..\KozaniProtocol;$(OutDir)..\KozaniManagerProxyStub;$(OutDir)\..\WindowsAppRuntime_DLL;$(RepoRoot)\dev\WindowsAppRuntime_Insights;$(RepoRoot)\dev\common;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PreprocessorDefinitions>_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>onecore.lib;onecoreuap.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>KozaniProtocol.lib;onecore.lib;onecoreuap.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir)..\KozaniProtocol;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<DelayLoadDLLs>Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
<Midl>
Expand All @@ -109,7 +113,8 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<!-- We only use protobuf Release builds so don't define _DEBUG if you use protobufs (for now) -->
<!-- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> -->
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
Expand All @@ -136,8 +141,12 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="Microsoft.Kozani.Activation.h" />
<ClInclude Include="KozaniManager-Constants.h" />
<ClInclude Include="KozaniManager-Override.h" />
<ClInclude Include="KozaniManagerActivity.h" />
<ClInclude Include="KozaniManagerTraceLogging.h" />
<ClInclude Include="KozaniProtobufMessages.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
Expand All @@ -149,6 +158,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="main.cpp" />
<ClCompile Include="Microsoft.Kozani.Activation.cpp" />
<ClCompile Include="KozaniManagerActivity.cpp" />
<ClCompile Include="KozaniManagerTraceLogging.cpp" />
</ItemGroup>
Expand All @@ -175,6 +185,7 @@
<Import Project="$(NugetPackageDirectory)\Microsoft.SourceLink.GitHub.$(MicrosoftSourceLinkGitHubVersion)\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('$(NugetPackageDirectory)\Microsoft.SourceLink.GitHub.$(MicrosoftSourceLinkGitHubVersion)\build\Microsoft.SourceLink.GitHub.targets')" />
<Import Project="$(NugetPackageDirectory)\Microsoft.Windows.ImplementationLibrary.$(MicrosoftWindowsImplementationLibraryVersion)\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(NugetPackageDirectory)\Microsoft.Windows.ImplementationLibrary.$(MicrosoftWindowsImplementationLibraryVersion)\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="$(NugetPackageDirectory)\Microsoft.Windows.CppWinRT.$(MicrosoftWindowsCppWinRTVersion)\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(NugetPackageDirectory)\Microsoft.Windows.CppWinRT.$(MicrosoftWindowsCppWinRTVersion)\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="$(NugetPackageDirectory)\Microsoft.WindowsAppSDK.Protobuf.$(MicrosoftWindowsAppSDKProtobufVersion)\build\native\Microsoft.WindowsAppSDK.Protobuf.targets" Condition="Exists('$(NugetPackageDirectory)\Microsoft.WindowsAppSDK.Protobuf.$(MicrosoftWindowsAppSDKProtobufVersion)\build\native\Microsoft.WindowsAppSDK.Protobuf.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
Expand All @@ -189,5 +200,7 @@
<Error Condition="!Exists('$(NugetPackageDirectory)\Microsoft.Windows.ImplementationLibrary.$(MicrosoftWindowsImplementationLibraryVersion)\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(NugetPackageDirectory)\Microsoft.Windows.ImplementationLibrary.$(MicrosoftWindowsImplementationLibraryVersion)\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('$(NugetPackageDirectory)\Microsoft.Windows.CppWinRT.$(MicrosoftWindowsCppWinRTVersion)\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(NugetPackageDirectory)\Microsoft.Windows.CppWinRT.$(MicrosoftWindowsCppWinRTVersion)\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('$(NugetPackageDirectory)\Microsoft.Windows.CppWinRT.$(MicrosoftWindowsCppWinRTVersion)\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(NugetPackageDirectory)\Microsoft.Windows.CppWinRT.$(MicrosoftWindowsCppWinRTVersion)\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('$(NugetPackageDirectory)\Microsoft.WindowsAppSDK.Protobuf.$(MicrosoftWindowsAppSDKProtobufVersion)\build\native\Microsoft.WindowsAppSDK.Protobuf.props')" Text="$([System.String]::Format('$(ErrorText)', '$(NugetPackageDirectory)\Microsoft.WindowsAppSDK.Protobuf.$(MicrosoftWindowsAppSDKProtobufVersion)\build\native\Microsoft.WindowsAppSDK.Protobuf.props'))" />
<Error Condition="!Exists('$(NugetPackageDirectory)\Microsoft.WindowsAppSDK.Protobuf.$(MicrosoftWindowsAppSDKProtobufVersion)\build\native\Microsoft.WindowsAppSDK.Protobuf.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(NugetPackageDirectory)\Microsoft.WindowsAppSDK.Protobuf.$(MicrosoftWindowsAppSDKProtobufVersion)\build\native\Microsoft.WindowsAppSDK.Protobuf.targets'))" />
</Target>
</Project>
</Project>
31 changes: 28 additions & 3 deletions dev/Kozani/KozaniManager/KozaniManager.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Microsoft.Kozani.Activation.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KozaniManagerActivity.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand All @@ -32,19 +35,41 @@
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Microsoft.Kozani.Activation.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="KozaniManager-Constants.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="KozaniManager-Override.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="KozaniManagerActivity.h">
<Filter>Source Files</Filter>
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="KozaniManagerTraceLogging.h">
<Filter>Source Files</Filter>
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="KozaniProtobufMessages.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<<<<<<< HEAD
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
</ItemGroup>
<ItemGroup>
=======
>>>>>>> develop
<ResourceCompile Include="KozaniManager.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
<<<<<<< HEAD
</Project>
=======
</Project>
>>>>>>> develop
14 changes: 14 additions & 0 deletions dev/Kozani/KozaniManager/KozaniProtobufMessages.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

#include "pch.h"

// Include all protobuf files here so we can disable any warnings they contain
#pragma warning(push)
#pragma warning(disable : 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable : 4127) // conditional expression is constant
#pragma warning(disable : 5054) // operator '*': deprecated between enumerations of different types

#include <Kozani.Activation.pb.h>

#pragma warning(pop)
66 changes: 66 additions & 0 deletions dev/Kozani/KozaniManager/Microsoft.Kozani.Activation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

#include "pch.h"

#include "Microsoft.Kozani.Activation.h"

std::string Microsoft::Kozani::Activation::ActivateApp(
std::int64_t cookie,
PCWSTR appUserModelId,
::IInspectable* activatedEventArgs)
{
winrt::com_ptr<::IInspectable> inspectable(activatedEventArgs, winrt::take_ownership_from_abi);
auto args{ inspectable.as<winrt::Windows::ApplicationModel::Activation::IActivatedEventArgs>() };
return ActivateApp(cookie, appUserModelId, args);
}

std::string Microsoft::Kozani::Activation::ActivateApp(
std::int64_t cookie,
PCWSTR appUserModelId,
winrt::Windows::ApplicationModel::Activation::IActivatedEventArgs& args)
{
const auto activationKind{ args.Kind() };
if (activationKind == winrt::Windows::ApplicationModel::Activation::ActivationKind::Launch)
{
auto specificArgs{ args.as<winrt::Windows::ApplicationModel::Activation::LaunchActivatedEventArgs>() };
return ActivateApp(cookie, appUserModelId, specificArgs);
}

THROW_HR_MSG(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "ActivationKind:%d", activationKind);
}

std::string Microsoft::Kozani::Activation::ActivateApp(
std::int64_t cookie,
PCWSTR appUserModelId,
winrt::Windows::ApplicationModel::Activation::LaunchActivatedEventArgs& args)
{
const auto arguments{ args.Arguments() };
return ActivateApp_Launch(cookie, appUserModelId, arguments.c_str());
}

std::string Microsoft::Kozani::Activation::ActivateApp_Launch(
std::int64_t cookie,
PCWSTR appUserModelId,
PCWSTR arguments)
{
const std::string appUserModelIdUtf8{ ::Microsoft::Utf8::ToUtf8(appUserModelId) };
const std::string argumentsUtf8{ arguments ? ::Microsoft::Utf8::ToUtf8(arguments) : "" };
return ActivateApp_Launch(cookie, appUserModelIdUtf8, argumentsUtf8);
}

std::string Microsoft::Kozani::Activation::ActivateApp_Launch(
std::int64_t cookie,
const std::string& appUserModelId,
const std::string& arguments)
{
::Microsoft::Kozani::Activation::ActivateAppRequest message;
message.set_cookie(cookie);
message.set_activation_kind(::Microsoft::Kozani::Activation::ActivationKind::Launch);
message.set_app_user_model_id(appUserModelId);
message.set_arguments(arguments);

std::string bytes;
message.SerializeToString(&bytes);
return bytes;
}
Loading

0 comments on commit bdafab1

Please sign in to comment.