Skip to content

Commit 3bfae4f

Browse files
dantraMSFTdaxian-dbw
authored andcommitted
Rename/Update PowerShell ETW manifest to remove the Windows PowerShell dependency. (PowerShell#5360)
- Build PowerShell.Core.Instrumentation.dll - Resource-only binary for the ETW resources. - Create a registration script for registering/unregistering the ETW provider.
1 parent b194731 commit 3bfae4f

6 files changed

Lines changed: 207 additions & 5 deletions

File tree

build.psm1

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,24 @@ cmd.exe /C cd /d "$location" "&" "$($vcPath)\vcvarsall.bat" "$Arch" "&" cmake "$
257257
log " Copying $srcPath to $dstPath"
258258
Copy-Item $srcPath $dstPath
259259
}
260+
261+
#
262+
# Build the ETW manifest resource-only binary
263+
#
264+
$location = "$PSScriptRoot\src\PowerShell.Core.Instrumentation"
265+
Set-Location -Path $location
266+
267+
$command = @"
268+
cmd.exe /C cd /d "$location" "&" "$($vcPath)\vcvarsall.bat" "$Arch" "&" cmake "$overrideFlags" -DBUILD_ONECORE=ON -DBUILD_TARGET_ARCH=$Arch -G "$cmakeGenerator" . "&" msbuild ALL_BUILD.vcxproj "/p:Configuration=$Configuration"
269+
"@
270+
log " Executing Build Command for PowerShell.Core.Instrumentation: $command"
271+
Start-NativeExecution { Invoke-Expression -Command:$command }
272+
273+
# Copy the binary to the packaging directory
274+
# NOTE: No PDB file; it's a resource-only DLL.
275+
$srcPath = [IO.Path]::Combine($location, $Configuration, 'PowerShell.Core.Instrumentation.dll')
276+
Copy-Item -Path $srcPath -Destination $dstPath
277+
260278
} finally {
261279
Pop-Location
262280
}
@@ -600,7 +618,7 @@ function New-PSOptions {
600618
[string]$Output,
601619

602620
[switch]$SMAOnly,
603-
621+
604622
[switch]$PSModuleRestore
605623
)
606624

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
#
3+
# Builds PowerShell.Core.Instrumentation.dll resource-only DLL containing ETW event resources
4+
#
5+
6+
# The fully qualified path to the event manifest
7+
SET(EVENTS_MANIFEST "${CMAKE_CURRENT_SOURCE_DIR}/PowerShell.Core.Instrumentation.man")
8+
9+
# User mode manifest resource-only dll
10+
function(add_manifest_binary)
11+
12+
add_definitions(-D_DLL=1)
13+
add_library(${ARGV})
14+
15+
# NOTE: EVENTS_MANIFEST must be the fully qualified path to the manifest
16+
SET(MC_MANIFEST_FULLNAME ${EVENTS_MANIFEST})
17+
18+
# get the ETW manifest's filename without the directory or extension
19+
get_filename_component(MC_MANIFEST_BASENAME ${EVENTS_MANIFEST} NAME_WE)
20+
21+
SET(MC_COMMAND "mc.exe")
22+
SET(GeneratedManifestFiles)
23+
24+
# The target directory for generated managed files
25+
SET (MC_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}")
26+
27+
# include the generated directory in the include path
28+
include_directories("${MC_GENERATED_DIR}")
29+
30+
SET (MC_GENERATED_FILES
31+
${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}.rc
32+
${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}TEMP.BIN
33+
${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}_MSG00001.BIN
34+
)
35+
36+
SET(MC_COMMAND "mc.exe -h ${MC_GENERATED_DIR} -r ${MC_GENERATED_DIR} ${MC_MANIFEST_FULLNAME}")
37+
38+
add_custom_command(
39+
COMMENT "Generating native event manifest files for ${EVENTS_MANIFEST}"
40+
OUTPUT ${MC_GENERATED_FILES}
41+
DEPENDS ${MC_MANIFEST_FULLNAME}
42+
COMMAND cmd.exe /c ${MC_COMMAND}
43+
WORKING_DIRECTORY ${MC_GENERATED_DIR}
44+
VERBATIM
45+
)
46+
47+
list (APPEND GeneratedManifestFiles ${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}.rc)
48+
49+
set_source_files_properties(${GeneratedManifestFiles} PROPERTIES GENERATED TRUE)
50+
add_custom_target(GeneratedManifestFiles DEPENDS ${GeneratedManifestFiles})
51+
52+
# for a resource only dll, cmake can report an error
53+
# if there is no linker language set.
54+
# CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
55+
# Missing variable is: CMAKE_RC_CREATE_SHARED_LIBRARY
56+
get_property(isSet TARGET ${ARGV0} PROPERTY LINKER_LANGUAGE SET)
57+
if (NOT ${isSet})
58+
set_target_properties(${ARGV0} PROPERTIES LINKER_LANGUAGE "CXX")
59+
endif()
60+
61+
set_target_properties(${ARGV0} PROPERTIES LINK_FLAGS "/NODEFAULTLIB /NOENTRY")
62+
63+
if (BUILD_ONECORE)
64+
set_target_properties(${ARGV0} PROPERTIES COMPILE_DEFINITIONS "CORECLR")
65+
endif (BUILD_ONECORE)
66+
67+
# ensure the target is dependent on the generated files.
68+
add_dependencies(${ARGV0} GeneratedManifestFiles)
69+
70+
endfunction()
71+
72+
file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/version.rc)
73+
74+
add_manifest_binary(PowerShell.Core.Instrumentation SHARED ${SOURCES})
75+

tools/ResxGen/PowerShell-Core-Instrumentation.man renamed to src/PowerShell.Core.Instrumentation/PowerShell.Core.Instrumentation.man

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<assemblyIdentity
1313
buildType="$(build.buildType)"
1414
language="neutral"
15-
name="PowerShellCore-Instrumentation"
15+
name="PowerShell.Core.Instrumentation"
1616
processorArchitecture="msil"
1717
publicKeyToken="$(build.WindowsPublicKeyToken)"
1818
version="$(build.version)"
@@ -31,9 +31,9 @@
3131
first uninstalled and then installed again (using wevtutil)-->
3232
<provider
3333
guid="{f90714a8-5509-434a-bf6d-b1624c8a19a2}"
34-
messageFileName="System.Management.Automation.dll"
34+
messageFileName="PowerShell.Core.Instrumentation.dll"
3535
name="PowerShellCore"
36-
resourceFileName="System.Management.Automation.dll"
36+
resourceFileName="PowerShell.Core.Instrumentation.dll"
3737
symbol="PS_PROVIDER"
3838
>
3939
<!--The following section defines the events which can be written
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<#
2+
.Synopsis
3+
Registers or unregisters the PowerShell ETW manifest
4+
.Parameter Path
5+
The fully qualified path to the PowerShell.Core.Instrumentation.man manifest file.
6+
The default value is the location of this script.
7+
8+
.Parameter Unregister
9+
Specify to unregister the manifest.
10+
.Notes
11+
The PowerShell.Core.Instrumentation.man and PowerShell.Core.Instrumentation.dll files are
12+
expected to be at the location specified by the Path parameter.
13+
When registered, PowerShell.Core.Instrumentation.dll is locked to prevent deleting or changing.
14+
To update the binary, first unregister the manifest using the -Unregister switch.
15+
#>
16+
[CmdletBinding()]
17+
param
18+
(
19+
[ValidateNotNullOrEmpty()]
20+
[string] $Path = $PSScriptRoot,
21+
22+
[switch] $Unregister
23+
)
24+
Set-StrictMode -Version Latest
25+
$ErrorActionPreference = 'Stop'
26+
27+
function Start-NativeExecution([scriptblock]$sb, [switch]$IgnoreExitcode)
28+
{
29+
$backupEAP = $script:ErrorActionPreference
30+
$script:ErrorActionPreference = "Continue"
31+
try
32+
{
33+
& $sb
34+
# note, if $sb doesn't have a native invocation, $LASTEXITCODE will
35+
# point to the obsolete value
36+
if ($LASTEXITCODE -ne 0 -and -not $IgnoreExitcode)
37+
{
38+
throw "Execution of {$sb} failed with exit code $LASTEXITCODE"
39+
}
40+
}
41+
finally
42+
{
43+
$script:ErrorActionPreference = $backupEAP
44+
}
45+
}
46+
47+
function Test-Elevated
48+
{
49+
[CmdletBinding()]
50+
[OutputType([bool])]
51+
Param()
52+
53+
# if the current Powershell session was called with administrator privileges,
54+
# the Administrator Group's well-known SID will show up in the Groups for the current identity.
55+
# Note that the SID won't show up unless the process is elevated.
56+
return (([Security.Principal.WindowsIdentity]::GetCurrent()).Groups -contains "S-1-5-32-544")
57+
}
58+
$IsWindowsOs = $PSHOME.EndsWith('\WindowsPowerShell\v1.0', [System.StringComparison]::OrdinalIgnoreCase) -or $IsWindows
59+
60+
if (-not $IsWindowsOs)
61+
{
62+
throw 'This script must be run on Windows.'
63+
}
64+
65+
if (-not (Test-Elevated))
66+
{
67+
throw 'This script must be run from an elevated process.'
68+
}
69+
70+
$manifest = Get-Item -Path (Join-Path -Path $Path -ChildPath 'PowerShell.Core.Instrumentation.man')
71+
$binary = Get-Item -Path (Join-Path -Path $Path -ChildPath 'PowerShell.Core.Instrumentation.dll')
72+
73+
$files = @($manifest, $binary)
74+
foreach ($file in $files)
75+
{
76+
if (-not (Test-Path -Path $file))
77+
{
78+
throw "Could not find $($file.Name) at $Path"
79+
}
80+
}
81+
82+
[string] $command = "wevtutil um {0}" -f $manifest.FullName
83+
84+
# Unregister if present. Avoids warnings when registering the manifest
85+
# and it is already registered.
86+
Write-Verbose "unregister the manifest, if present: $command"
87+
Start-NativeExecution {Invoke-Expression $command} $true
88+
89+
if (-not $Unregister)
90+
{
91+
$command = "wevtutil.exe im {0} /rf:{1} /mf:{1}" -f $manifest.FullName, $binary.FullName
92+
Write-Verbose -Message "Register the manifest: $command"
93+
Start-NativeExecution { Invoke-Expression $command }
94+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// Copyright (C) Microsoft. All rights reserved.
3+
//
4+
#include <windows.h>
5+
#include <ntverp.h>
6+
7+
#define VER_FILETYPE VFT_DLL
8+
#define VER_FILESUBTYPE VFT2_UNKNOWN
9+
#define VER_FILEDESCRIPTION_STR "PowerShellCore"
10+
#define VER_INTERNALNAME_STR "PowerShell.Core.Instrumentation.dll"
11+
#define VER_ORIGINALFILENAME_STR "PowerShell.Core.Instrumentation.dll"
12+
13+
#include "common.ver"
14+
15+
#include "PowerShell.Core.Instrumentation.rc"

src/powershell-win-core/powershell-win-core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
2020
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
2121
</Content>
22-
<Content Include="..\..\license_thirdparty_proprietary.txt;..\..\DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY;..\powershell-native\Install-PowerShellRemoting.ps1">
22+
<Content Include="..\..\license_thirdparty_proprietary.txt;..\..\DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY;..\powershell-native\Install-PowerShellRemoting.ps1;..\PowerShell.Core.Instrumentation\PowerShell.Core.Instrumentation.man;..\PowerShell.Core.Instrumentation\RegisterManifest.ps1">
2323
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
2424
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
2525
</Content>

0 commit comments

Comments
 (0)