Last active
May 20, 2019 18:32
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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