diff --git a/.pipelines/ESRPSigning_sdk.json b/.pipelines/ESRPSigning_sdk.json
new file mode 100644
index 0000000000..19bbb88a65
--- /dev/null
+++ b/.pipelines/ESRPSigning_sdk.json
@@ -0,0 +1,51 @@
+{
+ "Version": "1.0.0",
+ "UseMinimatch": false,
+ "SignBatches": [
+ {
+ "MatchedPath": [
+ "Microsoft.CmdPal.Extensions.dll",
+ "Microsoft.CmdPal.Extensions.Helpers.dll"
+ ],
+ "SigningInfo": {
+ "Operations": [
+ {
+ "KeyCode": "CP-230012",
+ "OperationSetCode": "SigntoolSign",
+ "Parameters": [
+ {
+ "parameterName": "OpusName",
+ "parameterValue": "Microsoft"
+ },
+ {
+ "parameterName": "OpusInfo",
+ "parameterValue": "http://www.microsoft.com"
+ },
+ {
+ "parameterName": "FileDigest",
+ "parameterValue": "/fd \"SHA256\""
+ },
+ {
+ "parameterName": "PageHash",
+ "parameterValue": "/NPH"
+ },
+ {
+ "parameterName": "TimeStamp",
+ "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
+ }
+ ],
+ "ToolName": "sign",
+ "ToolVersion": "1.0"
+ },
+ {
+ "KeyCode": "CP-230012",
+ "OperationSetCode": "SigntoolVerify",
+ "Parameters": [],
+ "ToolName": "sign",
+ "ToolVersion": "1.0"
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/.pipelines/v2/release.yml b/.pipelines/v2/release.yml
index 7a5b29c1d4..3fb02f13f5 100644
--- a/.pipelines/v2/release.yml
+++ b/.pipelines/v2/release.yml
@@ -105,6 +105,25 @@ extends:
move /Y "Microsoft.PowerToys.Telemetry.2.0.2\build\include\TelemetryBase.cs" "src\common\Telemetry\TelemetryBase.cs" || exit /b 1
displayName: Emplace telemetry files
+ - stage: Build_SDK
+ displayName: Build SDK
+ dependsOn: []
+ jobs:
+ - template: .pipelines/v2/templates/job-build-sdk.yml@self
+ parameters:
+ pool:
+ name: SHINE-INT-L
+ image: SHINE-VS17-Latest
+ os: windows
+ codeSign: true
+ signingIdentity:
+ serviceName: $(SigningServiceName)
+ appId: $(SigningAppId)
+ tenantId: $(SigningTenantId)
+ akvName: $(SigningAKVName)
+ authCertName: $(SigningAuthCertName)
+ signCertName: $(SigningSignCertName)
+
- stage: Publish
displayName: Publish
dependsOn: [Build]
diff --git a/.pipelines/v2/templates/job-build-project.yml b/.pipelines/v2/templates/job-build-project.yml
index 1933b74e8d..34d63a43f2 100644
--- a/.pipelines/v2/templates/job-build-project.yml
+++ b/.pipelines/v2/templates/job-build-project.yml
@@ -228,6 +228,45 @@ jobs:
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_abstracted_utils_dll.json'
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
+ - task: CopyFiles@2
+ displayName: Stage SDK/build
+ inputs:
+ contents: |-
+ "**/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.props"
+ "**/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.targets"
+ flattenFolders: True
+ targetFolder: $(JobOutputDirectory)/sdk/build
+
+ - task: CopyFiles@2
+ displayName: Stage SDK/lib
+ inputs:
+ contents: |-
+ "**/Microsoft.CmdPal.Extensions.Helpers/$(BuildPlatform)/release/WinUI3Apps/CmdPal/Microsoft.CmdPal.Extensions.Helpers.dll"
+ "**/Microsoft.CmdPal.Extensions.Helpers/$(BuildPlatform)/release/WinUI3Apps/CmdPal/Microsoft.CmdPal.Extensions.Helpers.deps.json"
+ flattenFolders: True
+ targetFolder: $(JobOutputDirectory)/sdk/lib/net8.0-windows10.0.19041.0
+
+ - task: CopyFiles@2
+ displayName: Stage SDK/runtimes
+ inputs:
+ flattenFolders: True
+ ${{ if eq(variables['BuildPlatform'],'x64') }}:
+ contents: |-
+ "**/Microsoft.CmdPal.Extensions/$(BuildPlatform)/release/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.dll"
+ targetFolder: $(JobOutputDirectory)/sdk/runtimes/win-$(BuildPlatform)/native/
+ ${{ if eq(variables['BuildPlatform'],'arm64') }}:
+ contents: |-
+ "**/Microsoft.CmdPal.Extensions/$(BuildPlatform)/release/WinUI3Apps/CmdPal/Microsoft.CmdPal.Extensions.dll"
+ targetFolder: $(JobOutputDirectory)/sdk/runtimes/win-$(BuildPlatform)/native/
+
+ - task: CopyFiles@2
+ displayName: Stage SDK/winmd
+ inputs:
+ contents: |-
+ "**/Microsoft.CmdPal.Extensions/$(BuildPlatform)/release/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.winmd"
+ flattenFolders: True
+ targetFolder: $(JobOutputDirectory)/sdk/winmd
+
- task: VSBuild@1
displayName: Create Hosts File Editor package
inputs:
diff --git a/.pipelines/v2/templates/job-build-sdk.yml b/.pipelines/v2/templates/job-build-sdk.yml
new file mode 100644
index 0000000000..f8aa5dca3e
--- /dev/null
+++ b/.pipelines/v2/templates/job-build-sdk.yml
@@ -0,0 +1,91 @@
+parameters:
+ - name: buildConfigurations
+ type: object
+ default:
+ - Release
+ - name: codeSign
+ type: boolean
+ default: false
+ - name: pool
+ type: object
+ default: []
+ - name: signingIdentity
+ type: object
+ default: {}
+ - name: sdkVersionNumber
+ type: string
+ default: '0.0.1'
+
+jobs:
+- job: "BuildSDK"
+ ${{ if ne(length(parameters.pool), 0) }}:
+ pool: ${{ parameters.pool }}
+ displayName: Build SDK
+ timeoutInMinutes: 240
+ cancelTimeoutInMinutes: 1
+ templateContext: # Required when this template is hosted in 1ES PT
+ outputs:
+ - output: pipelineArtifact
+ artifactName: SDK
+ targetPath: $(Build.ArtifactStagingDirectory)
+ steps:
+ - checkout: self
+ clean: true
+ submodules: true
+ persistCredentials: True
+ fetchTags: false
+ fetchDepth: 1
+
+ - pwsh: |-
+ & "$(build.sourcesdirectory)\src\modules\cmdpal\extensionsdk\nuget\BuildSDKHelper.ps1" -Configuration "Release" -VersionOfSDK ${{ parameters.sdkVersionNumber }} -BuildStep "build" -IsAzurePipelineBuild
+ displayName: Build SDK
+
+ - ${{ if eq(parameters.codeSign, true) }}:
+ - template: steps-esrp-signing.yml
+ parameters:
+ displayName: Sign SDK
+ signingIdentity: ${{ parameters.signingIdentity }}
+ inputs:
+ FolderPath: 'src/modules'
+ signType: batchSigning
+ batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_sdk.json'
+ ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
+
+ - pwsh: |-
+ & "$(build.sourcesdirectory)\src\modules\cmdpal\extensionsdk\nuget\BuildSDKHelper.ps1" -Configuration "Release" -VersionOfSDK ${{ parameters.sdkVersionNumber }} -BuildStep "pack" -IsAzurePipelineBuild
+ displayName: Pack SDK
+
+ - task: CopyFiles@2
+ displayName: Copy Nuget to Artifact Staging
+ inputs:
+ sourceFolder: "$(build.sourcesdirectory)/src/modules/cmdpal/extensionsdk/_build"
+ contents: '*.nupkg'
+ targetFolder: '$(Build.ArtifactStagingDirectory)'
+
+ - ${{ if eq(parameters.codeSign, true) }}:
+ - template: steps-esrp-signing.yml
+ parameters:
+ displayName: Sign NuGet packages
+ signingIdentity: ${{ parameters.signingIdentity }}
+ inputs:
+ FolderPath: $(Build.ArtifactStagingDirectory)
+ Pattern: '*.nupkg'
+ UseMinimatch: true
+ signConfigType: inlineSignParams
+ inlineOperation: >-
+ [
+ {
+ "KeyCode": "CP-401405",
+ "OperationCode": "NuGetSign",
+ "Parameters": {},
+ "ToolName": "sign",
+ "ToolVersion": "1.0"
+ },
+ {
+ "KeyCode": "CP-401405",
+ "OperationCode": "NuGetVerify",
+ "Parameters": {},
+ "ToolName": "sign",
+ "ToolVersion": "1.0"
+ }
+ ]
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 9df5e45685..52472cd401 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -30,6 +30,7 @@
+
diff --git a/nuget.config b/nuget.config
index e6a17ffdfe..892716c8d8 100644
--- a/nuget.config
+++ b/nuget.config
@@ -3,10 +3,14 @@
+
+
+
+
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Microsoft.CmdPal.Extensions.Helpers.csproj b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Microsoft.CmdPal.Extensions.Helpers.csproj
index 6682a5c48d..3119d8e62c 100644
--- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Microsoft.CmdPal.Extensions.Helpers.csproj
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Microsoft.CmdPal.Extensions.Helpers.csproj
@@ -7,6 +7,8 @@
false
enable
enable
+ AnyCPU
+ None
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.vcxproj b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.vcxproj
index 15e580160b..9531e2f042 100644
--- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.vcxproj
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.vcxproj
@@ -48,7 +48,7 @@
- $(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal
+ $(SolutionDir)$(Platform)\$(Configuration)\Microsoft.CmdPal.Extensions
obj\$(Platform)\$(Configuration)\
@@ -189,7 +189,4 @@
-
-
-
\ No newline at end of file
diff --git a/src/modules/cmdpal/extensionsdk/nuget/BuildSDKHelper.ps1 b/src/modules/cmdpal/extensionsdk/nuget/BuildSDKHelper.ps1
new file mode 100644
index 0000000000..6005024d8d
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/nuget/BuildSDKHelper.ps1
@@ -0,0 +1,102 @@
+Param(
+ [string]$Configuration = "release",
+ [string]$VersionOfSDK = "0.0.0",
+ [string]$BuildStep = "all",
+ [switch]$IsAzurePipelineBuild = $false,
+ [switch]$Help = $false
+)
+
+$StartTime = Get-Date
+
+if ($Help) {
+ Write-Host @"
+Copyright (c) Microsoft Corporation.
+Licensed under the MIT License.
+
+Syntax:
+ Build.cmd [options]
+
+Description:
+ Builds the Command Palette SDK
+
+Options:
+
+ -Configuration
+ Only build the selected configuration(s)
+ Example: -Configuration Release
+ Example: -Configuration "Debug,Release"
+
+ -VersionOfSDK
+ Set the version number of the build sdk nuget package
+ Example: -VersionOfSDK "1.0.0"
+
+ -Help
+ Display this usage message.
+"@
+ Exit
+}
+
+$ErrorActionPreference = "Stop"
+
+$buildPlatforms = "x64","arm64"
+
+$msbuildPath = &"${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe
+if ($IsAzurePipelineBuild) {
+ $nugetPath = "nuget.exe";
+} else {
+ $nugetPath = (Join-Path $PSScriptRoot "NugetWrapper.cmd")
+}
+
+if (($BuildStep -ieq "all") -Or ($BuildStep -ieq "build")) {
+ & $nugetPath restore (Join-Path $PSScriptRoot "..\..\..\..\..\PowerToys.sln")
+
+ Try {
+ foreach ($config in $Configuration.Split(",")) {
+ foreach ($platform in $buildPlatforms) {
+ $msbuildArgs = @(
+ ("$PSScriptRoot\..\Microsoft.CmdPal.Extensions.Helpers\Microsoft.CmdPal.Extensions.Helpers.csproj"),
+ ("/p:Platform="+$platform),
+ ("/p:Configuration="+$config),
+ ("/binaryLogger:CmdPal.Extensions.$platform.$config.binlog"),
+ ("/p:VersionNumber="+$VersionOfSDK)
+ )
+
+ & $msbuildPath $msbuildArgs
+ }
+ }
+ } Catch {
+ $formatString = "`n{0}`n`n{1}`n`n"
+ $fields = $_, $_.ScriptStackTrace
+ Write-Host ($formatString -f $fields) -ForegroundColor RED
+ Exit 1
+ }
+}
+
+if (($BuildStep -ieq "all") -Or ($BuildStep -ieq "pack")) {
+ foreach ($config in $Configuration.Split(",")) {
+ if ($config -eq "release")
+ {
+ New-Item -ItemType Directory -Force -Path "$PSScriptRoot\..\_build"
+ & $nugetPath pack (Join-Path $PSScriptRoot "Microsoft.CmdPal.Extensions.SDK.nuspec") -Version $VersionOfSDK -OutputDirectory "$PSScriptRoot\..\_build"
+ } else {
+ Write-Host @"
+WARNING: You are currently building as '$config' configuration.
+CmdPalSDK nuget creation only supports 'release' configuration right now.
+"@ -ForegroundColor YELLOW
+ }
+ }
+}
+
+if ($IsAzurePipelineBuild) {
+ Write-Host "##vso[task.setvariable variable=VersionOfSDK;]$VersionOfSDK"
+ Write-Host "##vso[task.setvariable variable=VersionOfSDK;isOutput=true;]$VersionOfSDK"
+}
+
+$TotalTime = (Get-Date)-$StartTime
+$TotalMinutes = [math]::Floor($TotalTime.TotalMinutes)
+$TotalSeconds = [math]::Ceiling($TotalTime.TotalSeconds)
+
+Write-Host @"
+Total Running Time:
+$TotalMinutes minutes and $TotalSeconds seconds
+"@ -ForegroundColor CYAN
\ No newline at end of file
diff --git a/src/modules/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.nuspec b/src/modules/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.nuspec
new file mode 100644
index 0000000000..15af55082b
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.nuspec
@@ -0,0 +1,35 @@
+
+
+
+ Microsoft.CmdPal.Extensions.SDK
+ 0.0.0
+ Command Palette SDK
+ Microsoft
+ Microsoft
+ false
+ Command Palette SDK provides support for creating Command Palette extensions on Windows.
+ Release notes are available in the Power Toys repository.
+ Command Palette Extension SDK
+ © Microsoft Corporation. All rights reserved.
+
+ https://github.com/microsoft/powertoys
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/modules/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.props b/src/modules/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.props
new file mode 100644
index 0000000000..d81221216d
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.props
@@ -0,0 +1,5 @@
+
+
+ $([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', '..'))
+
+
\ No newline at end of file
diff --git a/src/modules/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.targets b/src/modules/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.targets
new file mode 100644
index 0000000000..3c2f6c946b
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/nuget/Microsoft.CmdPal.Extensions.SDK.targets
@@ -0,0 +1,7 @@
+
+
+
+ Always
+
+
+
\ No newline at end of file
diff --git a/src/modules/cmdpal/extensionsdk/nuget/NugetWrapper.cmd b/src/modules/cmdpal/extensionsdk/nuget/NugetWrapper.cmd
new file mode 100644
index 0000000000..62fb6878bd
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/nuget/NugetWrapper.cmd
@@ -0,0 +1,13 @@
+@echo OFF
+setlocal
+
+if "%VisualStudioVersion%" == "" set VisualStudioVersion=15.0
+
+if not exist %TEMP%\nuget.6.4.0.exe (
+ echo Nuget.exe not found in the temp dir, downloading.
+ powershell -Command "& { Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/v6.4.0/nuget.exe -outfile $env:TEMP\nuget.6.4.0.exe }"
+)
+
+%TEMP%\nuget.6.4.0.exe %*
+
+exit /B %ERRORLEVEL%