I am trying to compile c# source code in powershell by using this command:
Add-Type -ReferencedAssemblies $assemblies -TypeDefinition $source
But c#-6.0 features are not working, for example:
Add-Type : c:\Users\...\AppData\Local\Temp\2\d2q5hn5b.0.cs(101) : Unexpected character '$'
For code:
new Problem($"... ({identifier})", node)
I am using powershell-v5.1
Is there a way to fix this?
The good news – you can add USB-C to your computer, as long as your motherboard supports it. It's quite simple to add USB-C ports to a desktop computer.
If your motherboard has any open PCI-Express slots, you can use an expansion card to add USB-C ports to the rear of the PC. This requires taking off the outer case, removing the corresponding expansion tab, and then installing the new card directly to the motherboard.
Modern desktop and laptop computers all make use of USB-C ports, meaning that they can work with different kinds of peripherals.
Thanks. No it is a feature of the motherboard to only support a data transfer usb-C port. No way to upgrade. No it is a feature of the motherboard to only support a data transfer usb-C port.
Powershell uses CodeDomProvider
to compile their assemblies. The version provided with the framework just supports C# 5, so no new features are available by default.
However, if you provide another CodeDomProvider
, you can compile any language, also C#6. There is a CodeDomProvider
available for Roslyn (the new .NET compiler). You can download it from NuGet and include the assembly using Add-Type
. Then create an instance of the compiler and pass that in the -CodeDomProvider
attribute.
To expand upon Patrick Hoffmans's solution, I was a bit uncomfortable about using the reflection method in unbob's solution as that could potentially break in the future.
I worked out the following powershell
code instead which uses .NET
named classes and interfaces:
#requires -Version 5
# download https://www.nuget.org/packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/ and extract with 7-zip to a location, enter that location on the next line
$DotNetCodeDomLocation = 'C:\Utils\microsoft.codedom.providers.dotnetcompilerplatform.2.0.1'
Add-Type -Path "$DotNetCodeDomLocation\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll"
# using Invoke-Expression moves this class definition to runtime, so it will work after the add-type and the ps5 class interface implementation will succeed
# This uses the public interface ICompilerSettings instead of the private class CompilerSettings
Invoke-Expression -Command @"
class RoslynCompilerSettings : Microsoft.CodeDom.Providers.DotNetCompilerPlatform.ICompilerSettings
{
[string] get_CompilerFullPath()
{
return "$DotNetCodeDomLocation\tools\RoslynLatest\csc.exe"
}
[int] get_CompilerServerTimeToLive()
{
return 10
}
}
"@
$DotNetCodeDomProvider = [Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider]::new([RoslynCompilerSettings]::new())
This can then be used as in the following examples:
To directly add a type to the powershell
instance, with assembly reference example (requires the roslyn
compiler and the above code to be bundled with your script):
Add-Type -CodeDomProvider $DotNetCodeDomProvider -TypeDefinition $your_source_code_block -ReferencedAssemblies @([System.Reflection.Assembly]::GetAssembly([hashtable]).Location)
To compile the code to a dll
for loading in future/other scripts (only requires the resulting dll
file to be bundled with your script):
$DotNetAssemblyParameters = [System.CodeDom.Compiler.CompilerParameters]::new(
@([System.Reflection.Assembly]::GetAssembly([hashtable]).Location),
'path_and_name_for_saved.dll',
$false
)
# you can adjust more compilation settings here if you want, see
# https://docs.microsoft.com/en-us/dotnet/api/system.codedom.compiler.compilerparameters?view=netframework-4.7.2
$compilationResults = $DotNetCodeDomProvider.CompileAssemblyFromSource(
$DotNetAssemblyParameters,
$your_source_code_block
)
The compiled dll
can then be used with a simple Add-Type
:
Add-Type -Path 'path_and_name_for_saved.Dll'
This allows for you to use the latest .NET
compiler in powershell
either inline with your main script if you bundle the CodeDomProvider
dll
and the roslyn
compiler, or you can compile the C#
code out to a dll
so it doesn't have to be recompiled each time the script is run, allowing for easier portability and a faster script run time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With