Fixes errors while dynamically compiling Add-Type

This commit is contained in:
Lord Hepipud 2022-02-09 12:12:20 +01:00
parent c0897c4bce
commit ecc11128cb
5 changed files with 110 additions and 2 deletions

1
.gitignore vendored
View file

@ -7,6 +7,7 @@ cache/*
.vs/ .vs/
*.log *.log
*.pfx *.pfx
*.dll
# JEA # JEA
RoleCapabilities/IcingaForWindows.psrc RoleCapabilities/IcingaForWindows.psrc

View file

@ -11,6 +11,10 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
[Issue and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/20?closed=1) [Issue and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/20?closed=1)
### Bugfixes
* [#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
### Enhancements ### Enhancements
* [#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 * [#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

View file

@ -72,8 +72,8 @@ function Get-IcingaJEAConfiguration()
} }
} }
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)) { 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)) {
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; 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;
} }
} }

View file

@ -0,0 +1,78 @@
<#
.SYNOPSIS
Compiles Add-Type calls as DLL inside our cache/lib folder
.DESCRIPTION
Allows to compile DLLs for .NET related code required for plugins
or certain tasks on the Windows machine, not natively supported by
PowerShell.
All DLL files are compiled within the cache/lib folder within the Framework
and loaded on demand in case required. Once loaded within a shell session,
there the function will simply do nothing
.PARAMETER TypeDefinition
The code to compile a DLL for. Like Add-Type, the code has to start with @"
at the beginning and end with "@ at the very beginning of a new line without
spaces or tabs
.PARAMETER TypeName
The name of the DLL and function being generated. The '.dll' name is NOT required
.PARAMETER Force
Allows to force create the library again and load it inside the shell
.EXAMPLE
$TypeDefinition = @"
/*
Your code
*/
"@
Add-IcingaAddTypeLib -TypeDefinition $TypeDefinition -TypeName 'Example';
#>
function Add-IcingaAddTypeLib()
{
param (
$TypeDefinition = $null,
[string]$TypeName = '',
[switch]$Force = $FALSE
);
# Do nothing if TypeDefinition is null
if ($null -eq $TypeDefinition) {
Write-IcingaConsoleError -Message 'Failed to add type with name "{0}". The TypeDefinition is empty' -Objects $TypeName;
return;
}
# If no name is set, return an error as we require the name for identification
if ([string]::IsNullOrEmpty($TypeName)) {
Write-IcingaConsoleError -Message 'Failed to add type, as no name is specified';
return;
}
# If the type does already exist within our shell, to not load it again
if ((Test-IcingaAddTypeExist -Type $TypeName) -And $Force -eq $FALSE) {
return;
}
# Get our DLL folder
[string]$DLLFolder = (Join-Path -Path (Get-IcingaCacheDir) -ChildPath 'dll');
if ((Test-Path $DLLFolder) -eq $FALSE) {
New-Item -Path $DLLFolder -ItemType 'Directory' | Out-Null;
}
# Update the TypeName to include .dll ending
if ($TypeName.Contains('.dll') -eq $FALSE) {
$TypeName = [string]::Format('{0}.dll', $TypeName);
}
# Create the full path to our file
[string]$DLLPath = Join-Path -Path $DLLFolder -ChildPath $TypeName;
# If the DLL already exist, load the DLL from disk
if ((Test-Path $DLLPath) -And $Force -eq $FALSE) {
Add-Type -Path $DLLPath;
return;
}
# If the DLL does not exist or we use -Force, create it
Add-Type -TypeDefinition $TypeDefinition -OutputType 'Library' -OutputAssembly $DLLPath;
# Load the newly created DLL
Add-Type -Path $DLLPath;
}

View file

@ -0,0 +1,25 @@
<#
.SYNOPSIS
Removes the dll folder from the cache and deletes
all pre-compiled libraries by Icinga for Windows
.DESCRIPTION
Removes the dll folder from the cache and deletes
all pre-compiled libraries by Icinga for Windows
.EXAMPLE
PS> Clear-IcingaAddTypeLib
#>
function Clear-IcingaAddTypeLib()
{
[string]$DLLFolder = (Join-Path -Path (Get-IcingaCacheDir) -ChildPath 'dll');
if ((Test-Path $DLLFolder) -eq $FALSE) {
Write-IcingaConsoleNotice 'The dll folder does not exist';
return;
}
if (Remove-ItemSecure -Path $DLLFolder -Recurse -Force) {
Write-IcingaConsoleNotice 'The dll cache folder was successfully removed';
} else {
Write-IcingaConsoleError 'Failed to remove dll cache folder. Make sure it is not used at the moment and try again'
}
}