-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
<probing privatePath="..." /> doesn't work in .Net 5.0 #45342
Comments
Tagging subscribers to this area: @vitek-karas, @agocke, @CoffeeFlux Issue DetailsIn .Net 4, probing during assembly loading could be influenced by use of the 'probing' element in the
In this example, the However this does not work with .Net 5. Including an app.config file in the project results in an If I move the interop dllls into the same folder as the .exe, all works fine, but I really don't want the top-level bin folder polluted with all these interop dlls. Is there any current workaround for this? And is there any plan to provide the same probing behaviour as in .Net 4?
|
This looks like an issue with discovering assemblies in a COM scenario. The COM loading itself doesn't prescribe how assemblies are placed on disk but does generate a SxS manifest when compiling a COM sever with @vitek-karas or @elinor-fung do either of you have thoughts on how one could educate the loader or update the appropriate JSON file for finding COM components in a subfolder? |
I'm guessing that the The simplest way to do this would probably be in code. Register an event handler for This should fix it for any errors which are due to the application failing to find an assembly. |
[Sorry for the delay in responding to this, and the length of this post, but this stuff is tricky and important...] Yes, the And for this reason, the suggestion of making the code explicitly load these dlls is quite simply a non-starter. It needs to work in the straightforward fashion that it has for years in .Net Framework. I've attached two simple Visual Studio projects that demonstrate the issue: one using .Net Framework that works as intended, and another with identical code but using .Net 5.0 that doesn't. These projects use the Microsoft Scripting Runtime COM library as a convenient simple test case. (See the section Sample Apps below). But before I go any further, let me say what does work in .Net 5: if the COM library is referenced directly via the COM component list in Visual Studio, and Also I can confirm that using Background and current .Net Framework approachThe simple scenario that works described above is very different from my scenario. Here we have a product that was originally developed as a set of Visual Basic ActiveX dlls and control libraries, together with a set of .exes. This product can be used as a platform for third-party developers to produce their own applications. Some of the .dlls have since been ported to .Net Framework, and some .Net applications have been developed using a mixture of the COM and .Net components. So the current situation is that the consumers of the COM components may be:
When deployed, none of the COM components are registered on the target computers, since I use registration-free COM throughout - though of course on development machines at least the ActiveX Control components have to be registered. This has led to the following folder structure which has served me well for years:
The .Net exes in the bin folder locate their dependencies using the
I very much want to preserve this structure going forward with .Net 5, but at present this is not possible because the Sample AppsThe attached samples contain a trivial single-form Windows Forms app: one version for .Net Framework, and one for .Net 5. The apps use the Microsoft Scripting Runtime component to enumerate the computer's drives and write their labels to a textbox. TestDotNetFramework.zip In both apps, the Interop.Scripting dependency has both The .Net Framework version runs just fine, but the .Net 5 version fails miserably. What is particularly odd is that using fuslogvw.exe, nothing is recorded at all for the .Net 5 version - it evidently never gets as far as even attempting any assembly resolution. On the other hand, change the .Net 5 app so that either Other ConsiderationsI understand that a lot of effort has been put into improving the various sorts of interop in .Net 5, and it may well be that Using The structure outlined above avoids such problems because the RCWs are built once, stored once in a well-defined location, and referenced on an as-needed basis by individual projects. That's why I want to be able to keep it, unless someone can confirm that 'Embed Interop Types` has now somehow solved these issues. |
Thanks for the sample repro.
I think perhaps the underlying question there is if they are referenced in such a way that they will be included in the application's The general issue here seems to be configuring an application to use a subdirectory for assembly loading - similar to dotnet/sdk#10366. In this case, since the dependencies are already not part of the static void Main()
{
AssemblyLoadContext.Default.Resolving += ResolveAssembly;
...
}
private static Assembly ResolveAssembly(AssemblyLoadContext alc, AssemblyName assemblyName)
{
string probeSetting = AppContext.GetData("SubdirectoriesToProbe") as string;
if (string.IsNullOrEmpty(probeSetting))
return null;
foreach (string subdirectory in probeSetting.Split(';'))
{
string pathMaybe = Path.Combine(AppContext.BaseDirectory, subdirectory, $"{assemblyName.Name}.dll");
if (File.Exists(pathMaybe))
return alc.LoadFromAssemblyPath(pathMaybe);
}
return null;
} The config property could be set in the <RuntimeHostConfigurationOption Include="SubdirectoriesToProbe" Value="Platform;Interop" /> As you said, this would obviously not be as straightforward as the config in .NET Framework, but unfortunately, I don't know that there is currently a simple way to do this purely through configuration files in .NET 5. |
@elinor-fung thanks for the comprehensive answer. Your proposal is pretty simple and works fine in my simple sample app. How it would scale for the scenario I outlined before, is not clear to me at present, but I don't anticipate any major issues apart from the tedium of doing it. My antipathy towards it is 'philosophical': it means that the deployment layout has to effectively be encoded in the project file for each application, and my feeling is that these two things should be entirely separate. Thus it's fine that the build puts everything into a single folder (more or less), but when there are dozens of libraries and many apps, it makes a lot of sense to be able to apply some sensible structuring when everything is deployed, in a way that's simple and straightforward. The ability to have all the .exes in a top-level folder and all the dependencies in (a set of) subdirectories seems so straightforward and simple and obvious that I'm surprised it wasn't a design goal for .Net 5 from day 1. As a prime example of this structure, take a look at Visual Studio itself. Its main program devenv.exe is small, and its devenv.exe.config uses So I guess Microsoft aren't planning on porting Visual Studio to .Net 5 any time soon... Shame really, dogfood and all that! |
It is also possible to use a template |
In theory the |
Tagging subscribers to this area: @eerhardt, @maryamariyan Issue DetailsIn .Net 4, probing during assembly loading could be influenced by use of the 'probing' element in the
In this example, the However this does not work with .Net 5. Including an app.config file in the project results in an If I move the interop dllls into the same folder as the .exe, all works fine, but I really don't want the top-level bin folder polluted with all these interop dlls. Is there any current workaround for this? And is there any plan to provide the same probing behaviour as in .Net 4?
|
Tagging subscribers to this area: @vitek-karas, @agocke Issue DetailsIn .Net 4, probing during assembly loading could be influenced by use of the 'probing' element in the
In this example, the However this does not work with .Net 5. Including an app.config file in the project results in an If I move the interop dllls into the same folder as the .exe, all works fine, but I really don't want the top-level bin folder polluted with all these interop dlls. Is there any current workaround for this? And is there any plan to provide the same probing behaviour as in .Net 4?
|
@vitek-karas and @agocke I am moving this to the hosting side of things since it is general limitation on that process. However I am inclined to actually move this over to the SDK since it is about providing an experience for customized |
In .Net 4, probing during assembly loading could be influenced by use of the 'probing' element in the
app.exe.config
file. TheprivatePath
attribute contained list of subfolders that would be searched during probing. An example from one of my apps is:In this example, the
TradeWright.TradeBuild.ComInterop
subfolder contains a number (69 to be precise) of COM interop libraries produced by use of tlbimp.exe and AxImp.exe. The corresponding ActiveX .dlls and .ocxs are in parallel subfolders with appropriate manifests to enable registration-free COM, and the .exes have corresponding embedded application manifests. This all works perfectly, and it means my top-level bin folder contains only the .exes and .exe.configs, and all the interop dll's are neatly tucked away.However this does not work with .Net 5. Including an app.config file in the project results in an
app.dll.config
file being generated, but the 'probing' element is not actioned. The interop files are not located and the apps get nowhere.If I move the interop dllls into the same folder as the .exe, all works fine, but I really don't want the top-level bin folder polluted with all these interop dlls.
Is there any current workaround for this? And is there any plan to provide the same probing behaviour as in .Net 4?
The text was updated successfully, but these errors were encountered: