Skip to content

Commit ecc1112

Browse files
committed
Fixes errors while dynamically compiling Add-Type
1 parent c0897c4 commit ecc1112

File tree

5 files changed

+110
-2
lines changed

5 files changed

+110
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ cache/*
77
.vs/
88
*.log
99
*.pfx
10+
*.dll
1011

1112
# JEA
1213
RoleCapabilities/IcingaForWindows.psrc

doc/100-General/10-Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
1111

1212
[Issue and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/20?closed=1)
1313

14+
### Bugfixes
15+
16+
* [#472](https://github.com/Icinga/icinga-powershell-framework/pull/472) Fixes random errors while dynamically compiling Add-Type code by now writing a DLL inside `cache/dll` for later usage
17+
1418
### Enhancements
1519

1620
* [#469](https://github.com/Icinga/icinga-powershell-framework/pull/469) Improves plugin doc generator to allow multi-lines in code examples and updates plugin overview as table, adding a short description on what the plugin is for

lib/core/jea/Get-IcingaJEAConfiguration.psm1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ function Get-IcingaJEAConfiguration()
7272
}
7373
}
7474

75-
if ($null -ne (Select-String -InputObject $SourceCode -Pattern 'add-type' -SimpleMatch) -Or $null -ne (Select-String -InputObject $SourceCode -Pattern 'typedefinition@"' -SimpleMatch) -Or $null -ne (Select-String -InputObject $SourceCode -Pattern '@"' -SimpleMatch)) {
76-
Write-IcingaConsoleWarning 'The module "{0}" is using "Add-Type" definitions for file "{1}". Ensure you validate the code before trusting this publisher.' -Objects $module.Name, $PSFile.FullName;
75+
if ($null -ne (Select-String -InputObject $SourceCode -Pattern 'add-type' -SimpleMatch) -Or $null -ne (Select-String -InputObject $SourceCode -Pattern 'add-icingaaddtypelib' -SimpleMatch) -Or $null -ne (Select-String -InputObject $SourceCode -Pattern 'typedefinition@"' -SimpleMatch) -Or $null -ne (Select-String -InputObject $SourceCode -Pattern '@"' -SimpleMatch)) {
76+
Write-IcingaConsoleWarning 'The module "{0}" is using "Add-Type" or "Add-IcingaAddTypeLib" definitions for file "{1}". Ensure you validate the code before trusting this publisher.' -Objects $module.Name, $PSFile.FullName;
7777
}
7878
}
7979

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<#
2+
.SYNOPSIS
3+
Compiles Add-Type calls as DLL inside our cache/lib folder
4+
.DESCRIPTION
5+
Allows to compile DLLs for .NET related code required for plugins
6+
or certain tasks on the Windows machine, not natively supported by
7+
PowerShell.
8+
9+
All DLL files are compiled within the cache/lib folder within the Framework
10+
and loaded on demand in case required. Once loaded within a shell session,
11+
there the function will simply do nothing
12+
.PARAMETER TypeDefinition
13+
The code to compile a DLL for. Like Add-Type, the code has to start with @"
14+
at the beginning and end with "@ at the very beginning of a new line without
15+
spaces or tabs
16+
.PARAMETER TypeName
17+
The name of the DLL and function being generated. The '.dll' name is NOT required
18+
.PARAMETER Force
19+
Allows to force create the library again and load it inside the shell
20+
.EXAMPLE
21+
$TypeDefinition = @"
22+
/*
23+
Your code
24+
*/
25+
"@
26+
Add-IcingaAddTypeLib -TypeDefinition $TypeDefinition -TypeName 'Example';
27+
#>
28+
function Add-IcingaAddTypeLib()
29+
{
30+
param (
31+
$TypeDefinition = $null,
32+
[string]$TypeName = '',
33+
[switch]$Force = $FALSE
34+
);
35+
36+
# Do nothing if TypeDefinition is null
37+
if ($null -eq $TypeDefinition) {
38+
Write-IcingaConsoleError -Message 'Failed to add type with name "{0}". The TypeDefinition is empty' -Objects $TypeName;
39+
return;
40+
}
41+
42+
# If no name is set, return an error as we require the name for identification
43+
if ([string]::IsNullOrEmpty($TypeName)) {
44+
Write-IcingaConsoleError -Message 'Failed to add type, as no name is specified';
45+
return;
46+
}
47+
48+
# If the type does already exist within our shell, to not load it again
49+
if ((Test-IcingaAddTypeExist -Type $TypeName) -And $Force -eq $FALSE) {
50+
return;
51+
}
52+
53+
# Get our DLL folder
54+
[string]$DLLFolder = (Join-Path -Path (Get-IcingaCacheDir) -ChildPath 'dll');
55+
56+
if ((Test-Path $DLLFolder) -eq $FALSE) {
57+
New-Item -Path $DLLFolder -ItemType 'Directory' | Out-Null;
58+
}
59+
60+
# Update the TypeName to include .dll ending
61+
if ($TypeName.Contains('.dll') -eq $FALSE) {
62+
$TypeName = [string]::Format('{0}.dll', $TypeName);
63+
}
64+
65+
# Create the full path to our file
66+
[string]$DLLPath = Join-Path -Path $DLLFolder -ChildPath $TypeName;
67+
68+
# If the DLL already exist, load the DLL from disk
69+
if ((Test-Path $DLLPath) -And $Force -eq $FALSE) {
70+
Add-Type -Path $DLLPath;
71+
return;
72+
}
73+
74+
# If the DLL does not exist or we use -Force, create it
75+
Add-Type -TypeDefinition $TypeDefinition -OutputType 'Library' -OutputAssembly $DLLPath;
76+
# Load the newly created DLL
77+
Add-Type -Path $DLLPath;
78+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<#
2+
.SYNOPSIS
3+
Removes the dll folder from the cache and deletes
4+
all pre-compiled libraries by Icinga for Windows
5+
.DESCRIPTION
6+
Removes the dll folder from the cache and deletes
7+
all pre-compiled libraries by Icinga for Windows
8+
.EXAMPLE
9+
PS> Clear-IcingaAddTypeLib
10+
#>
11+
function Clear-IcingaAddTypeLib()
12+
{
13+
[string]$DLLFolder = (Join-Path -Path (Get-IcingaCacheDir) -ChildPath 'dll');
14+
15+
if ((Test-Path $DLLFolder) -eq $FALSE) {
16+
Write-IcingaConsoleNotice 'The dll folder does not exist';
17+
return;
18+
}
19+
20+
if (Remove-ItemSecure -Path $DLLFolder -Recurse -Force) {
21+
Write-IcingaConsoleNotice 'The dll cache folder was successfully removed';
22+
} else {
23+
Write-IcingaConsoleError 'Failed to remove dll cache folder. Make sure it is not used at the moment and try again'
24+
}
25+
}

0 commit comments

Comments
 (0)