无法使用Powershell在Windows 10上将Bcrypt.Net-Next程序集安装到GAC中 [英] Unable to install the Bcrypt.Net-Next assembly in to the GAC on Windows 10 using Powershell

查看:145
本文介绍了无法使用Powershell在Windows 10上将Bcrypt.Net-Next程序集安装到GAC中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在SSIS包的数据流中实现BCrypt哈希.我想通过将Bcrypt程序集部署到GAC,然后在脚本组件中调用它来做到这一点.我从Git下载了该项目,构建了一个强大的命名项目(我创建了一个密钥),然后使用Powershell将程序集部署到了GAC.我使用Powershell而不是gacutil.exe,因为我正在运行Windows 10,而Windows 10没有gacutil.exe.

I need to implement BCrypt hashing in an SSIS package's data flow. I would like to do this by deploying the Bcrypt assembly to the GAC and then calling it in a script component. I downloaded the project from Git, built the strong named project (I created a key), and deployed the assembly to the GAC using Powershell. I used Powershell instead of gacutil.exe because I am running Windows 10, which does not have gacutil.exe.

https://github.com/BcryptNet/bcrypt.net

# NOTE: Run powershell as administrator
[Reflection.Assembly]::LoadWithPartialName("System.EnterpriseServices") | Out-Null         
[System.EnterpriseServices.Internal.Publish] $publish = New-Object System.EnterpriseServices.Internal.Publish

# to install a dll
$publish.GacInstall("C:\temp\Bcrypt.net\BCrypt.Net-Next.dll")

我没有得到任何错误,实际上我没有得到任何输出-它只是转到下一行.但是该程序集未安装在%windir%\ Microsoft.NET \ assembly

I do not get any error, in fact I do not get any output - it just goes to the next line. But the assembly is not installed in %windir%\Microsoft.NET\assembly

知道为什么这行不通吗?

Any idea why this is not working?

注意:我这样做是与使用NuGet相反,因为我将在SSIS脚本组件中使用它.显然,NuGet无法与SSIS解决方案一起使用.

Note: I am doing it this way as opposed to using NuGet because I am going to be using this in an SSIS script component. Apparently, NuGet does not work with SSIS solutions.

推荐答案

以补充您自己的答案:

我很惊讶 [Reflection.Assembly] :: LoadWithPartialName('System.EnterpriseServices')无法正常工作-对我来说确实有用,但这是有争议的,因为在PowerShell中,最好使用
添加类型-AssemblyName
,其中:

I'm surprised that [Reflection.Assembly]::LoadWithPartialName('System.EnterpriseServices') didn't work - it does for me, but it's a moot point, because in PowerShell it's preferable to use
Add-Type -AssemblyName
, which:

    就语法而言,
  • 更像是PowerShell惯用语,并且
  • 如果无法加载程序集,则报告(语句终止)错误(而 [Reflection.Assembly] :: LoadWithPartialName() quiet no)-op (如果无法加载程序集).
  • is more PowerShell-idiomatic in terms of its syntax, and
  • reports a (statement-terminating) error if the assembly cannot be loaded (whereas [Reflection.Assembly]::LoadWithPartialName() is a quiet no-op in case of failure to load the assembly).
# Try to load the latest System.EnterpriseServices.dll assembly
# from the GAC.
Add-Type -AssemblyName System.EnterpriseServices

类似于 [Reflection.Assembly]:: LoadWithPartialName() Add-Type -AssemblyName 允许您按其简单名称加载GAC程序集(也反映在DLL中/executable文件名(不带扩展名),它既不需要您知道程序集的版本号,也不知道其公钥(不过, Add-Type -AssemblyName > not 也会首先在 application 目录中查找,该目录在PowerShell中可能是PowerShell可执行文件本身的位置.

Like [Reflection.Assembly]::LoadWithPartialName(), Add-Type -AssemblyName allows you to load GAC assemblies by their simple name (as also reflected in the DLL/executable file name without extension), which neither requires you to know the assembly's version number nor its public key (however, Add-Type -AssemblyName does not also first look in the application directory, which in PowerShell would presumably be the location of the PowerShell executable itself).

请注意, [Reflection.Assembly] :: LoadWithPartialName()被正式声明为废弃 ,因为通过加载程序集由于安装了不兼容的版本或具有重复简单名称的程序集,>简单名称稍后可能会破坏现有代码.

Note that [Reflection.Assembly]::LoadWithPartialName() is officially declared obsolete, because loading assemblies by simple name can break existing code later, due to installation of incompatible versions or assemblies with duplicate simple names.

但是,以晚期绑定脚本语言(例如PowerShell),可以使用简单名称进行加载( Add-Type -AssemblyName (不是过时的),并简化了加载(您可以指定程序集的明确的全名,但是-参见下文).

However, in a late-bound scripting language such as PowerShell, loading by simple name may be acceptable (Add-Type -AssemblyName is not obsolete), and simplifies loading (you can specify an assembly's unambiguous full name, however - see below).

当然,如果 [Reflection.Assembly] :: LoadWithPartialName('System.EnterpriseServices')对于您莫名其妙地不起作用,则 Add-Type -AssemblyName System.EnterpriseServices 可能类似地失败,但是总的来说还是挺好的.

Of course, if [Reflection.Assembly]::LoadWithPartialName('System.EnterpriseServices') inexplicably didn't work for you, Add-Type -AssemblyName System.EnterpriseServices may similarly fail, but the general point stands.

[Reflection.Assembly] :: LoadWithPartialName()的推荐替代值为

The recommended replacement for [Reflection.Assembly]::LoadWithPartialName() is [Reflection.Assembly]::Load(), which is what you ended up using. It requires you to know the assembly's full name, which must include the assembly's full version number and its public key - although a lower version number than the one actually present in the GAC is seemingly accepted.

请注意, 添加类型-AssemblyName 也接受(以强名称命名)完整的程序集名称:

Note that Add-Type -AssemblyName accepts (strong-named) full assembly names too:

# Load from the GAC by *full assembly name*.
# Equivalent of [Reflection.Assembly]::Load()
Add-Type -AssemblyName 'System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'


退后一步:


Taking a step back:

我建议避免在GAC中放置自定义程序集:,原因有两个:

  • PowerShell [Core] 6+,最终将使Windows PowerShell过时,它基于.NET Core 构建,而不再具有GAC ,因此在迁移时您将需要其他方法.

  • PowerShell [Core] 6+, which will eventually make Windows PowerShell obsolete, is built on .NET Core, which doesn't have a GAC anymore, so you'll need a different approach when you migrate.

  • 在PowerShell [Core]中, Add-Type -AssemblyName 在PowerShell附带的程序集中查找由简单名称给出的程序集,尽管它看起来在 current 中目录优先.
  • In PowerShell [Core], Add-Type -AssemblyName looks for assemblies given by simple name among the assemblies that ship with PowerShell itself, though it looks in the current directory first.

系统.正式不支持直接使用您使用的EnterpriseServices.Internal.Publish 类型:.NET Framework在内部使用" Publish ".您不需要直接在代码中使用它.",并且正式支持的在GAC中安装程序集的唯一方法是通过 Windows Installer ( gacutil.exe 是仅用于开发).

The System.EnterpriseServices.Internal.Publish type you're using isn't officially supported for direct use: "Publish is used internally by the .NET Framework. You do not need to use it directly in your code.", and the only officially supported way to install assemblies in the GAC is via Windows Installer (gacutil.exe is only meant to be used during development).

相反,我推荐以下方法:

  • 编写一个包装目标程序集的辅助PowerShell模块 ,命名为 BCrypt .

将该模块放置在 $ env:PSModulePath 中列出的目录之一中,以便任何执行 Import-Module BCrypt 的脚本>将感兴趣的程序集隐式加载到会话中.

Place that module in one of the directories listed in $env:PSModulePath, so that any script executing Import-Module BCrypt implicitly loads the assembly of interest into the session.

这样的模块很容易编写:

Such a module is easy to author:

  • 选择在 $ env:PSModulePath 中列出的合适目录,并在其中创建一个名为 BCrypt 的子目录.

  • Choose a suitable directory listed in $env:PSModulePath and create a subdirectory named, say, BCrypt in it.

将程序集DLL( BCrypt.Net-Next.dll )复制到该子目录中.

Copy your assembly DLL (BCrypt.Net-Next.dll) into that subdirectory.

切换到子目录并在其中创建模块清单 BCrypt.psd1 :

Change to the subdirectory and create a module manifest BCrypt.psd1 there:

  New-ModuleManifest BCrypt.psd1 -RequiredAssemblies BCrypt.Net-Next.dll -ModuleVersion 1.0

提供其他 New-ModuleManifest 参数,和/或根据需要在事实之后编辑模块清单.

Provide additional New-ModuleManifest arguments as needed and/or edit the module manifest after the fact, as needed.

这篇关于无法使用Powershell在Windows 10上将Bcrypt.Net-Next程序集安装到GAC中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆