libgit2 / libgit2sharp

Git + .NET = ❤
http://libgit2.github.com
MIT License
3.21k stars 889 forks source link

Exception when using it inside a Visual Studio 2022 Extensibility project #2103

Open luislhg opened 5 months ago

luislhg commented 5 months ago

Hello, I'm unable to this this package within my Visual Studio 2022 extension.

Reproduction steps

  1. Create a new VisualStudio.Extensibiltiy Extension project (VS 2022)
  2. Add a reference to <PackageReference Include="LibGit2Sharp" Version="0.30.0"/>
  3. Add using (var repo = new Repository(repoDir)) to a command

Sample project: ExtensibilityNativeLibraries.zip

Expected behavior

To initialize the repo instance

Actual behavior

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)"}

Version of LibGit2Sharp (release number or SHA1)

0.30.0

Operating system(s) tested; .NET runtime tested

Windows 11, .NET 8

ethomson commented 5 months ago

Are you shipping the native libgit2 DLL as part of your vsix?

luislhg commented 5 months ago

Are you shipping the native libgit2 DLL as part of your vsix?

I'm not sure how that would wok in the new Extensibility API project with .NET 8? It fails in debug already as you can see in the sample project.

luislhg commented 3 months ago

Just wanted to explain that I ran the sample and; Yes, the native libgit2 are being exported with the vsix. ExtensibilityNativeLibraries.dll is the extension assembly, and it has all the proper folders and libgit2 sharp, but when running the extension it just doesn't work or find it.

image

Workaround/Solution I used GlobalSettings.NativeLibraryPath to specify it manually and then it worked

string nativeLibraryPath = Path.Combine(assemblyFolder, "runtimes", "win-x64", "native");
GlobalSettings.NativeLibraryPath = nativeLibraryPath;

The final question is: Is it expected that I have to specify the folder like this for a standard/default location? Note: there is a working sample project attached to the issue.

Other than that, this issue is solved, and the solution is above in case anyone else stumbles over this.

ethomson commented 3 months ago

Thanks @luislhg thats very helpful. Is there a way to detect when we're running in this environment so that we can load from the proper location in LibGit2Sharp?

luislhg commented 3 months ago

Hum, I'm not sure what the difference is in this environment All that I had to do/specify in the NativeLibraryPath was this for it to work in the VS Extension:

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

Which is the normal path I'd expect it to automatically pick up in my own executing folder...

bording commented 3 months ago

I wasn't familiar with the extension model you were using, so I took a quick look over the documentation in the repo.

It looks like it's a new out-of-proc model for VS extensions, which means you're no longer limited to targeting .NET Framework, so that's cool.

However, since the extension wasn't able to automatically find the native libraries, that implies that that when they are loading the extension, they aren't properly looking at the deps.json file of the extension.

If you look at your ExtensibilityNativeLibraries.deps.json in the sample you provided, you'll see that all of the LibGit2Sharp native runtime information is in there, and that info is used by the .NET runtime to load the correct native library for you.

It looks like however the VSExtensibility system is loading the extensions, they aren't picking up that information, so the native library location is unknown until you manually set it via NativeLibraryPath.

I don't know the details of how they are loading the extension assemblies, but there are ways available to them to ensure they are referencing the deps.json files of the extension assemblies. If they did that, then the proper native library would loaded.

I was going to suggest opening an issue, but I see that you already have.