Skip to content

Instantly share code, notes, and snippets.

@vbfox
Last active May 20, 2019 18:32
Show Gist options
  • Save vbfox/18a26f47ba9d2c8abf8aa1262ee7a806 to your computer and use it in GitHub Desktop.
Save vbfox/18a26f47ba9d2c8abf8aa1262ee7a806 to your computer and use it in GitHub Desktop.
Helps libgit2sharp to find it's native dll in LINQPad when loaded via NuGet
static class LibGit2SharpForLinqPad
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, EntryPoint = "GetDllDirectory", SetLastError = true)]
static extern uint GetDllDirectoryPInvoke(uint length, StringBuilder lpPathName);
static string GetDllDirectory()
{
var size = GetDllDirectoryPInvoke(0, null);
if (size == 0)
{
if (Marshal.GetLastWin32Error() != 0)
{
throw new Win32Exception();
}
else
{
// No directory set
return null;
}
}
var builder = new StringBuilder((int)size);
var result = GetDllDirectoryPInvoke(size, builder);
if (result == 0 && Marshal.GetLastWin32Error() != 0)
{
throw new Win32Exception();
}
return builder.ToString();
}
public static void Initialize()
{
var nativeMethods =
typeof(Repository)
.Assembly
.GetType("LibGit2Sharp.Core.NativeMethods");
var dllName =
nativeMethods
.GetMethod("giterr_last", BindingFlags.Static | BindingFlags.NonPublic)
.GetCustomAttribute<DllImportAttribute>()
.Value;
dllName = Path.ChangeExtension(dllName, ".dll");
var assemblyLocation = typeof(Repository).Assembly.Location;
var searchLocation = Path.GetFullPath(Path.Combine(assemblyLocation, "..", "..", "..", ".."));
var expectedParent = Marshal.SizeOf(typeof(IntPtr)) == 8 ? "amd64" : "x86";
var potentialPaths =
from filePath in Directory.EnumerateFiles(searchLocation, dllName, SearchOption.AllDirectories)
let dirName = Path.GetDirectoryName(filePath)
let dir = new DirectoryInfo(dirName)
where dir.Name == expectedParent
select dirName;
var dllFolder = potentialPaths.First();
var previousDllDirectory = GetDllDirectory();
try
{
SetDllDirectory(dllFolder);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(nativeMethods.TypeHandle);
}
finally
{
SetDllDirectory(null);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment