首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将StackExchange.Redis.dll加载到powershell中?

如何将StackExchange.Redis.dll加载到powershell中?
EN

Stack Overflow用户
提问于 2022-01-17 17:06:28
回答 1查看 419关注 0票数 2

我正在尝试创建一个powershell脚本来清除redis缓存,它在Azure中,但我认为这与此无关。我看到了两个例子,我正在尝试复制人们将StackExchange.Redis.dll加载到脚本中的地方:https://www.powershellgallery.com/packages/Saritasa.Redis/1.2.0/Content/Saritasa.Redis.psm1Clearing Azure Redis Cache using PowerShell during deployment

我已经从nuget.org下载了当前的nuget.org。我尝试在2台服务器上加载它,一台安装了.Net 4.61,另一台安装了.Net 4.8。我在这两个问题上都有同样的问题。

如果我尝试使用[System.Reflection.Assembly]::LoadFrom,我得到如下所示:

代码语言:javascript
运行
复制
PS E:\redis\stackexchange.redis.2.2.88\lib\net461> dir


    Directory: E:\redis\stackexchange.redis.2.2.88\lib\net461


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        05/11/2021     00:42     637440 StackExchange.Redis.dll
-a---        05/11/2021     00:42     705989 StackExchange.Redis.xml


PS E:\redis\stackexchange.redis.2.2.88\lib\net461> [System.Reflection.Assembly]::LoadFrom("E:\redis\stackexchange.redis.
2.2.88\lib\net461\StackExchange.Redis.dll")

GAC    Version        Location
---    -------        --------
False  v4.0.30319     E:\redis\stackexchange.redis.2.2.88\lib\net461\StackExchange.Redis.dll


PS E:\redis\stackexchange.redis.2.2.88\lib\net461> [StackExchange.Redis.ConnectionMultiplexer]::Connect($myConnectionStr
ing)
Unable to find type [StackExchange.Redis.ConnectionMultiplexer]: make sure that the assembly containing this type is
loaded.
At line:1 char:1
+ [StackExchange.Redis.ConnectionMultiplexer]::Connect($myConnectionString)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (StackExchange.R...tionMultiplexer:TypeName) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound

PS E:\redis\stackexchange.redis.2.2.88\lib\net461>

如果我尝试使用Add-Type,我得到:

代码语言:javascript
运行
复制
PS E:\redis\stackexchange.redis.2.2.88\lib\net461> Add-Type -AssemblyName .\StackExchange.Redis.dll
Add-Type : Could not load file or assembly '.\\StackExchange.Redis.dll' or one of its dependencies. The given assembly
name or codebase was invalid. (Exception from HRESULT: 0x80131047)
At line:1 char:1
+ Add-Type -AssemblyName .\StackExchange.Redis.dll
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Add-Type], FileLoadException
    + FullyQualifiedErrorId : System.IO.FileLoadException,Microsoft.PowerShell.Commands.AddTypeCommand

PS E:\redis\stackexchange.redis.2.2.88\lib\net461>

我查看了nuget.org中的依赖项,我看到了一个名为Pipelines.Sockets.Unofficial的非微软依赖项,它也是我下载的,并且得到了同样的东西。有一个完整的其他依赖关系层次结构,我认为这些依赖关系都是.Net的一部分,如果.Net安装在服务器上,我肯定不需要下载它们。谢谢你的帮助,我一整天都在努力!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-28 14:08:25

我会把我学到的东西放在我的代码之上,以防像我这样缺乏经验的人读到这篇文章。这些要点不按任何顺序排列:

  • 下载供powershell使用的nuget包,最简单的方法是使用Install,例如:Install-Package -Name System.IO.Pipelines -ProviderName NuGet -SkipDependencies -Destination C:\Stackexchange.Redis-packages -RequiredVersion 5.0.1注意到-SkipDependencies是必需的,因为没有它,-SkipDependencies给了我一个关于循环依赖的错误消息,在https://endjin.com/blog/2020/12/how-to-consume-a-nuget-package-in-powershell中描述过。您必须自己下载依赖项!另一种方法是:在nuget.org中单击下载链接下载.nupkg文件,将其重命名为.zip,解压缩文件,然后在文件资源管理器中右击dll文件,单击属性,取消阻塞.

我认为这个应用程序很好地显示了DLL的依赖关系,它显示了依赖项的全部继承性,如果找到或不存在https://github.com/lucasg/Dependencies

Get file version and assembly version of DLL files in the current directory and all sub directories获取powershell:Get-ChildItem -Filter *.dll -Recurse | Select-Object Name,@{n='FileVersion';e={$_.VersionInfo.FileVersion}},@{n='AssemblyVersion';e={[Reflection.AssemblyName]::GetAssemblyName($_.FullName).Version}}中dll文件的组装版本的

  • 加载DLL时,Add-Type的行为与[System.Reflection.Assembly]::LoadFrom()不同。Add似乎加载了可能有用的依赖项。如果Add-Type -Literalpath <dllFileName>错误消息失败,“Add:无法加载一个或多个所请求的类型”。检索LoaderExceptions属性以获得更多信息“您可以获得它在$error[0].Exception.GetBaseException().LoaderExceptions $error[0].Exception.GetBaseException().LoaderExceptions中寻找的DLL”。

为了避免继承中的DLL依赖于同一个DLL的不同版本(这似乎很常见)的情况,这个家伙的解决方案简直太棒了。我找不到其他的选择,而且它似乎非常有效,https://www.azurefromthetrenches.com/powershell-binding-redirects-and-visual-studio-team-services/

我使用的DLL --我使用的DLL--最后在一个文件夹中得到了这些DLL文件:

代码语言:javascript
运行
复制
Name                                       FileVersion   AssemblyVersion
----                                       -----------   ---------------
Microsoft.Bcl.AsyncInterfaces.dll          6.0.21.52210  6.0.0.0
Pipelines.Sockets.Unofficial.dll           2.2.0.45337   1.0.0.0
StackExchange.Redis.dll                    2.2.88.56325  2.0.0.0
System.Buffers.dll                         4.6.28619.01  4.0.3.0
System.IO.Pipelines.dll                    5.0.120.57516 5.0.0.1
System.Memory.dll                          4.6.28619.01  4.0.1.1
System.Numerics.Vectors.dll                4.6.26515.06  4.1.4.0
System.Runtime.CompilerServices.Unsafe.dll 6.0.21.52210  6.0.0.0
System.Threading.Channels.dll              6.0.21.52210  6.0.0.0
System.Threading.Tasks.Extensions.dll      4.6.28619.01  4.2.0.1

代码它还没有完成,但是显示了加载和使用的Stackexhange.Redis DLL。

代码语言:javascript
运行
复制
# Code to load the DLLs needed for Stackexchange.Redis.dll and clear the cache
# Basically copied from https://www.azurefromthetrenches.com/powershell-binding-redirects-and-visual-studio-team-services/

$DllPath = 'C:\Stackexchange.Redis-packages\combined DLLS'
$redisHostName = '<my cache name here>.redis.cache.windows.net'
$redisConnectionString = '<my cache name here>.redis.cache.windows.net:6380,password=<my cache password here>,ssl=True,abortConnect=False'

# Load DLL assemblies into memory, required by the event handler below
$SystemBuffersDll = [System.Reflection.Assembly]::LoadFrom("$DllPath\System.Buffers.dll")
$SystemRuntimeCompilerServicesUnsafeDll = [System.Reflection.Assembly]::LoadFrom("$DllPath\System.Runtime.CompilerServices.Unsafe.dll")
$SystemMemoryDll = [System.Reflection.Assembly]::LoadFrom("$DllPath\System.Memory.dll")
$SystemSystemThreadingTasksExtensionsDll = [System.Reflection.Assembly]::LoadFrom("$DllPath\System.Threading.Tasks.Extensions.dll")
$SystemIoPipelinesDll = [System.Reflection.Assembly]::LoadFrom("$DllPath\System.IO.Pipelines.dll")
$MicrosoftBclAsyncInterfacesDll = [System.Reflection.Assembly]::LoadFrom("$DllPath\Microsoft.Bcl.AsyncInterfaces.dll")
$PipelinesSocketsUnofficialDll = [System.Reflection.Assembly]::LoadFrom("$DllPath\Pipelines.Sockets.Unofficial.dll")
$SystemThreadingChannelsDll = [System.Reflection.Assembly]::LoadFrom("$DllPath\System.Threading.Channels.dll")

# Event handler to be run when the AssemblyResolve event occurs
$onAssemblyResolveEventHandler = [System.ResolveEventHandler] {
    param($sender, $e)

    Write-Verbose "Assembly resolve event for $($e.Name)"

    $dllName = $e.Name.Split(',')[0]
  
    switch ($dllName) {
        'System.Buffers' {return $SystemBuffersDll}
        'System.Runtime.CompilerServices.Unsafe' {return $SystemRuntimeCompilerServicesUnsafeDll}
        'System.Memory' {return $SystemMemoryDll}
        'System.Threading.Tasks.Extensions' {return $SystemSystemThreadingTasksExtensionsDll}
        'Microsoft.Bcl.AsyncInterfaces' {return $MicrosoftBclAsyncInterfacesDll}
        'Pipelines.Sockets.Unofficial' {return $PipelinesSocketsUnofficialDll}
        'System.Threading.Channels' {return $SystemThreadingChannelsDll}
        'System.Numerics.Vectors' {return $SystemNumericsVectorsDll}
        'System.IO.Pipelines' {return $SystemIoPipelinesDll}
    }

    foreach($assembly in [System.AppDomain]::CurrentDomain.GetAssemblies()) {
        if ($assembly.FullName -eq $e.Name) {
        return $assembly
        }
    }
      return $null
}

# Set up the handler above to be triggered when the AssemblyResolve event occurs
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($onAssemblyResolveEventHandler)


# Load StackExchange.Redis.dll, prefer Add-Type because it seems to include dependencies, LoadFrom doesn't so might get an error later
Add-Type -LiteralPath  "$DllPath\StackExchange.Redis.dll"    

$redis = [StackExchange.Redis.ConnectionMultiplexer]::Connect("$redisConnectionString, allowAdmin=true")
$redisServer = $redis.GetServer($redisHostName, 6380)
# $rs.FlushAllDatabases(async=true)
$redisServer.FlushAllDatabases()

# Detach the event handler (not detaching can lead to stack overflow issues when closing PS)
[System.AppDomain]::CurrentDomain.remove_AssemblyResolve($onAssemblyResolveEventHandler)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70745024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档