.NET Core 2中NuGet版GetApplicationRoot返回空值问题咨询
Great question—let’s break down what’s likely going on here and walk through actionable steps to fix it.
Core Root Cause
The key difference between your local project reference and NuGet package scenario boils down to two critical details:
- Which assembly
Assembly.GetExecutingAssembly()targets: In your NuGet package’s method, this call returns theWildHare.Extensions.dllassembly (the package’s own code), not your main application’s assembly (FirstCore.exe). Assembly.CodeBasebehavior in .NET Core 2.x: For NuGet-packaged assemblies,CodeBaseoften returns afile://prefixed URL (e.g.,file:///C:/Code/Samples/Core2/FirstCore/bin/Debug/netcoreapp2.0/WildHare.Extensions.dll) instead of a plain local file path. Your regex uses a negative lookbehind(?<!fil)to avoid matching this prefix, but the path returned afterPath.GetDirectoryName()still includes remnants of it, making the regex fail to find a valid drive letter match.
Troubleshooting & Fix Steps
1. Verify Assembly and Path Values First
Start by adding debug output to your NuGet package’s GetApplicationRoot() method to confirm exactly what’s happening. Temporarily modify the method (for testing) to log these details:
public static string GetApplicationRoot() { var currentAssembly = Assembly.GetExecutingAssembly(); Console.WriteLine($"Current Assembly: {currentAssembly.FullName}"); Console.WriteLine($"CodeBase: {currentAssembly.CodeBase}"); Console.WriteLine($"Location: {currentAssembly.Location}"); var exePath = Path.GetDirectoryName(currentAssembly.CodeBase); Console.WriteLine($"Processed exePath: {exePath}"); var appPathMatcher = new Regex(@"(?<!fil)[A-Za-z]:\\+[\S\s]*?(?=\\+bin)"); var appRoot = appPathMatcher.Match(exePath).Value; Console.WriteLine($"Matched appRoot: {appRoot}"); return appRoot; }
When you run this with the NuGet package reference, you’ll clearly see:
- The assembly being targeted is
WildHare.Extensions, not your main app assembly CodeBasestarts with thefile://prefix- The processed
exePathincludes this prefix, so the regex can’t find a valid drive letter match
2. Replace CodeBase with Location (More Reliable for .NET Core)
Assembly.CodeBase is obsolete in .NET Core, and Assembly.Location returns a plain local file path (no file:// prefix) for assemblies loaded from disk. Update your method to use this instead:
public static string GetApplicationRoot() { var exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var appPathMatcher = new Regex(@"[A-Za-z]:\\+[\S\s]*?(?=\\+bin)"); var appRoot = appPathMatcher.Match(exePath).Value; return appRoot; }
This eliminates the need to handle the file:// prefix entirely and works consistently across .NET Core versions.
3. Target the Main Application Assembly (Even Better)
Right now, your method gets the path of the assembly containing the method (WildHare.Extensions), not the main app’s assembly. For a more robust solution, use Assembly.GetEntryAssembly() to target the assembly that started the application (your FirstCore.exe), which guarantees you’re getting the correct root directory regardless of where the code lives:
public static string GetApplicationRoot() { // Fall back to executing assembly if entry assembly isn't available (e.g., in unit tests) var mainAssembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); var exePath = Path.GetDirectoryName(mainAssembly.Location); var appPathMatcher = new Regex(@"[A-Za-z]:\\+[\S\s]*?(?=\\+bin)"); var appRoot = appPathMatcher.Match(exePath).Value; return appRoot; }
This works reliably across local project references, NuGet packages, and different .NET frameworks.
4. Fix Regex to Handle file:// Prefix (If You Prefer CodeBase)
If you still want to use CodeBase, parse the URL to get the local path first instead of relying on a regex lookbehind:
public static string GetApplicationRoot() { var codeBase = Assembly.GetExecutingAssembly().CodeBase; var uri = new Uri(codeBase); var exePath = Path.GetDirectoryName(uri.LocalPath); // Converts file:// to a plain local path var appPathMatcher = new Regex(@"[A-Za-z]:\\+[\S\s]*?(?=\\+bin)"); var appRoot = appPathMatcher.Match(exePath).Value; return appRoot; }
Why Local Project References Worked
When you use a project reference, WildHare.Extensions.dll is compiled directly into your main app’s bin directory. Its CodeBase returns a plain local path (no file:// prefix) because it’s loaded from the same directory as your main app, so your original regex matches correctly.
内容的提问来源于stack exchange,提问作者WillC

