Skip to content

Commit 08f75af

Browse files
committed
[posh profile] Add new functions and Readme.
1 parent 1498bb2 commit 08f75af

File tree

4 files changed

+215
-0
lines changed

4 files changed

+215
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright (c) 2023 Matthias Wolf, Mawosoft.
2+
3+
<#
4+
.SYNOPSIS
5+
Gets the StrictMode version applying to the scope of the caller.
6+
This is a pendant to Set-StrictMode.
7+
.OUTPUTS
8+
[version] object of the StrictMode. A value of 0.0 equals -Off, a value of $null indicates
9+
that Set-StrictMode has not be called at all within the caller's scope.
10+
#>
11+
function Get-StrictMode {
12+
[CmdletBinding()]
13+
[OutputType([version])]
14+
param ()
15+
$bflags = [System.Reflection.BindingFlags]'Instance, NonPublic'
16+
# $PSCmdlet.SessionState actually contains the session state of the caller, not the one
17+
# currently applying here.
18+
$state = [System.Management.Automation.SessionState].GetProperty('Internal', $bflags).GetValue($PSCmdlet.SessionState)
19+
[type]$stateType = $state.GetType()
20+
$scope = $stateType.GetProperty('CurrentScope', $bflags).GetValue($state)
21+
$moduleScope = $stateType.GetProperty('ModuleScope', $bflags).GetValue($state)
22+
[type]$scopeType = $scope.GetType()
23+
[System.Reflection.PropertyInfo]$piParent = $scopeType.GetProperty('Parent', $bflags)
24+
[System.Reflection.PropertyInfo]$piMode = $scopeType.GetProperty('StrictModeVersion', $bflags)
25+
while ($null -ne $scope) {
26+
[version]$mode = $piMode.GetValue($scope)
27+
if ($null -ne $mode) {
28+
return $mode
29+
}
30+
# Modules don't inherit strict mode from global scope.
31+
if ($scope -eq $moduleScope) { break }
32+
$scope = $piParent.GetValue($scope)
33+
}
34+
return $null
35+
}

PowerShell/Profile/Common/README.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Notes on Get-StrictMode
2+
3+
Caller scope vs. parent/child scopes.
4+
5+
```
6+
[PSScriptCmdlet] $PSCmdlet
7+
[CommandOrigin] .CommandOrigin (Internal/Runspace)
8+
[MshCommandRuntime] .CommandRuntime (strictly ICommandRuntime)
9+
[PipelineProcessor] .PipelineProcessor
10+
[SessionStateScope] .ExecutionScope $7 (null) <-- Calling command scope
11+
[SessionState] .SessionState
12+
[SessionStateInternal] .Internal $6
13+
[SessionStateScope] .CurrentScope $7 (null) <-- Calling command scope
14+
[SessionState] .InternalState
15+
[SessionStateInternal] .Internal $6
16+
17+
[InvocationInfo] $MyInvocation
18+
19+
[EngineIntrinsics] $ExecutionContext
20+
[SessionState] .SessionState
21+
[SessionStateInternal] .Internal $1
22+
[SessionStateScope] .CurrentScope $2 (4.0.1)
23+
[SessionStateScope] .Parent $4
24+
[SessionStateScope] .ScriptScope $4
25+
[Version] .StrictModeVersion
26+
[ExecutionContext] .ExecutionContext $5
27+
[SessionStateScope] .GlobalScope $3 (3.0)
28+
[PSModuleInfo] .Module
29+
[SessionStateScope] .ModuleScope $4 (4.0)
30+
[SessionStateScope] .ScriptScope $4
31+
[ExecutionContext] ._context $5
32+
[CommandProcessor] CurrentCommandProcessor
33+
[SessionStateScope] .CommandScope $2
34+
[SessionStateInternal] .CommandSessionState $1
35+
[ExecutionContext] .Context $5
36+
[bool] .UseLocalScope (true)
37+
[SessionStateInternal] ._previousCommandSessionState $6
38+
[SessionStateScope] .CurrentScope $7 (null) <-- Calling command scope
39+
[SessionStateScope] .Parent (1.0)
40+
[SessionStateScope] ._previousScope $4 <-- This is misleading and not the calling scope
41+
42+
43+
[CallStackFrame[]] Get-PSCallStack
44+
[CallStackFrame] [0]
45+
[FunctionContext] .FunctionContext
46+
[ExecutionContext] ._executionContext $5
47+
[ScriptBlock] ._scriptBlock
48+
[SessionStateInternal] .SessionStateInternal $1
49+
[CallStackFrame] [1]
50+
[FunctionContext] .FunctionContext
51+
[ExecutionContext] ._executionContext $5
52+
[ScriptBlock] ._scriptBlock
53+
[SessionStateInternal] .SessionStateInternal $6
54+
[SessionStateScope] .CurrentScope $7 (null) <-- Calling command scope
55+
[CallStackFrame] [2]
56+
[FunctionContext] .FunctionContext
57+
[ExecutionContext] ._executionContext $5
58+
[ScriptBlock] ._scriptBlock
59+
[SessionStateInternal] .SessionStateInternal (null, no state, global)
60+
```
61+
62+
global
63+
```powershell
64+
Set-StrictMode -Version 3.0
65+
Get-Mode1
66+
```
67+
68+
StrictMode.psm1
69+
```powershell
70+
Set-StrictMode -Version 4.0
71+
function Get-StrictMode {
72+
[CmdletBinding()]
73+
param()
74+
Set-StrictMode -Version 4.0.1
75+
[ExternalDebugView]::new().View(@(
76+
'PSCmdlet'
77+
$PSCmdlet
78+
'MyInvocation'
79+
$MyInvocation
80+
'ExecutionContext'
81+
$ExecutionContext
82+
'GetPSCallStack'
83+
Get-PSCallStack
84+
))
85+
}
86+
```
87+
88+
Module1.psm1
89+
```powershell
90+
Set-StrictMode -Version 1.0
91+
function Get-Mode1 {
92+
[CmdletBinding()]
93+
param()
94+
Get-StrictMode
95+
}
96+
function Get-Mode2 {
97+
[CmdletBinding()]
98+
param()
99+
Set-StrictMode -Version 1.0.2
100+
Get-StrictMode
101+
}
102+
```
103+
104+
Module2.psm1
105+
```powershell
106+
function Get-Mode3 {
107+
[CmdletBinding()]
108+
param()
109+
Get-StrictMode
110+
}
111+
function Get-Mode4 {
112+
[CmdletBinding()]
113+
param()
114+
Set-StrictMode -Version 4.0.4
115+
Get-StrictMode
116+
}
117+
```
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright (c) 2023 Matthias Wolf, Mawosoft.
2+
3+
<#
4+
.SYNOPSIS
5+
Adds the [ExternalDebugView] class.
6+
.DESCRIPTION
7+
The [ExternalDebugView] class breaks into or launches an external debugger for managed code.
8+
Methods:
9+
public void View(object @object);
10+
Properties:
11+
public static bool DisabledGlobally;
12+
public bool Disabled;
13+
.NOTES
14+
This is wrapped into a function, because using Add-Type -TypeDefinition <sourcecode> is relatively
15+
time-consuming and the feature itself will be used infrequently.
16+
#>
17+
function Add-ExternalDebugView {
18+
[CmdletBinding()]
19+
param()
20+
Add-Type -TypeDefinition @'
21+
using System.Diagnostics;
22+
23+
public sealed class ExternalDebugView
24+
{
25+
private static volatile bool s_disabledGlobally;
26+
27+
public static bool DisabledGlobally
28+
{
29+
// Verbose form for Windows PowerShell
30+
get
31+
{
32+
return s_disabledGlobally;
33+
}
34+
set
35+
{
36+
s_disabledGlobally = value;
37+
}
38+
}
39+
40+
public bool Disabled { get; set; }
41+
42+
// The argument passed to View() is not always accessible in the Debugger.
43+
// We temporarly store it here to work around that issue.
44+
public object Object { get; set; }
45+
46+
public void View(object @object)
47+
{
48+
Object = @object;
49+
if (Disabled || DisabledGlobally) return;
50+
if (Debugger.IsAttached)
51+
{
52+
Debugger.Break();
53+
}
54+
else
55+
{
56+
Debugger.Launch();
57+
}
58+
Object = null;
59+
}
60+
}
61+
'@
62+
}

PowerShell/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Scripts for PowerShell itself.

0 commit comments

Comments
 (0)