Home

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.1

    Thanks

  • edited June 2020

    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!

  • edited March 2022

    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.

Sign In or Register to comment.