diff --git a/src/shared/Git-Credential-Manager/Program.cs b/src/shared/Git-Credential-Manager/Program.cs index 4329dc65a..1dc953202 100644 --- a/src/shared/Git-Credential-Manager/Program.cs +++ b/src/shared/Git-Credential-Manager/Program.cs @@ -3,6 +3,7 @@ using System; using System.IO; using System.Reflection; +using System.Runtime.InteropServices; using Atlassian.Bitbucket; using GitHub; using Microsoft.AzureRepos; @@ -36,16 +37,19 @@ 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 +#pragma warning disable IL3000 + bool isSingleFile = string.IsNullOrEmpty(Assembly.GetEntryAssembly()?.Location); +#pragma warning restore IL3000 - 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); } diff --git a/src/shared/Microsoft.Git.CredentialManager/Application.cs b/src/shared/Microsoft.Git.CredentialManager/Application.cs index 21ac00b23..d57aaf8aa 100644 --- a/src/shared/Microsoft.Git.CredentialManager/Application.cs +++ b/src/shared/Microsoft.Git.CredentialManager/Application.cs @@ -76,8 +76,13 @@ protected override async Task RunInternalAsync(string[] args) rootCommand.AddCommand(providerCommand); } - // Trace the current version and program arguments - Context.Trace.WriteLine($"{Constants.GetProgramHeader()} '{string.Join(" ", args)}'"); + // Trace the current version, OS, runtime, and program arguments + PlatformInformation info = PlatformUtils.GetPlatformInformation(); + Context.Trace.WriteLine($"Version: {Constants.GcmVersion}"); + Context.Trace.WriteLine($"Runtime: {info.ClrVersion}"); + Context.Trace.WriteLine($"Platform: {info.OperatingSystemType} ({info.CpuArchitecture})"); + Context.Trace.WriteLine($"AppPath: {_appPath}"); + Context.Trace.WriteLine($"Arguments: {string.Join(" ", args)}"); try { diff --git a/src/shared/Microsoft.Git.CredentialManager/Constants.cs b/src/shared/Microsoft.Git.CredentialManager/Constants.cs index cd0594a35..80820b412 100644 --- a/src/shared/Microsoft.Git.CredentialManager/Constants.cs +++ b/src/shared/Microsoft.Git.CredentialManager/Constants.cs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -using System.Diagnostics; +using System; using System.Reflection; namespace Microsoft.Git.CredentialManager @@ -105,35 +105,35 @@ public static class HelpUrls public const string GcmLinuxCredStores = "https://aka.ms/gcmcore-linuxcredstores"; } - private static string _gcmVersion; + private static Version _gcmVersion; - /// - /// The current version of Git Credential Manager. - /// - public static string GcmVersion + public static Version GcmVersion { get { if (_gcmVersion is null) { - _gcmVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion; + var assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); + var attr = assembly.GetCustomAttribute(); + if (attr is null) + { + _gcmVersion = assembly.GetName().Version; + } + else if (Version.TryParse(attr.Version, out Version asmVersion)) + { + _gcmVersion = asmVersion; + } + else + { + // Unknown version! + _gcmVersion = new Version(0, 0); + } } return _gcmVersion; } } - /// - /// Get standard program header title for Git Credential Manager, including the current version and OS information. - /// - /// Standard program header. - public static string GetProgramHeader() - { - PlatformInformation info = PlatformUtils.GetPlatformInformation(); - - return $"Git Credential Manager version {GcmVersion} ({info.OperatingSystemType}, {info.ClrVersion})"; - } - /// /// Get the HTTP user-agent for Git Credential Manager. ///