tdhintz
Level 5

Microsoft.Data.SqlClient custom action fails to load dependency.

Jump to solution

A .Net 4.8 custom action referencing a Net Standard 2.0 assembly which uses Microsoft.Data.SqlClient doesn't work.  The following stack trace is thrown.  The action is set to x64.  Is there a way to make this work or is InstallShield not compatible with .Net Standard solutions? ? The dependencies look like this:


<row><td>MyAction</td><td>Assembly</td><td>&lt;PATH_TO_RELEASE_FILES4&gt;\C2SISTools.dll</td></row>
<row><td>MyAction</td><td>Class</td><td>C2SISTools.C2SInstaller</td></row>
<row><td>MyAction</td><td>Dependency0</td><td>&lt;PATH_TO_RELEASE_FILES4&gt;\Microsoft.Data.SqlClient.SNI.x64.dll</td></row>
<row><td>MyAction</td><td>Dependency1</td><td>&lt;PATH_TO_RELEASE_FILES4&gt;\Microsoft.Data.SqlClient.dll</td></row>
<row><td>MyAction</td><td>Method</td><td>Example</td></row>
<row><td>MyAction</td><td>Param1</td><td>[C2S_BRANDING]</td></row>
<row><td>MyAction</td><td>Param2</td><td>[SUPPORTDIR]</td></row>
<row><td>MyAction</td><td>Param3</td><td>[C2S_OLD_VERSION_NUMBER]</td></row>
<row><td>MyAction</td><td>Return</td><td>-</td></row>
<row><td>MyAction</td><td>TargetPlatform</td><td>x64</td></row>
<row><td>MyAction</td><td>Type</td><td>0</td></row>

(additional dependency records were omitted for clarity)

Stack trace:
System.DllNotFoundException: Unable to load DLL 'Microsoft.Data.SqlClient.SNI.x64.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
at Microsoft.Data.SqlClient.SNINativeManagedWrapperX64.UnmanagedIsTokenRestricted(IntPtr token, Boolean& isRestricted)
at Microsoft.Data.Win32NativeMethods.IsTokenRestrictedWrapper(IntPtr token)
at Microsoft.Data.ProviderBase.DbConnectionPoolIdentity.GetCurrent()
at Microsoft.Data.ProviderBase.DbConnectionPoolGroup.GetConnectionPool(DbConnectionFactory connectionFactory)
at Microsoft.Data.ProviderBase.DbConnectionFactory.GetConnectionPool(DbConnection owningObject, DbConnectionPoolGroup connectionPoolGroup)
at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at Microsoft.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)

 

 

Labels (1)
0 Kudos
1 Solution

I figured out the Microsoft.Data.SqlClient issue. The problem is that it has a dependency on a native SNI DLL. It isn't an assembly and can't be loaded by an MSI. To make it available it must be in the current working folder, so I placed it in the SUPPORTDIR and made the method cd to that folder before attempting to do SQL actions. 

View solution in original post

0 Kudos
2 Replies
tdhintz
Level 5

The issue appears to be that the InstallShield assembly loader isn't compatible with the required assembly.  This is demonstrated by manually loading the assembly.  I gather the assembly is required to be in the same folder as the working directory or it won't be able to find it.  Installshield only unpacks a single assembly to that folder.  Suggestions?

System.BadImageFormatException: Could not load file or assembly 'file:///C:\Users\qatest\AppData\Local\Temp\{6a5a12f6-d6b8-4d54-885e-050e531f18d5}\Microsoft.Data.SqlClient.SNI.x64.dll' or one of its dependencies. The module was expected to contain an assembly manifest.
File name: 'file:///C:\Users\qatest\AppData\Local\Temp\{6a5a12f6-d6b8-4d54-885e-050e531f18d5}\Microsoft.Data.SqlClient.SNI.x64.dll'
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)

0 Kudos

I figured out the Microsoft.Data.SqlClient issue. The problem is that it has a dependency on a native SNI DLL. It isn't an assembly and can't be loaded by an MSI. To make it available it must be in the current working folder, so I placed it in the SUPPORTDIR and made the method cd to that folder before attempting to do SQL actions. 

0 Kudos