Probably the wrong repo to report this and most likely I did something wrong. I get an exception when I try to create a runspace in a console application published as a single file. Runs fine when published normally.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.1.0-preview.6" />
</ItemGroup>
</Project>
using System;
using System.Management.Automation.Runspaces;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var rs = RunspaceFactory.CreateRunspace();
Console.WriteLine("Hello World!");
}
}
}
dotnet publish -r win-x64 --self-contained false /p:PublishSingleFile=true
Hello World
Unhandled exception. System.TypeInitializationException: The type initializer for 'System.Management.Automation.PSVersionInfo' threw an exception.
---> System.ArgumentException: The path is empty. (Parameter 'path')
at System.IO.Path.GetFullPath(String path)
at System.Diagnostics.FileVersionInfo.GetVersionInfo(String fileName)
at System.Management.Automation.PSVersionInfo..cctor()
--- End of inner exception stack trace ---
at System.Management.Automation.PSVersionInfo.get_PSVersion()
at Microsoft.PowerShell.DefaultHost..ctor(CultureInfo currentCulture, CultureInfo currentUICulture)
at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace()
at ConsoleApp1.Program.Main(String[] args)
dotnet --info
.NET SDK (reflecting any global.json):
Version: 5.0.100-preview.8.20417.9
Commit: fc62663a35
Runtime Environment:
OS Name: Windows
OS Version: 10.0.19041
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.100-preview.8.20417.9\
Host (useful for support):
Version: 5.0.0-preview.8.20407.11
Commit: bf456654f9
.NET SDKs installed:
5.0.100-preview.8.20417.9 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.NETCore.App 5.0.0-preview.8.20407.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 5.0.0-preview.8.20411.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
I tried to compile PowerShell to single file a month ago with the same result.
I guess the exception comes from follow line:
c#
string assemblyPath = typeof(PSVersionInfo).Assembly.Location;
I found 29 such patterns in PowerShell code. And I don't know whether the exception is a .Net bug or we should use another pattern/workaround.
I think the scenario (single file) has a right to exist and we could support it in next milestone.
It is a question for PowerShell Committee.
/cc @SteveL-MSFT @daxian-dbw
@iSazonov same problem occurs when trying to publish a Blazor webassembly with SMA. (Not the only one).
My initial report is not entirely correct. I claimed that a normal publish works. That's not true, at least not on my box. It works fine with a simple build in release mode from Visual Studio 2019 Preview.
dotnet publish -c release
However, as soon as I publish the solution with a runtime identifier (which is required for single file publish), the binary explodes upon startup. Publishing to win-x64 does not work.
dotnet publish -c release -r win-x64
@iSazonov We need to first understand what is the problem before having the committee involved.
@daxian-dbw My question is does PowerShell team want to support single file build scenario? If yes we can start to investigate problems in implementation of the scenario.
API | Note
-- | --
Assembly.Location | Returns an empty string.
Module.FullyQualifiedName | Returns a string with the value of聽
Module.Name | Returns a string with the value of聽
Assembly.GetFile | Throws聽IOException.
Assembly.GetFiles | Throws聽IOException.
Assembly.CodeBase | Throws聽PlatformNotSupportedException.
Assembly.EscapedCodeBase | Throws聽PlatformNotSupportedException.
AssemblyName.CodeBase | Returns聽null.
AssemblyName.EscapedCodeBase | Returns聽null.
Action | Recommendation
-- | --
To access files next to the executable | use AppContext.BaseDirectory.
To find the file name of the executable | use the first element of Environment.GetCommandLineArgs().
To avoid shipping loose files entirely | consider using embedded resources.
Actual behaviour :
Unhandled exception. System.TypeInitializationException: The type initializer for 'System.Management.Automation.PSVersionInfo' threw an exception.
---> System.ArgumentException: The path is empty. (Parameter 'path')
at System.IO.Path.GetFullPath(String path)
at System.Diagnostics.FileVersionInfo.GetVersionInfo(String fileName)
at System.Management.Automation.PSVersionInfo..cctor()
--- End of inner exception stack trace ---
at System.Management.Automation.PSVersionInfo.get_PSVersion()
at Microsoft.PowerShell.DefaultHost..ctor(CultureInfo currentCulture, CultureInfo currentUICulture)
at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace()
at ConsoleApp1.Program.Main(String[] args)
should be replaced by a safer way to get the product info (from the custom attributes of the assembly)
string productVersion = typeof(PSVersionInfo).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion.Trim();
Most helpful comment
API incompatibility :
API | Note聽or throws an exception..
-- | --
Assembly.Location | Returns an empty string.
Module.FullyQualifiedName | Returns a string with the value of聽
Module.Name | Returns a string with the value of聽
Assembly.GetFile | Throws聽IOException.
Assembly.GetFiles | Throws聽IOException.
Assembly.CodeBase | Throws聽PlatformNotSupportedException.
Assembly.EscapedCodeBase | Throws聽PlatformNotSupportedException.
AssemblyName.CodeBase | Returns聽null.
AssemblyName.EscapedCodeBase | Returns聽null.
Recommendations :
Action | Recommendation
-- | --
To access files next to the executable | use AppContext.BaseDirectory.
To find the file name of the executable | use the first element of Environment.GetCommandLineArgs().
To avoid shipping loose files entirely | consider using embedded resources.
Other considerations
Source : Single file deployment and API incompatibility