Unable to load DLL 'Microsoft.Data.SqlClient.SNI.dll' or one of its dependencies

Hey everyone, I’m currently developing a custom activity for Sql Server Bulk Insert using Microsoft.Data.SqlClient version 4.1.0.

Encountering a confusing issue, let me elaborate. I’m including the project DLL via NuGet package and adding the Microsoft.Data.SqlClient version 4.1.0 in the Edit Dependencies of NuGet.

Here are some key points to note:

  1. My activity requires a connection string as input for establishing a connection.
  2. I’m utilizing the Class Library (.NetFramework) project for activity development.
  3. Transitioning the activity from legacy to Windows environment.
  4. The legacy activity operates smoothly without any issues.

Now, let’s discuss the scenarios within UiPath Studio:

  1. When UiPath.Database.Activities package is not installed:
    In this scenario, I simply add my package and utilize the activity. However, upon execution, I encounter the following error:

“Unable to load DLL ‘Microsoft.Data.SqlClient.SNI.dll’ or one of its dependencies: The specified module could not be found. (0x8007007E)”

  1. When UiPath.Database.Activities package is installed (maintaining the same Microsoft.Data.SqlClient version 4.1.0):
    Even after installing the package and running my activity, the same error persists.

  2. When Connect to Database Activity is used:
    In this scenario, I employ the Connect to Database Activity without configuring it, simply providing the same connection string in the connection string field and choosing to provide to System.Data.SqlClient. Surprisingly, following this, my activity works without encountering any issues.

The issue at hand has led me to explore various solutions:

  1. Verifying the files of Microsoft.Data.SqlClient.SNI.x64.dll and Microsoft.Data.SqlClient.SNI.x84.dll in the output directory of the DLL file after building the project from Visual Studio.

  2. Attempting to add all packages shown in the UiPath.Database.Activities package in the Edit Dependencies of NuGet package explorer, alongside their respective versions.
    image

  3. Adding Microsoft.Data.SqlClient.SNI with Microsoft.Data.SqlClient in the edit dependencies.

  4. Manually adding Microsoft.Data.SqlClientx64.SNI.dll in my UiPath project root directory for testing purposes.

  5. Comparing the packages inside Microsoft.Data.SqlClient version 4.1.0 for UiPath and mine.

image

and mine

image

Despite exploring these solutions, I remain puzzled as to why the same packages work seamlessly for UiPath activities but encounter issues with mine. Additionally, the dependency of my activity on the Connect to Database activity for execution adds to the confusion.

My Code

public class DataTableToSQLTable : CodeActivity
 {
    
     [Category("Input")]
     [RequiredArgument]
     [Description("Datatable to push into SQL table.")]
     public InArgument<DataTable> SourceDatatble { get; set; }

     [Category("Input")]
     [RequiredArgument]
     [Description("Datatable coloumns name that map wih sql table columns.")]
     public InArgument<string[]> SourceColumns { get; set; }

     [Category("Input")]
     [RequiredArgument]
     [Description("The connection string used to establish a database connection.")]
     public InArgument<string> connectionString { get; set; }

     [Category("Input")]
     [RequiredArgument]
     [Description("SQL table name.")]
     public InArgument<string> SQLTableName { get; set; }

     [Category("Input")]
     [RequiredArgument]
     [Description("SQL table columns name that map wih datatble columns.")]
     public InArgument<string[]> DestinationColumns { get; set; }

     protected override void Execute(CodeActivityContext context)
     {
         DataTable table = SourceDatatble.Get(context);
         string[] sourceColumns = SourceColumns.Get(context);
         string[] destinationColumns = DestinationColumns.Get(context);
         string connectionString = this.connectionString.Get(context);
         string sqlTableName = SQLTableName.Get(context);

         // Check if the source and destination columns match in length.
         if (sourceColumns.Length != destinationColumns.Length)
         {
             throw new Exception("The number of source columns does not match the number of destination columns.");
         }

         try
         {
             // First, try to open a connection to the database to ensure that our connection string is valid.
             using (SqlConnection connection = new SqlConnection(connectionString))
             {
                 connection.Open(); // Attempt to open the connection.
                 if (connection.State == ConnectionState.Open)
                 {
                     Console.WriteLine("Successfully established a connection to the database.");
                 }
                 else
                 {
                     throw new Exception("Failed to establish a connection to the database.");
                 }
             }

             // If connection is successful, proceed with the bulk insert operation.
             using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.KeepIdentity))
             {
                 for (int i = 0; i < sourceColumns.Length; i++)
                 {
                     sqlBulkCopy.ColumnMappings.Add("[" + sourceColumns[i] + "]", "[" + destinationColumns[i] + "]");
                 }
                 sqlBulkCopy.BulkCopyTimeout = 600; // You can adjust this value based on your requirements.
                 sqlBulkCopy.DestinationTableName = "[" + sqlTableName + "]";
                 sqlBulkCopy.WriteToServer(table);
             }
         }
         catch (Exception ex)
         {
             // It's often useful to provide more specific exception handling.
             // For example, you might want to handle SqlException differently to give more detailed DB error messages.
             throw new Exception($"An error occurred: {ex.Message}", ex);
         }
     }
 }

UiPath Connect to Database actviity code

using System;
using System.Activities;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Markup;
using UiPath.Database;
using UiPath.Database.Activities;
using UiPath.Database.Activities.Properties;

[LocalizedDescription("Activity_DatabaseConnect_Description")]
public class DatabaseConnect : AsyncTaskCodeActivity
{
	private readonly IDBConnectionFactory _connectionFactory;

	[DefaultValue(null)]
	[LocalizedCategory("ConnectionConfiguration")]
	[RequiredArgument]
	[LocalizedDisplayName("Activity_DatabaseConnect_Property_ProviderName_Name")]
	[LocalizedDescription("Activity_DatabaseConnect_Property_ProviderName_Description")]
	public InArgument<string> ProviderName { get; set; }

	[DependsOn("ProviderName")]
	[DefaultValue(null)]
	[LocalizedCategory("ConnectionConfiguration")]
	[LocalizedDisplayName("Activity_DatabaseConnect_Property_ConnectionString_Name")]
	[LocalizedDescription("Activity_DatabaseConnect_Property_ConnectionString_Description")]
	public InArgument<string> ConnectionString { get; set; }

	[DefaultValue(null)]
	[DependsOn("ProviderName")]
	[LocalizedCategory("ConnectionConfiguration")]
	[LocalizedDisplayName("Activity_DatabaseConnect_Property_ConnectionSecureString_Name")]
	[LocalizedDescription("Activity_DatabaseConnect_Property_ConnectionSecureString_Description")]
	public InArgument<SecureString> ConnectionSecureString { get; set; }

	[LocalizedCategory("Output")]
	[DependsOn("ProviderName")]
	[LocalizedDisplayName("Activity_DatabaseConnect_Property_DatabaseConnection_Name")]
	[LocalizedDescription("Activity_DatabaseConnect_Property_DatabaseConnection_Description")]
	public OutArgument<DatabaseConnection> DatabaseConnection { get; set; }

	public DatabaseConnect()
	{
		_connectionFactory = new DBConnectionFactory();
	}

	internal DatabaseConnect(IDBConnectionFactory factory)
	{
		_connectionFactory = factory;
	}

	protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken)
	{
		string connString = ConnectionString.Get(context);
		SecureString connSecureString = ConnectionSecureString.Get(context);
		if (connString == null && connSecureString == null)
		{
			throw new ArgumentNullException(UiPath_Database_Activities.ValidationError_ConnectionStringMustNotBeNull);
		}
		if (connString != null && connSecureString != null)
		{
			throw new ArgumentException(UiPath_Database_Activities.ValidationError_ConnectionStringMustBeSet);
		}
		string provName = ProviderName.Get(context);
		DatabaseConnection dbConnection = null;
		try
		{
			dbConnection = await Task.Run(() => _connectionFactory.Create(connString ?? new NetworkCredential("", connSecureString).Password, provName));
		}
		catch (Exception arg)
		{
			Trace.TraceError($"{arg}");
			throw;
		}
		return delegate(AsyncCodeActivityContext asyncCodeActivityContext)
		{
			DatabaseConnection.Set(asyncCodeActivityContext, dbConnection);
		};
	}
}

Hello, have you been able to solve your problem or not?
The same thing happened to me, but I can’t solve it. If you found a solution I would like to know it, thank you.

Yes i do found the solution, i will share the details in some time

The error you’re encountering, “Unable to load DLL ‘Microsoft.Data.SqlClient.SNI.dll’ or one of its dependencies”, arises when your custom activity for Sql Server Bulk Insert cannot locate the required DLL file or its dependent files. Here’s a breakdown of the potential causes and solutions:

1. Missing NuGet Package:

  • Scenario: You haven’t included the Microsoft.Data.SqlClient.SNI NuGet package in your custom activity project.
  • Solution: Add the Microsoft.Data.SqlClient.SNI package using the NuGet Package Manager within Visual Studio.

2. Version Mismatch:

  • Scenario: The version of Microsoft.Data.SqlClient.SNI in your project differs from the one used by UiPath.Database.Activities.
  • Solution: Ensure both your project and UiPath.Database.Activities use the same Microsoft.Data.SqlClient.SNI version. Check the installed version of UiPath.Database.Activities and reference the same version in your project.

3. Incorrect Build Configuration:

  • Scenario: You’re building your project in a configuration (e.g., Debug) that doesn’t copy the necessary DLLs to the output directory.
  • Solution: Set the “Copy Local” property of Microsoft.Data.SqlClient.SNI to “True” in the NuGet Package Manager. Alternatively, ensure the build configuration copies native dependencies to the output directory.

4. Dependency Issues:

  • Scenario: Other dependencies required by Microsoft.Data.SqlClient.SNI are missing.
  • Solution: Use a tool like Dependency Walker (https://www.dependencywalker.com/) to identify missing dependencies. Install those missing packages using NuGet.

Additional Tips:

  • Clean and Rebuild: After making changes to NuGet packages or build configurations, perform a clean and rebuild of your project to ensure changes take effect.
  • Reference System.Data.SqlClient: While it might seem unnecessary, explicitly referencing the System.Data.SqlClient assembly in your project can sometimes resolve dependency issues.

By following these steps and considering the additional tips, you should be able to resolve the DLL loading error and successfully execute your custom Sql Server Bulk Insert activity.

1 Like

I tried almost all of that none of them really worked , but then I made the project from scratch in the new activity SDK provided by UiPath and it just worked like a charm , but you can see this long converstaion i did on SO with this uer, who helped me out till the end , here is the SO Question

I discussed this issue extensively on StackOverflow with a helpful user, but ultimately, I couldn’t find a solution there. You might want to review that conversation thread for more insights.

Briefly, here’s what I experienced:

  1. I attempted various solutions for my .Net Framework Project, including numerous suggestions from online and that specific user. Unfortunately, none were effective.

  2. I switched to creating a new project using the Custom Activity SDK provided by UiPath, which proved successful. My company organized a session with UiPath on this SDK, which offered a basic understanding—essentially same on the documentation as well.During the development, I encountered some challenges with dependencies and other configuration issues with this SDK Template, but I managed to resolve them independently.
    If you’re experiencing similar issues after starting a project with this SDK, let me know; I might be able to assist.

  3. To summarize, you have two main approaches: You could try the various methods that both the user and I attempted on StackOverflow for the .NetFramework project, as well as the suggestions from @mukesh.singh. Alternatively, consider starting a fresh project with the SDK template provided by UiPath. Be aware not to confuse ‘Creating activities with code’ with ‘Creating activities using the Activity Creator,’ as the second is now deprecated.

I hope the solutions from @mukesh.singh and the StackOverflow thread can assist with your current project. If not, you might need to invest a day or two to familiarize yourself with the new SDK template.

Hi @indiedev91

You went down a rabbit hole with this one :sweat_smile:

For some context, in case anyone is still wondering what is wrong here.

To start, our Database package is one of the ones you can check out on this repo (just in case someone is curious; there are other packages on the repo as well, feel free to explore):

As to the above issue itself → there is an issue how this DLL file gets loaded. We are currently working around it in our own package by loading it manually.

See below for a few open issues on the SqlClient side:

2 Likes

@loginerror Thanks a lot, i didn’t expect your answer on this one, also thanks for the resources provided, i never gone to this open issues that you have listed

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.