WillC
WillC

Reputation: 2115

Core 2 Application Root Empty When From Nuget Packet

The code in the GetApplicationRoot() method is identical to the code in the WildHare IOExtensions.GetApplicationRoot() method.

If the code is referenced in the same solution using a project reference in a .net Core 2 project, they return the same value. In a net471 project, both lines also return the same application root.

In .net Core 2, if I use the IOExtensions.GetApplicationRoot() method imported from the Nuget WildHare packet, it returns an empty value.

Just to be clear, I am the author of the package and was surprised when this did not work in the context of a .net Core Nuget package and am interested in the why.

Any ideas?

using System;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using WildHare.Extensions;

namespace FirstCore
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"GetApplicationRoot(): { GetApplicationRoot() }");
            // Returns C:\Code\Samples\Core2\FirstCore

            Console.WriteLine($"IOExtensions.GetApplicationRoot(): { IOExtensions.GetApplicationRoot() }");
            // Returns empty string

            Console.ReadLine();
        }

        public static string GetApplicationRoot()
        {
            var exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
            var appPathMatcher = new Regex(@"(?<!fil)[A-Za-z]:\\+[\S\s]*?(?=\\+bin)");
            var appRoot = appPathMatcher.Match(exePath).Value;

            return appRoot;
        }
    }
 }

Result

 

Upvotes: 0

Views: 208

Answers (1)

pfx
pfx

Reputation: 23244

The value returned from Assembly.GetExecutingAssembly().CodeBase is not always what you expect it to be and therefore it won't match the regular expression, which results in an empty string.

Assembly.GetExecutingAssembly resolves the assembly that contains the code that is currently executing, which here is the WildHare assembly.

While developing a .NET Core application, any assemblies referenced via NuGet packages don't get copied to the bin folder.
This means that the WildHare assembly gets resolved from the NuGet packages folder, having a codebase like eg. file:///C:/Users/you/.nuget/packages/wildhare/0.9.8.3/lib/netstandard2.0/WildHare.dll
This path doesn't match the regular expression, giving an empty string as result.

When building a Full .NET Framework application (eg. 4.7.1), all assemblies do get copied to the bin folder, which results in a regex match.

When having the code inline in your main assembly, the codebase path will of course include the bin folder and will pass the regex.

Use Assembly.GetEntryAssembly instead of Assembly.GetExecutingAssembly, as Assembly.GetCallingAssembly returns the assembly that is the process executable in the default application domain, or the first executable that was executed, which is your main application.

Remark: do note that because of the regular expression match in your implementation, GetApplicationRoot will only be effective if the application is running from within a bin folder, which will be very unlikely once an application is published. Either relax or remove this constraint.

Upvotes: 3

Related Questions