将字符串从 Win32 应用程序传递到 PowerShell 脚本的最有效方法是什么?

问题描述 投票:0回答:1

我正在编写一个将从 PowerShell 脚本调用的本机 Win32 应用程序。它需要以字符串的形式将结果传递回 PowerShell 脚本(因此它不仅仅是一个整数。)

最有效的方法是什么?

c++ powershell winapi
1个回答
0
投票

以有用的评论为基础:

  • 进程外解决方案最简单,但效率不高:

    • 将您的应用程序创建为console子系统应用程序,并使其通过其stdout流输出字符串。

      • 与任何 shell 一样,PowerShell 可以直接调用您的应用程序并捕获其输出(例如,
        $output = .\yourapp.exe ...
    • PowerShell 根据存储在

      Console.OutputEncoding
      中的编码对此类字符串进行解码,默认为系统的旧版 OEM 代码页。

      • 这限制了可以编码的字符,并且需要转码为本机 .NET 字符串(由 UTF-16 代码单元组成)。

      • 但是,只要调用 PowerShell 脚本(临时)设置

        [Console]::OutputEncoding = [System.Text.Encoding]::Unicode
        ,您就可以自由发出 UTF-16LE 字符串; UTF-8 也是如此 (
        [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
        )。

        • 虽然 UTF-16LE 允许最直接解码为 .NET 字符串,但我怀疑性能差异在实践中是否重要,尤其是在 PowerShell 脚本的上下文中。
        • 现在可以将系统配置为使用 UTF-8 系统范围(将 ANSI 和 OEM 代码页设置为
          65001
          ,即 UTF-8),但请注意,这具有 深远的影响后果 - 请参阅此答案了解详细信息。
  • 流程内解决方案,效率更高:

    Add-Type -Namespace SampleNS -Name Sample -UsingNamespace System.Text -MemberDefinition @' // P/Invoke declaration // Note the use of `CharSet=CharSet.Unicode` to ensure // that the *Unicode* version is called. [DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern int GetWindowText(IntPtr hWnd, StringBuilder stringBuf, int nMaxCount); // Convenience function that wraps the StringBuilder logic public static string GetWindowText(IntPtr hWnd) { var sb = new StringBuilder(1024); // Preallocate the buffer. GetWindowText(hWnd, sb, sb.Capacity+1); return sb.ToString(); } '@ # Invoke with the current PowerShell window's handle. [SampleNS.Sample]::GetWindowText( (Get-Process -Id $PID).MainWindowHandle )

© www.soinside.com 2019 - 2024. All rights reserved.