SNI.dll
I am using the Microsoft.Data.SqlClient and it needs SNI.dll for the proper platform. I am using the Micorosoft.Data.SqlClient NuGet package in LINQPad but whenever I run a query in LINQPad it tells me it cannot find the SNI.dll with something like:
Failed to load C:\Users\wjvii\AppData\Local\Temp\LINQPad5_suxutjro\shadow_anolsn\x86\SNI.dll
I am not sure where to put the sni.dll so that LINQPad can find it, does someone know?
Thank you in advance.
Comments
-
I take it you're using LINQPad 5? If so, that library relies on MSBuild, so it won't work with LINQPad. I don't know why Microsoft have designed it in this way, because it prevents tools such as LINQPad from using it.
I could write a hack to make this particular library work, but it will be distributed in a beta build that won't go RTM for a few months.
In terms of a workaround, you could try copying the X86 SNI.dll from the following folder:
%localappdata%\LINQPad\NuGet.FW46\Microsoft.Data.SqlClient\Microsoft.Data.SqlClient.SNI.1.1.0\build\net46\x86
into the folder where LINQPad.exe lives.
-
Thank you for the feedback. I agree, I really dislike these native dependencies and how they get used and deployed. I will try some of the suggestions and put the details of the outcome in this discussion when I am done.
-
Hi, I have LinqPad 5 and tried to put SNI.dll in the LinqPad folder and does not work.
There is another workaround to fix this issue?
I have many scripts with app.config and it’s not possible to use LinqPad 6, and cannot use Ef core 3.1Thanks
-
I'll take a look at it, but it's tricky because the SqlClient library hard-codes where it expects the sni.dll file to be.
A workaround is to add the following class to My Extensions:
public static class Fix { public static void SNI<T>() { // LINQPad knows where sni.dll is and automatically adds the right version // (x86 or x64) to the environment %PATH%. This is enough to make most // native libraries work, but not Microsoft.Data.SqlClient. So we must copy // it to a location that's relative to Microsoft.Data.SqlClient.dll. if (!FindInPath ("sni.dll", out var sniPath)) throw new FileNotFoundException ( @"Unable to find sni.dll in %PATH%. Ensure that you're referenced the Microsoft.Data.SqlClient NuGet package."); sniPath.DumpTrace ("SNI Path"); string targetFolder = Path.Combine ( Path.GetDirectoryName (typeof (T).Assembly.Location), (IntPtr.Size == 4 ? "x86" : "x64")); if (!Directory.Exists (targetFolder)) Directory.CreateDirectory (targetFolder); string targetFile = Path.Combine (targetFolder, "sni.dll"); if (!File.Exists (targetFile)) File.Copy (sniPath, targetFile); targetFile.DumpTrace ("SNI target path"); } [DllImport ("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = false)] static extern bool PathFindOnPath ([MarshalAs (UnmanagedType.LPTStr)] StringBuilder pszFile, IntPtr unused); static bool FindInPath (String pszFile, out String fullPath) { const int MAX_PATH = 260; StringBuilder sb = new StringBuilder (pszFile, MAX_PATH); bool found = PathFindOnPath (sb, IntPtr.Zero); fullPath = found ? sb.ToString() : null; return found; } }
Note that My Extensions will not need a reference to Microsoft.Data.SqlClient.
Then, from the query that references Microsoft.Data.SqlClient, call this:
Fix.SNI<Microsoft.Data.SqlClient.SqlConnection>();
You will need to call this method only once after downloading the Microsoft.Data.SqlClient NuGet package. However, should you update the Microsoft.Data.SqlClient package (i.e., download a later version), you will need to call the method again. (There's no harm in keeping the call to Fix.SNI in there permanently if you like.)
-
It's working.
Thank your very much .
-
Thank you so much @JoeAlbahari ! This was such a nightmare to diagnose and you've saved the day!!
-
The copy from C:\Users\XXXXXX\AppData\Local\LINQPad\NuGet.FW46\Microsoft.Data.SqlClient\Microsoft.Data.SqlClient.SNI.2.1.1\build\net46 to the location of LINQPad.exe worked for me, thanks Joe!
-
Sorry, after digging in extensively, I realized what I was posting to this thread was a related but separate issue and I moved it to a new discussion.