导入模块时PowerShell Types.ps1xml找不到类型

时间:2020-09-29 22:25:35

标签: c# powershell types module binary

我无法导入包含清单,二进制文件(根模块)和类型文件的模块,该文件定义了引用二进制文件中标识的类型的类型转换器或代码属性。

当我尝试导入模块时,从详细的输出中可以看到,在导入二进制模块的类之前先加载类型文件:

VERBOSE: Loading module from path '...\bin\Debug\Module\manifest.psd1'.
VERBOSE: Loading 'TypesToProcess' from path '...\bin\Debug\Module\Type.PS1XML'.

在加载根模块之前,出现以下错误:

Import-Module : The following error occurred while loading the extended type data file: , ...\bin\Debug\Module\Type.PS1XML(64) :
Error: Unable to find type [MyRootModule.MyItemConverter].
At line:1 char:128
+ ... odule\Manifest.psd1 | Import-Module -verbose ; $Debu ...
+                                            ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Import-Module], RuntimeException
    + FullyQualifiedErrorId : FormatXmlUpdateException,Microsoft.PowerShell.Commands.ImportModuleCommand

问题是,导入根模块后如何加载类型(不将整个模块转换为通过对模块目录中的每个项目调用Import-ModuleUpdate-TypeData来加载所有内容的脚本)?或者,我还必须采取其他什么方法来解决此错误,并同时导入模块和类型?

这是一个简单的例子。此模块(仅在本地作为示例)具有以下各项:

module\manifest.psd1

module\root.dll

module\type.ps1xml

这是root.dll

的内容
namespace MyRootModule {
  public class MyTestItem {
    public string Name {get; set;}
    public int Id {get; set;}
  }
  public class MyItemConverter : PSTypeConverter {
    // code omitted for brevity
    // effectively creates a 'MyTestItem' with id '1' for string input 'one', and vice versa.
  }
}

这是manifest.psd1

的相关内容
@{
RootModule = 'root.dll'
TypesToProcess = 'type.ps1xml'
}

这是type.ps1xml

的内容
<?xml version="1.0" encoding="utf-8" ?>
<Types>
  <Type>
    <Name>MyRootModule.MyTestItem</Name>
    <TypeConverter>
      <TypeName>MyRootModule.MyItemConverter</TypeName>
    <TypeConverter>
  </Type>
</Types>

如果我先加载二进制模块,然后强制加载清单或使用update-typedata -PrependPath $pathToTypeFile,则一切正常,并且我可以按照期望的方式使用转换器(即[MyRootModule.MyTestItem]1返回[MyRootModule.MyTestItem]的新实例,这表明问题与转换器本身无关。

TLDR; powershell模块正在将类型文件加载到二进制文件之前,并且由于当时找不到二进制文件中定义的类型,因此导入失败。

1 个答案:

答案 0 :(得分:0)

花一些时间,但是如果有人遇到此问题,我会在此处标记答案。模块清单中有一个我遗忘/从未关注的组件,RequiredAssemblies。您可以将dll标记为必需的程序集,并在加载类型文件之前将其标记为要导入的根模块。 (注意:导入cmdlet仍需要将其列为根目录或嵌套模块。)

例如,将上面列出的清单更新为以下内容可解决此问题:

@{
RootModule = 'root.dll'
TypesToProcess = 'type.ps1xml'
RequiredAssemblies = 'root.dll'
}
相关问题