了解如何在没有 C# Cmdlet 定义的情况下将详细或调试字符串消息写入 PowerShell 运行空间

2024-01-10

我有一个 C# 类库,它提供了许多可以从 PowerShell 脚本 (.PS1) 和高级模块 (.PSM1) 调用的接口。我有一个静态方法可以使用以下命令将详细消息和调试消息写入控制台System.Console class:

public class Write
{

        public static void Verbose(string msg, string source)
        {

            if (Config.EnableVerbose)
            {

                ConsoleColor originalForeGroundColor = Console.ForegroundColor;
                ConsoleColor originalBackGroundColor = Console.BackgroundColor;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.BackgroundColor = ConsoleColor.Black;
                Console.Write("VERBOSE: {0} {1}{2}", source, msg, Environment.NewLine);
                Console.ForegroundColor = originalForeGroundColor;
                Console.BackgroundColor = originalBackGroundColor;

            }

       }

}

但是,当这些消息显示在 PowerShell 控制台中时,无法使用重定向来捕获它们,就像使用Out-File, >&0甚至与Start-Transcript.

我读过了about_Redirection,并且使用重定向修饰符不会捕获控制台输出。例如,使用我编写的 PowerShell 高级功能(又名 Cmdlet):

Get-CommandTrace -ScriptBlock { Get-Resource } *> C:\Temp\capture.log

The Get-CommandTraceCmdlet 设置$VerbosePreference = 'Continue'在 ScriptBlock 执行期间,并捕获详细信息Get-Resource那里输出。但不捕获我的 C# 库的控制台输出。

所以,我的问题很简单:既不是 Cmdlet 类也不是继承类的 C# 类是否能够将输出写入调用它的现有 PowerShell 运行空间?


Note:

  • This is not一个完整的答案,因为它有严格的限制 - 尽管它可能适用于特定的用例。

  • 该答案使用的原始形式已弃用的 PowerShell SDK 方法.CreateNestedPipeline() https://github.com/PowerShell/PowerShellStandard/issues/42#issuecomment-516255508,如果您针对的是编写代码,则不能再使用PowerShell标准库 https://github.com/PowerShell/PowerShellStandard为了实现跨平台和跨版本兼容性(应在所有受支持的平台上的 Windows PowerShell 和 PowerShell Core 中运行的代码)。
    克里斯(OP)本人找到了一个兼容的替代方案,该答案的当前形式就是基于该替代方案。


挑战是写信给调用管道的输出流(正如您观察到的那样Console与 PowerShell 的输出流无关,直接打印到控制台,无法在 PowerShell 中捕获或重定向此类输出)。

虽然您可以获得调用的参考runspace,据我所知,没有办法获得对运行管道.

使用调用运行空间,您可以通过以下方式写入 PowerShell 的输出流:new管道,但附带严重的限制:

  • You 不能直接写入调用者的成功输出流 (1) 那样;也就是说,虽然您可以调用针对other流,例如Write-Verbose, Write-Output/ 隐式输出确实not work.

  • 在变量中捕获此嵌套管道的输出或通过管道发送输出需要将方法调用括起来(...) (or $(...) or @(...))除了对成功输出流应用适当的重定向(例如,4>&1对于详细流)。

详细信息请参见代码注释。

Add-Type -TypeDefinition @'
  using System.Management.Automation;

  public class Write
  {

      public static void Verbose(string msg)
      {
        using (PowerShell ps = PowerShell.Create(RunspaceMode.CurrentRunspace)) {
          // IMPORTANT: Use .AddScript(), not .AddCommand().
          //            Even though .AddCommand() + .AddParameter() is arguably a cleaner way to
          //            formulate the command, it results in output that cannot be captured.
          //            As noted, Write-Output / success-stream output does NOT work.
          ps.AddScript("Write-Verbose '" + msg.Replace("'", "''") + "'").Invoke();
        }
      }

  }
'@

#"

$VerbosePreference = 'Continue'
    
# Regular output to the verbose stream.
Write-Verbose 'msg1'

# Verbose output via the custom type.
[Write]::Verbose('msg2')

# SUPPRESSING and REDIRECTING TO A FILE work.
[Write]::Verbose('msg3') 4> $null
[Write]::Verbose('msg4') 4> t.txt

# By default, REDIRECTING TO THE STANDARD OUTPUT STREAM (1) 
# works only for the OUTSIDE, i.e. for CALLERS of this script.
[Write]::Verbose('msg5') 4>&1

# Redirecting to the standard output stream (1) can also be used to:
#  * CAPTURE the result INSIDE your script
#  * SEND THE RESULT THROUGH THE PIPELINE, 
# additionally invoke the method call enclosed in (...) or $(...) or @(...)
$out = ([Write]::Verbose('msg6') 4>&1); "captured: [$out]"
([Write]::Verbose('msg7') 4>&1) | ForEach-Object { "piped: [$_]" }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解如何在没有 C# Cmdlet 定义的情况下将详细或调试字符串消息写入 PowerShell 运行空间 的相关文章

  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 通过PowerShell检索Azure AD应用程序的“API权限”

    出于报告和监视的目的 我想检索应用程序 应用程序注册 的 Azure 门户中显示的信息以获取 API 权限 我尝试过以下代码 app Get AzureADApplication ObjectId aa7e174d 2639 4ac7 9b
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri

随机推荐