Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Odd issue only when publishing via single file - Value cannot be empty string #59

Closed
Deadpikle opened this issue Sep 19, 2023 · 2 comments

Comments

@Deadpikle
Copy link

Deadpikle commented Sep 19, 2023

Hi,

I'm experiencing a weird error that only happens when I publish my app as a single file. It seems to happen on deconstruction, which is odd. My goal is to load a list of solution configs and solution projects so that the user can choose an appropriate pair (config & project).

Here's the stack trace:

Unhandled exception. System.ArgumentException: The value cannot be an empty string. (Parameter 'path')
   at Microsoft.Build.Shared.BuildEnvironmentHelper.get_Instance()
   at Microsoft.Build.Utilities.Traits.get_Instance()
   at Microsoft.Build.Evaluation.ProjectCollection..ctor(IDictionary`2 globalProperties, IEnumerable`1 loggers, IEnumerable`1 remoteLoggers, ToolsetDefinitionLocations toolsetDefinitionLocations, Int32 maxNodeCount, Boolean onlyLogCriticalEvents, Boolean loadProjectsReadOnly)
   at Microsoft.Build.Evaluation.ProjectCollection..ctor(IDictionary`2 globalProperties, IEnumerable`1 loggers, IEnumerable`1 remoteLoggers, ToolsetDefinitionLocations toolsetDefinitionLocations, Int32 maxNodeCount, Boolean onlyLogCriticalEvents)
   at Microsoft.Build.Evaluation.ProjectCollection..ctor(IDictionary`2 globalProperties, IEnumerable`1 loggers, ToolsetDefinitionLocations toolsetDefinitionLocations)
   at Microsoft.Build.Evaluation.ProjectCollection..ctor(IDictionary`2 globalProperties)
   at Microsoft.Build.Evaluation.ProjectCollection..ctor()
   at Microsoft.Build.Evaluation.ProjectCollection.get_GlobalProjectCollection()
   at net.r_eg.MvsSln.Core.XProjectEnv.get_PrjCollection()
   at net.r_eg.MvsSln.Core.XProjectEnv.UnloadAll(Boolean throwIfErr)
   at net.r_eg.MvsSln.Core.IsolatedEnv.Dispose(Boolean _)
   at net.r_eg.MvsSln.Core.IsolatedEnv.Dispose()
   at net.r_eg.MvsSln.Sln.Dispose(Boolean _)
   at net.r_eg.MvsSln.Sln.Dispose()
   [MyApp stack trace here]

Here's the code in MyApp that the stack trace points to:

public static SolutionConfigPlatforms GetConfigurationsInSolution(DotnetProject solution)
{
    if (File.Exists(solution.FilePath))
    {
        using (var sln = new Sln(solution.FilePath, SlnItems.SolutionConfPlatforms | SlnItems.Env))
        {
            var output = new SolutionConfigPlatforms();
            output.DefaultConfig = sln.Result.DefaultConfig.Configuration;
            output.DefaultPlatform = sln.Result.DefaultConfig.Platform;
            foreach (var config in sln.Result.ProjectConfigs)
            {
                output.AddConfig(config.Configuration);
                output.AddPlatform(config.Platform);
            }
            return output; // <----- stack trace points here
        }
    }
    return new SolutionConfigPlatforms();
}

SolutionConfigPlatforms is a simple model defined as:

    class SolutionConfigPlatforms
    {
        public List<string> Configs { get; set; }
        public List<string> Platforms { get; set; }
        public string DefaultConfig { get; set; } // e.g. "Debug"
        public string DefaultPlatform { get; set; } // e.g. "AnyCPU"
         ...
     }

SLN:

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29709.97
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyApp.WPF", "MyApp.WPF\MyApp.WPF.csproj", "{83A590A7-F126-4FB2-8C94-4DF0ED16D5A5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyApp.Tests", "MyApp.Tests\MyApp.Tests.csproj", "{1F4289D8-3E67-46B1-B6B5-5368880F8969}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "MyApp.Shared", "MyApp.Shared\MyApp.Shared.shproj", "{9A68665F-F039-49F2-903D-95EFBDA36C60}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyApp.Avalonia", "MyApp.Avalonia\MyApp.Avalonia.csproj", "{C5C70FF0-E9ED-43AE-9CBC-1BF8CF60F37C}"
EndProject
Global
	GlobalSection(SharedMSBuildProjectFiles) = preSolution
		MyApp.Shared\MyApp.Shared.projitems*{83a590a7-f126-4fb2-8c94-4df0ed16d5a5}*SharedItemsImports = 5
		MyApp.Shared\MyApp.Shared.projitems*{9a68665f-f039-49f2-903d-95efbda36c60}*SharedItemsImports = 13
		MyApp.Shared\MyApp.Shared.projitems*{c5c70ff0-e9ed-43ae-9cbc-1bf8cf60f37c}*SharedItemsImports = 5
	EndGlobalSection
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{83A590A7-F126-4FB2-8C94-4DF0ED16D5A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{83A590A7-F126-4FB2-8C94-4DF0ED16D5A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{83A590A7-F126-4FB2-8C94-4DF0ED16D5A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{83A590A7-F126-4FB2-8C94-4DF0ED16D5A5}.Release|Any CPU.Build.0 = Release|Any CPU
		{1F4289D8-3E67-46B1-B6B5-5368880F8969}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{1F4289D8-3E67-46B1-B6B5-5368880F8969}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{1F4289D8-3E67-46B1-B6B5-5368880F8969}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{1F4289D8-3E67-46B1-B6B5-5368880F8969}.Release|Any CPU.Build.0 = Release|Any CPU
		{C5C70FF0-E9ED-43AE-9CBC-1BF8CF60F37C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{C5C70FF0-E9ED-43AE-9CBC-1BF8CF60F37C}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{C5C70FF0-E9ED-43AE-9CBC-1BF8CF60F37C}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{C5C70FF0-E9ED-43AE-9CBC-1BF8CF60F37C}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {01061048-C1F2-454F-9EA3-831A961CB95F}
	EndGlobalSection
EndGlobal

Note that this code runs on a background thread.

I haven't yet done the dirty work of trying to create a small minimal sample due to running out of time now, but am posting this in hopes that someone may know the answer or what to look at sooner than I will have time to dig in deeper. The issue seems to be deeper in MS-provided code, but am not sure if something is being utilized wrong.

Environment: macOS 12.6.9
.NET Version: .NET 8 RC 1 (this did seem to happen on .NET 7, too)

Build command: dotnet publish "/Users/[name]/Documents/Projects/[Name].csproj" --configuration "Release" --framework "net8.0" --runtime "osx-x64" /p:PublishSingleFile=true --self-contained True

Any help is appreciated!

Thanks~

@Deadpikle Deadpikle changed the title Odd issue only when publishing via single file Odd issue only when publishing via single file - Value cannot be empty string Sep 19, 2023
@3F
Copy link
Owner

3F commented Sep 20, 2023

Hello,

First of all, Env flag is not needed in your code above. To fix the odd behavior, try this:

SlnItems.SolutionConfPlatforms | SlnItems.ProjectConfPlatforms

However,

The real problem is a little deeper if you really need to use SlnItems.Env because MvsSln v2 (#23) partially relies on GlobalProjectCollection (msbuild) which can cause problems like yours (depends on environment).

That's why in the past MvsSln v2.4 introduced XProjectEnv in addition to IsolatedEnv, see #17

In other words,

Modern MvsSln provides two implementation of IXProjectEnv (IsolatedEnv is the default if raised SlnItems.Env). And if your environment also relies on GlobalProjectCollection, you need to consider to implement you custom disposing if needed at all.

Here you can find an example of applied custom disposing between two completely different environments Visual Studio as a VSIX plugin and MSBuild for CI 3F/vsSolutionBuildEvent#53

@Deadpikle
Copy link
Author

Deadpikle commented Sep 24, 2023

First of all, Env flag is not needed in your code above. To fix the odd behavior, try this:

This fixed the problem up real quick. Thank you for your reply and the additional info on how to fix things should I need SlnItems.Env in the future.

Appreciate it — and your library! 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants