Skip to content
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

Exception when using/referencing packages with native libraries #390

Open
luislhg opened this issue Jun 10, 2024 · 9 comments
Open

Exception when using/referencing packages with native libraries #390

luislhg opened this issue Jun 10, 2024 · 9 comments
Labels
bug Something isn't working outofprocSDK Issues about new out-of-process SDK question Further information is requested

Comments

@luislhg
Copy link

luislhg commented Jun 10, 2024

Hello, I'm trying to develop an extension that uses libgit2sharp, which has native libraries. It fails when trying to use it with this exception

The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception.

InnerException = {"Unable to load DLL 'git2-a418d9d' or one of its dependencies: Não foi possível encontrar o módulo especificado. (0x8007007E)"}

Here is a reproduceable project, it's very simple, just added a nuget reference to a package using native libraries, and this fails in the extension project. It works nicely in a console project for example.
ExtensibilityNativeLibraries.zip

@matteo-prosperi
Copy link
Member

Most likely LibGit2Sharp is not able to find the assembly since it's not in the running executable folder. I have never used LibGit2Sharp myself but, from a quick search on the internet, you could try to set LibGit2Sharp.GlobalSettings.NativeLibraryPath (see here).

@matteo-prosperi matteo-prosperi added the question Further information is requested label Jun 25, 2024
@luislhg
Copy link
Author

luislhg commented Jun 26, 2024

That being said, aren't all libraries supposed to be embedded into the vsix?
How would I specify a NativeLibraryPath in the first place if the users wont have that native library anywhere in their computers?

In the post's sample project, the debug/release folder will have the native libraries as expected, but once loaded into VS via VSIX, native libraries are not there (or are not found) and it doesn't work inside the extension.

@tinaschrepfer
Copy link
Member

If you open up the VSIX file (it's just a renamed zip file), do you see the dependencies you expect embedded in the zip?

@matteo-prosperi
Copy link
Member

How would I specify a NativeLibraryPath in the first place if the users wont have that native library anywhere in their computers?

My guess is that you would want those libraries to be packaged in the VSIX, you would then use Assembly.GetExecutingAssembly to get the installation folder of your extension and figure out the path of your native library so that you can set NativeLibraryPath. That may work

@luislhg
Copy link
Author

luislhg commented Jul 18, 2024

If you open up the VSIX file (it's just a renamed zip file), do you see the dependencies you expect embedded in the zip?

Yes, the native libraries are inside the vsix.

How would I specify a NativeLibraryPath in the first place if the users wont have that native library anywhere in their computers?

My guess is that you would want those libraries to be packaged in the VSIX, you would then use Assembly.GetExecutingAssembly to get the installation folder of your extension and figure out the path of your native library so that you can set NativeLibraryPath. That may work

The native libraries also are in the installation folder.


Thanks, I was able to workaround with:

string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
assemblyFolder = assemblyFolder[..^2];
GlobalSettings.NativeLibraryPath = Path.Combine(assemblyFolder, "runtimes", "win-x64", "native");

That being said, I don't need to do this for a regular console project which has the exact same folders.
I wonder if this is something specifically to VSIX with Native Libraries or to libgit2sharp?

Also, the GlobalSettings path applies to all extensions running under the same Visual Studio instance, which means that if a another extension points to a different path/version it would cause conflicts.
To add insult to injury, GlobalSettings.NativeLibraryPath throws exception if set more than one time, which means the second extension would crash, regardless if it's trying to set the same or a different path/version.

Other than that, the workaround provided above and could close this issue - assuming no one has anything else to add.
Thanks for the help!

@bording
Copy link

bording commented Jul 27, 2024

When LibGit2Sharp is referenced, all of the native library info is in the dep.json file, so the normal .NET runtime type loading mechanisms should be able to work to choose the correct native library.

When the extension assemblies are being loaded, are you using a custom AssemblyLoadContext to do that?
Are the deps.json files of the extension assemblies being processed?

@luislhg should not need to manually provide the path to the native binary in this case. It seems like something the VSExtensibility should be handling.

@BertanAygun
Copy link
Member

BertanAygun commented Jul 29, 2024

I was able to reproduce the issue and will be opening a work item to create guidance. I did notice that we currently don't deploy deps.json file as part of the extension but adding a target as below to deploy it didn't help either. We will have to investigate further.

Thanks,
Bertan Aygun

You can add the below to csproj to include deps.proj files:

    <Target Name="IncludeDepsJson" BeforeTargets="GetVsixSourceItems">
        <ItemGroup>
            <VsixSourceItem Include="bin\$(Configuration)\$(TargetFramework)\ExtensibilityNativeLibraries.deps.json" />
        </ItemGroup>
    </Target>

@BertanAygun BertanAygun added bug Something isn't working outofprocSDK Issues about new out-of-process SDK labels Jul 29, 2024
@luislhg
Copy link
Author

luislhg commented Jul 30, 2024

Glad that you managed to reproduce and work on it.

Some notes/questions I found:

  1. If I set the extension project to win-x64 it will work right away.
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  2. That being said would this setting also work when running under Windows OR Visual Studio for ARM64?
  3. Is the Visual Studio (and the out-of-proc extensibility) compatible AND native for both x64 and ARM64?

@BertanAygun
Copy link
Member

The works because with a single runtime identifier, native assemblies are added to extension directory directly. But as you said it wouldn't work for Visual Studio for ARM64. Both extensibility scenarios for Visual Studio do support arm64 and extension host for out-of-proc cases should be a native arm64 process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working outofprocSDK Issues about new out-of-process SDK question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants