mercredi 16 janvier 2019

How can an assembly being run inside the "C# Interactive" window find its original path?

I have a C# DLL that needs to know its location on disk, so it can find companion files. I'm already using Assembly.CodeBase so that my code works correctly whether it's being shadow-copied by NUnit or not (as recommended by the answers to this question).

However, when I use #r to load my assembly into the "C# Interactive" window in Visual Studio, and then call methods in my assembly, Assembly.CodeBase returns a temp path. I've seen this from my code, but it's even easier to reproduce within the C# Interactive window itself:

> #r "C:\path\to\my.assembly.dll"
> typeof(SomeTypeFromMyAssembly).Assembly.CodeBase
"file:///C:/Users/me/AppData/Local/Temp/InteractiveHostShadow/314264c8-e9c6-42b9-8e1d-100a30d4fbd9/8c9a9e04-58fb-4b16-8447-c68cb3a818b8/my.assembly.dll"

So instead of Assembly.CodeBase returning the original path of the DLL the way it normally does (even for shadow-copied files), it's returning a temp directory, which is evidently where C# Interactive copied it through some unconventional means.

I Googled the "InteractiveHostShadow" part of the path, and it appears in the source code of C# Interactive, in InteractiveHost.Service.cs:

_metadataFileProvider = new MetadataShadowCopyProvider(
    Path.Combine(Path.GetTempPath(), "InteractiveHostShadow"),
    noShadowCopyDirectories: s_systemNoShadowCopyDirectories,
    documentationCommentsCulture: new CultureInfo(cultureName));

But I'm not familiar enough with MetadataShadowCopyProvider to know how to get past its shadow-copying (evidently different from regular shadow-copying) to get the original DLL path.

How can I find the original path where an assembly was loaded from, in a way that works with the special flavor of shadow-copying used by C# Interactive?





Aucun commentaire:

Enregistrer un commentaire