LibSassHost icon indicating copy to clipboard operation
LibSassHost copied to clipboard

Calling from Powershell, cannot load dependent assemblies

Open leotohill opened this issue 3 years ago • 4 comments

In Powershell, v5

Add-Type SassLibHost.dll and then New-Object -typeName LibSassHost.SassCompiler

This fails as follows:

New-Object : Exception calling ".ctor" with "0" argument(s): "Failed to load the LibSassHost.Native- assembly, because the directory 'C:\Windows\System32\WindowsPowerShell\v1.0\LibSassHost.Native' does not exist."

I've copied the three dlls into my current directory. Apparently, LibSassHost is searching the load directory of the current application (Powershell) instead of the current directory.

Is there any solution for this?

Also, FYI, running in Powershell 7 fails earlier with the following message. Ps7 is .net core, and LibSassHost is attempting to access a system method that does not exist in core.

System.TypeInitializationException: The type initializer for 'LibSassHost.SassCompiler' threw an exception. ---> System.MissingMethodException: Method not found: 'System.String System.AppDomainSetup.get_PrivateBinPath()'. at LibSassHost.AssemblyResolver.GetBinDirectoryPath(AppDomain currentDomain) at LibSassHost.AssemblyResolver.Initialize() at LibSassHost.SassCompiler..cctor()

leotohill avatar Sep 13 '22 03:09 leotohill

Hello!

I've copied the three dlls into my current directory. Apparently, LibSassHost is searching the load directory of the current application (Powershell) instead of the current directory.

I didn't expect the library to be used in PowerShell. I will try to research this problem.

Also, FYI, running in Powershell 7 fails earlier with the following message. Ps7 is .net core, and LibSassHost is attempting to access a system method that does not exist in core.

System.TypeInitializationException: The type initializer for 'LibSassHost.SassCompiler' threw an exception. ---> System.MissingMethodException: Method not found: 'System.String System.AppDomainSetup.get_PrivateBinPath()'. at LibSassHost.AssemblyResolver.GetBinDirectoryPath(AppDomain currentDomain) at LibSassHost.AssemblyResolver.Initialize() at LibSassHost.SassCompiler..cctor()

This happened because you were trying to use in PowerShell 7 an assembly that targets to .NET Framework. Replace it with an assembly that targets to .NET Standard 2.X and most likely everything will work.

Taritsyn avatar Sep 13 '22 07:09 Taritsyn

I've copied the three dlls into my current directory.

By the way, how did you deploy two native assemblies?

In .NET Framework, it is recommended to do this is as follows:

x64/libsass.dll
x86/libsass.dll
LibSassHost.dll

In .NET Core and .NET 5+:

runtimes/win-x64/libsass.dll
runtimes/win-x86/libsass.dll
LibSassHost.dll

If you clearly know the bitness of the process in which your application will run, then you can simply put one the native assembly next to the managed assembly:

libsass.dll
LibSassHost.dll

Taritsyn avatar Sep 13 '22 08:09 Taritsyn

I now have this working on PS 7. My previous problems were due to using out of date and/or incorrect dlls. FYI, I have success by copying 3 dlls into a run folder. Here's a script fragment that illustrates my success:

$libSassHostDll = Join-Path $solutionRoot "packages"  "LibSassHost.1.3.3" "lib" "\netstandard2.1" "LibSassHost.dll"
Copy-Item $libSassHostDll $runFolder
$libSassDll = Join-Path $solutionRoot "Packages" "LibSassHost.Native.win-x64.1.3.3" "runtimes" "win-x64" "native" "libsass.dll"
Copy-Item $libSassDll $runFolder
$sbDll = Join-Path $solutionRoot "packages" "AdvancedStringBuilder.0.1.0" "lib" "netstandard2.0" "AdvancedStringBuilder.dll"
Copy-Item $sbDll $runFolder
$options = new-object LibSassHost.CompilationOptions
$options.SourceMap = $true
$options.OutputStyle = "Expanded"
# the fileout parameter is required but apparently unused. 
$r = [LibSassHost.SassCompiler]::CompileFile($fileIn, $fileOut, $options)
Out-File -Path $fileOut -InputObject $r.CompiledContent

Two surprises were:

  1. the need to copy in AdvancedStringBuilder.Dll
  2. the fact that the output file parameter to CompileFile is apparently unused.

But in the end, I have success. Thanks for your earlier response.

leotohill avatar Sep 14 '22 16:09 leotohill

Hello!

$libSassDll = Join-Path $solutionRoot "Packages" "LibSassHost.Native.win-x64.1.3.3" "runtimes" "win-x64" "native" "libsass.dll" Copy-Item $libSassDll $runFolder

Unfortunately, I forgot about the native subfolder.

  1. the need to copy in AdvancedStringBuilder.Dll

I also forgot, but it's good that this is an explicit dependency.

  1. the fact that the output file parameter to CompileFile is apparently unused.

It's all meant to be. The outputPath parameter is used when generating a source map. In general, this functionality has been discussed many times.

Taritsyn avatar Sep 14 '22 16:09 Taritsyn