Skip to content

Commit

Permalink
program: fix computation of app path with single file
Browse files Browse the repository at this point in the history
When publishing GCM as a 'single file' application, the computed path to
the entry executable is no longer correct.

On .NET Core 3.1, using Assembly.Location resolves to the temporary
extracted DLL file path. On .NET 5 Assembly.Location always returns the
empty string.

Since .NET 5, published single-file apps no longer use the self-
extraction model, and are real single file with all assemblies and
native libraries statically linked/bundled.

We now use the Environment.GetCommandLineArgs() method to get the raw
underlying "argv" arguments, which argv[0] is the absolute file path to
the entry executable.
  • Loading branch information
mjcheetham committed Feb 25, 2021
1 parent 7269802 commit ba9792a
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions src/shared/Git-Credential-Manager/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using Atlassian.Bitbucket;
using GitHub;
using Microsoft.AzureRepos;
Expand Down Expand Up @@ -36,16 +37,17 @@ public static void Main(string[] args)

private static string GetApplicationPath()
{
Assembly entryAssembly = Assembly.GetExecutingAssembly();
if (entryAssembly is null)
{
throw new InvalidOperationException();
}
// Assembly::Location always returns an empty string if the application was published as a single file
bool isSingleFile = string.IsNullOrEmpty(Assembly.GetEntryAssembly()?.Location);

string candidatePath = entryAssembly.Location;
// Use "argv[0]" to get the full path to the entry executable - this is consistent across
// .NET Framework and .NET >= 5 when published as a single file.
string[] args = Environment.GetCommandLineArgs();
string candidatePath = args[0];

// Strip the .dll from assembly name on Mac and Linux
if (!PlatformUtils.IsWindows() && Path.HasExtension(candidatePath))
// If we have not been published as a single file on .NET 5 then we must strip the ".dll" file extension
// to get the default AppHost/SuperHost name.
if (!isSingleFile && Path.HasExtension(candidatePath))
{
return Path.ChangeExtension(candidatePath, null);
}
Expand Down

0 comments on commit ba9792a

Please sign in to comment.