使用Microsoft.Data.SqlClient在自定义C# Powershell CmdLet中遇到的问题。

huangapple go评论70阅读模式
英文:

Problems using Microsoft.Data.SqlClient in custom c# Powershell CmdLet

问题

我在尝试使用C#(.NET Framework 4.7.2)编写自己的CmdLet时遇到了版本冲突的问题,使用了Microsoft.Data.SqlCLient库 - 仅这几行代码总是导致一些错误,因为SqlClient想要加载System.Memory版本4.0.1.1 - 我需要这个dll用于其他NuGet包,并且已经更新到了最新版本 - 我找不到如何阻止SqlClient使用旧版本System.Memory的解决方法

这是我总是收到的错误:

> 无法加载文件或程序集'System.Memory,Version=4.0.1.1,Culture=neutral,PublicKeyToken=cc7b13ffcd2ddd51'或其依赖项之一。系统找不到指定的文件。

对这个问题有什么帮助吗?我尝试了很多不同的方法(如app.config设置),但似乎都不起作用。

英文:

I run into a version conflict when trying to write my own CmdLet in C# (.NET Framework 4.7.2) using Microsoft.Data.SqlCLient - just these few lines of code are always resulting in some errors because SqlClient wants to load System.Memory version 4.0.1.1 - I need this dll for other nuget packages and have updated to latest version - I found no solution how to prevent SqlClient to use the old version of System.Memory

public class CmdLetEnvironment
{
    public static bool Connected = false;

    [System.Management.Automation.Cmdlet(System.Management.Automation.VerbsCommunications.Connect, "RDTest")]
    public class RDEnvironmentConnectCommand : System.Management.Automation.PSCmdlet
    {
        protected override void ProcessRecord()
        {
            try
            {
                SqlConnection conn = new SqlConnection("Data Source=localhost\\SQLEXPRESS;Initial Catalog=TestLocalOMA1;Integrated Security=True;Encrypt=False");
                conn.Open();
            }
            catch(Exception ex)
            {
                throw ex.InnerException;
            }
        }
    }
}

This is the error I always get:

> Could not load file or assembly 'System.Memory, Version=4.0.1.1, Culture=neutral,
PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.

Any help on this issue? I have tried so many different things (like app.config settings) but nothing seems to work

答案1

得分: 1

我找到了解决方法 - 由于PowerShell以不同的方式加载模块,而不是普通的.NET应用程序,您需要覆盖程序集加载。

在类中添加构造函数并覆盖AssemblyResolve以修复它 - 然后您只需要确保所有的dll都位于与您的CmdLet dll相同的目录中。

[System.Management.Automation.Cmdlet(System.Management.Automation.VerbsCommunications.Connect, "RDTest")]
public class RDEnvironmentConnectCommand : System.Management.Automation.PSCmdlet
{
    public RDEnvironmentConnectCommand()
    {
        var domain = AppDomain.CurrentDomain;
        domain.AssemblyResolve += LoadAssembly;
    }

    private Assembly LoadAssembly(object sender, ResolveEventArgs args)
    {
        Assembly result = null;

        // 获取当前dll的完整路径
        FileInfo info = new FileInfo(Assembly.GetExecutingAssembly().Location);

        // 获取执行.exe文件的文件夹
        var folderPath = info.Directory.FullName;

        // 构建加载程序集的潜在完整路径
        var assemblyName = args.Name.Split(new string[] { "," }, StringSplitOptions.None)[0];
        var assemblyExtension = "dll";
        var assemblyPath = Path.Combine(folderPath, string.Format("{0}.{1}", assemblyName, assemblyExtension));

        if (File.Exists(assemblyPath))
        {
            // 使用我们的自定义路径加载所需的程序集
            result = Assembly.LoadFrom(assemblyPath);
        }
        else
        {
            // 保留默认加载
            return args.RequestingAssembly;
        }

        return result;
    }

    protected override void ProcessRecord()
    {
        try
        {
            SqlConnection conn = new SqlConnection("Data Source=localhost\\SQLEXPRESS;Initial Catalog=TestLocalOMA1;Integrated Security=True;Encrypt=False");
            conn.Open();
        }
        catch (Exception ex)
        {
            throw ex.InnerException;
        }
    }
}

我希望这能帮助其他遇到相同问题的人们 使用Microsoft.Data.SqlClient在自定义C# Powershell CmdLet中遇到的问题。

英文:

I found the solution for it - as Powershell is loading modules in different way then normal .NET application you need to override the assembly loading.

Add a constructor to the class and override AssemblyResolve to fix it - then you only need to ensure that all dll's are located in same directory then your CmdLet dll

[System.Management.Automation.Cmdlet(System.Management.Automation.VerbsCommunications.Connect, "RDTest")]
public class RDEnvironmentConnectCommand : System.Management.Automation.PSCmdlet
{
        public RDEnvironmentConnectCommand()
        {
            var domain = AppDomain.CurrentDomain;
            domain.AssemblyResolve += LoadAssembly;
        }

        private Assembly LoadAssembly(object sender, ResolveEventArgs args)
        {
            Assembly result = null;

                //Get current dll fullpath
                FileInfo info = new FileInfo(Assembly.GetExecutingAssembly().Location);

                //Get folder of the executing .exe
                var folderPath = info.Directory.FullName;

                //Build potential fullpath to the loading assembly
                var assemblyName = args.Name.Split(new string[] { "," }, StringSplitOptions.None)[0];
                var assemblyExtension = "dll";
                var assemblyPath = Path.Combine(folderPath, string.Format("{0}.{1}", assemblyName, assemblyExtension));


                if (File.Exists(assemblyPath))
                {
                    //Load the required assembly using our custom path
                    result = Assembly.LoadFrom(assemblyPath);
                }
                else
                {
                    //Keep default loading
                    return args.RequestingAssembly;
                }

            return result;
        }

    protected override void ProcessRecord()
    {
        try
        {
            SqlConnection conn = new SqlConnection("Data Source=localhost\\SQLEXPRESS;Initial Catalog=TestLocalOMA1;Integrated Security=True;Encrypt=False");
            conn.Open();
        }
        catch(Exception ex)
        {
            throw ex.InnerException;
        }
    }
}

I hope that could help other people running into the same issue 使用Microsoft.Data.SqlClient在自定义C# Powershell CmdLet中遇到的问题。

huangapple
  • 本文由 发表于 2023年7月3日 15:42:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76602739.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定