I am trying to create and import a PowerShell module written in F#. However, I am encountering issues when attempting to import the compiled DLL into PowerShell.
F# Code (Library.fs)
// Library.fs
namespace HiThereFsharp
open System
open System.Management.Automation
[<Cmdlet(VerbsCommon.Get, "Greeting")>]
type HelloWorld() =
inherit PSCmdlet()
let mutable name = ""
[<Parameter(ValueFromPipeline = true)>]
member this.Name
with get () = name
and set (value) = name <- value
override this.ProcessRecord() =
let whoDat =
if String.IsNullOrEmpty(name) then
"World"
else
name
let greeting = "Hello " + whoDat
this.WriteObject(greeting)
I built the project using:
PS ~/RiderProjects/HiThereFsharp> dotnet build
which completed successfully. The output DLL is located at:
/home/deca/RiderProjects/HiThereFsharp/HiThereFsharp/bin/Debug/net8.0/HiThereFsharp.dll
When I try to import the module:
PS ~/RiderProjects/HiThereFsharp> Import-Module /home/deca/RiderProjects/HiThereFsharp/HiThereFsharp/bin/Debug/net8.0/HiThereFsharp.dll
I get the error:
Import-Module: Could not load file or assembly 'FSharp.Core, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
To resolve the missing FSharp.Core.dll
, I ran:
dotnet publish -c Debug -o ./out -r linux-x64 --self-contained true
Now my out
folder contains FSharp.Core.dll
. However, when trying to import the module again:
PS ~/RiderProjects/HiThereFsharp/HiThereFsharp> Import-Module ./out/HiThereFsharp.dll
I get a different error:
Import-Module: Could not load file or assembly 'HiThereFsharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Assembly with same name is already loaded
I tried removing the module before re-importing it:
Remove-Module HiThereFsharp
This resulted in:
Remove-Module: No modules were removed. Verify that the specification of modules to remove is correct and those modules exist in the runspace.
Attempting to force import:
Import-Module -Force ./out/HiThereFsharp.dll
Results in the same error:
Import-Module: Could not load file or assembly 'HiThereFsharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Assembly with same name is already loaded
Environment Information
My Csharp version works
namespace HiThere;
using System;
using System.Management.Automation;
[Cmdlet(VerbsCommon.Get, "Greeting")]
public class HelloWorld : PSCmdlet
{
[Parameter(ValueFromPipeline = true)]
public string Name { get; set;}
protected override void ProcessRecord()
{
var whoDat = string.IsNullOrEmpty(Name) ? "World" : Name;
var greeting = "Hello " + whoDat;
WriteObject(greeting);
}
}
PS ~/Documents/Programming/Csharp/HiThere> dotnet build
MSBuild version 17.8.5+b5265ef37 for .NET
Determining projects to restore...
All projects are up-to-date for restore.
HiThere -> /home/deca/Documents/Programming/Csharp/HiThere/bin/Debug/net8.0/HiThere.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.95
PS ~/Documents/Programming/Csharp/HiThere> Import-Module /home/deca/Documents/Programming/Csharp/HiThere/bin/Debug/net8.0/HiThere.dll
PS ~/Documents/Programming/Csharp/HiThere> Get-Greeting -Name ""
Hello World
I'm not really sure what I'm doing wrong. Any insights would be greatly appreciated!
You cannot in .NET Core and beyond (generally) unload an assembly (you could in .NET Framework via AppDomains).
Each test you run you need to start a new pwsh
instance. When doing this I generally make use of the command line to run a script which does the loading and then leaves me at the new prompt.
This also has the advantage of being in a consistent state (subject to bugs) each time making isolating issues much easier.
(Unloading modules only works if it is purely PowserShell code.)