c# - 从 PowerShell 中引用 C# 定义的结构时出现管道错误
问题描述
我有以下内容struct
,并且class
作为 PS 脚本模块的一部分。这部分代码是用 C# 编写的,并处理在将模块导入 PowerShell 会话时运行的代码,尽管OnImport()
我没有在此处包含这些位。这不是 C# 代码所做的一切,足以展示我面临的问题:
Add-Type -IgnoreWarnings @"
using System;
using System.Reflection;
using System.Management.Automation;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Runtime.Versioning;
namespace MyPowerShell {
public struct State {
public readonly static ICertificatePolicy OriginalSystemCertificatePolicy = ServicePointManager.CertificatePolicy;
public readonly static ICertificatePolicy SkipSSLCheckPolicy;
public readonly static Version PSVersion;
public readonly static string Framework;
static State() {
PSVersion = new Version(
$($PSVersionTable.PSVersion.Major),
$($PSVersionTable.PSVersion.Minor),
$($PSVersionTable.PSVersion.Build),
$($PSVersionTable.PSVersion.Revision)
);
OriginalSystemCertificatePolicy = ServicePointManager.CertificatePolicy;
SkipSSLCheckPolicy = new TrustAllCertsPolicy();
}
}
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
}
"@
这工作正常,一旦完成,我就可以从 PowerShell引用struct
属性和罚款:class
Add-Type
# Each of these returns the information expected and I can instantiate TrustAllCertsPolicy
[MyPowerShell.State]::PSVersion
[MyPowerShell.State]::OriginalSystemCertificatePolicy
[MyPowerShell.State]::SkipSSLCheckPolicy
$policy = [MyPowerShell.TrustAllCertsPolicy]::new()
但是我尝试以不同的方式添加从不依赖于扩展$PSVersionTable.PSVersion
源中属性的代码中检测当前 PowerShell 版本,稍微here string
修改定义:struct
public struct State {
public readonly static ICertificatePolicy OriginalSystemCertificatePolicy = ServicePointManager.CertificatePolicy;
public readonly static ICertificatePolicy SkipSSLCheckPolicy;
public readonly static Version PSVersion;
public readonly static string Framework; # Added this line
static State() {
PSVersion = new Version(
$($PSVersionTable.PSVersion.Major),
$($PSVersionTable.PSVersion.Minor),
$($PSVersionTable.PSVersion.Build),
$($PSVersionTable.PSVersion.Revision)
);
OriginalSystemCertificatePolicy = ServicePointManager.CertificatePolicy;
SkipSSLCheckPolicy = new TrustAllCertsPolicy();
# Added the following 2 lines
TargetFrameworkAttribute attribute = Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), typeof(TargetFrameworkAttribute)) as TargetFrameworkAttribute;
Framework = attribute.FrameworkName;
}
// TrustAllCertsPolicy Code
}
一旦我添加代码以FrameworkName
从 的静态构造函数中的条目程序集中提取属性struct
,它仍然可以编译,但我不能再引用所有属性上的任何属性,struct
从而导致管道错误:
[MyPowerShell.State]::PSVersion
An error occurred while creating the pipeline.
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : RuntimeException
但是,我可以使用以下调用来代替 set Framework
,AssemblyProductAttribute
而不是从调用程序集中使用,我没有问题:
static State() {
PSVersion = new Version(
$($PSVersionTable.PSVersion.Major),
$($PSVersionTable.PSVersion.Minor),
$($PSVersionTable.PSVersion.Build),
$($PSVersionTable.PSVersion.Revision)
);
OriginalSystemCertificatePolicy = ServicePointManager.CertificatePolicy;
SkipSSLCheckPolicy = new TrustAllCertsPolicy();
// Replaced the next two lines with this
AssemblyProductAttribute productAttr = Attribute.GetCustomAttribute(Assembly.GetCallingAssembly(), typeof(AssemblyProductAttribute)) as AssemblyProductAttribute;
Framework = productAttr.Product;
}
为什么struct
当我尝试从入口程序集获取时,我的 PowerShell 变得无法使用,但从调用程序集TargetFrameworkAttribute
获取时却可以正常工作?AssemblyProductAttribute
解决方案
如果您检查底层异常,您会发现原因是Attribute.GetCustomAttribute()
在静态构造函数中传递了一个空引用。
PS ~> $Error[0].GetBaseException() |Format-List -Force
Message : Value cannot be null.
Parameter name: element
ParamName : element
Data : {}
InnerException :
TargetSite : System.Attribute[] GetCustomAttributes(System.Reflection.Assembly, System.Type,
Boolean)
StackTrace : at System.Attribute.GetCustomAttributes(Assembly element, Type attributeType,
Boolean inherit)
at System.Attribute.GetCustomAttribute(Assembly element, Type attributeType,
Boolean inherit)
at State..cctor()
HelpLink :
Source : mscorlib
HResult : -2147467261
调用Assembly.GetEntryAssembly()
返回null
是因为宿主应用程序实际上不是托管程序集 -powershell.exe
是本机 Win32 PE。
推荐阅读
- flutter - 动态 ListView 内的 ListView ( Pagewise )
- css - 父容器有overflow:auto,但是当屏幕高度改变时子容器的高度仍然改变
- javascript - DataTables - 从单元格数据中的跨度获取 ID
- ajax - 使用分页的 Wordpress 延迟加载
- r - 警告信息 - 来自 dummies 包的 dummy
- c++ - 无法在不使用变量的情况下比较 C++ 中的字符串
- python-3.x - Python 停止了打开 Jupiter 笔记本的工作
- python - 如何在枚举的 for 循环中获取索引结果列表
- angular - 当输入值不变时如何强制对输入进行更改检测
- python - 在 Django 虚拟环境中使用 mysqlclient 进行迁移时出现问题