Reputation: 2115
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;
}
}
}
Upvotes: 0
Views: 208
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