-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
C++/CLI libraries may fail to load due to ijwhost.dll
not being on the search path
#38231
Comments
Tagging subscribers to this area: @vitek-karas, @swaroop-sridhar |
Would it be possible to ask the C++/CLI project system to include an assembly manifest like the one in your workaround for #37972 in either their templates or automatically as part of the build? |
Hello, xlw::PathUpdater::PathUpdater()
{
MEMORY_BASIC_INFORMATION theInfo ;
HMODULE theHandle = NULL;
char theDLLPathChar [MAX_PATH + 1] = "";
DWORD dwRet = 0;
std::string originalPathValue(StringUtilities::getEnvironmentVariable("PATH"));
bool ok(!originalPathValue.empty());
dwRet = static_cast<DWORD>(VirtualQuery (((LPCVOID)this), &theInfo,(static_cast<DWORD> (sizeof (MEMORY_BASIC_INFORMATION)))));
if (dwRet)
{
theHandle = ((HMODULE) (theInfo.AllocationBase));
GetModuleFileName (theHandle, theDLLPathChar , MAX_PATH);
xlw::XlfServices.StatusBar = theDLLPathChar;
}
else
{
ok = false;
std::cerr << XLW__HERE__ <<" Could not attain path of DLL" << std::endl;
}
if(ok)
{
std::string theDLLPath(theDLLPathChar);
std::string newPathValue(originalPathValue);
std::string::size_type pos = theDLLPath.find_last_of("\\");
newPathValue+= ";"+theDLLPath.substr(0,pos);
if (!SetEnvironmentVariable("Path", newPathValue.c_str()))
{
std::cerr << XLW__HERE__ << " SetEnvironmentVariable failed to set PATH" << std::endl;
ok = false;
}
else
{
std::cerr << XLW__HERE__ << " PATH set successfully " << std::endl;
}
}
if(!ok)
{
std::cerr << XLW__HERE__ << " Warning: Unable to initialise PATH to directory of library " << std::endl;
}
} This is executed quite early on when the XLL is loaded and works for most other dependant dlls that need to be found. It does not work for ijwhost.dll however. For some reason it's too late. Setting the PATH variable explicitly and externally makes everything work as expected. For .NET Core 3.1 we don't even get that far :
|
/cc @agocke |
Add assembly manifest for VC++ projects to prevent loading issues of ijwhost.dll dotnet/runtime#38231 dotnet/runtime#37972 (comment) Not sure exactly how to test this works as expected Reference https://docs.microsoft.com/en-us/windows/win32/sbscs/assembly-manifests #3197
This is still an issue for me with .NET 5.0 and VS 16.8.2. I resolved it by adding a linker manifest to handle "Ijwhost.dll", but it took me hours of troubleshooting and scouring the internet to figure that out. It would be great if it could just be handled automatically - ideally with "Ijwhost.dll" going away - either being statically linked or through some other mechanism. This is part of a larger problem of C++/CLI being unfriendly for plugin architectures. If your dll is being loaded by a host, the default assembly load path isn't where your plugin is, so you have to implement an AssemblyLoadContext resolve handler to load assemblies. It works - but it is an extra step that takes time to figure out and implement. This is stuff that should "just work", particularly with .NET Core becoming the new mainstream. |
@mikeoliphant could you please describe in a bit more details this:
I don't think I follow what is the problem here. Is it that loading plugins requires a resolver (regardless of C++/CLI being used or not)? I don't see how C++/CLI makes this different. |
I hadn't thought about that, but it makes sense that the path issue would still exist in a purely managed context. In C++/CLI the situation is exacerbated by the issue with "Ijwhost.dll". |
I am facing this same issue. Our .net6 core web server runnning on Window nano server 1809 is taking dependency on a c++ library. when running the NanoServerApiScanner.exe it says that ijwhost.dll is missing When searching for the Any help would be greatly appreciated |
I got this solved by including the ijwhost.dll in the linker manifest |
@mikeoliphant do you have that process documented somewhere? |
|
To support C++/CLI libraries in .NET Core,
ijwhost
was created as a shim for finding and loading the runtime. All C++/CLI libraries are linked to this shim, such thatijwhost.dll
is found/loaded when the C++/CLI library is loaded.By default, Windows' DLL search will look for dependencies of a DLL as if they were loaded with just the module name. This means that, depending on how a host application loads the C++/CLI library, the C++/CLI library may fail to load due to
ijwhost.dll
not being found. In order for the load to work one of the following needs to be true:ijwhost.dll
is on the search pathLOAD_WITH_ALTERED_SEARCH_PATH
orLOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
flags forLoadLibrary
such that dependencies are searched for in the same directory as the C++/CLI libraryC++/CLI libraries cannot dictate how their hosts load them and authors should not need to be concerned with how the
ijwhost
shim is found and loaded. The runtime/tooling should make the usage ofijwhost
hidden to the user such that it just works without user intervention.In .NET Framework, the equivalent shim (
mscoree
/mscoreei
) is system-wide, so this was not an issue.Potential options:
ijwhost
a static library that gets linked into the C++/CLI library@jkoritzinsky @AaronRobinsonMSFT @vitek-karas
The text was updated successfully, but these errors were encountered: