Refresh and enable the ComInterop code in PowerShell by daxian-dbw · Pull Request #13304 · PowerShell/PowerShell

PR Summary

Fix #12842

Refresh and enable the ComInterop code in PowerShell to get significant perf improvement in COM related operations.

Perf Comparison

Here is the perf difference shown by running the real world script provided in #12842 (comment)
It's 20x faster with this PR.

PowerShell 7.0.3

Started script

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Could not find Timezones.csv in C:\arena\tmp\comInterop\testing.
Script will continue, ID will be used instead of time-zone name.
Config system global line found.
Section done.
Config system interface line found.
Section done.
Config router static line found.
Section done.
Creating Table of Contents
Writing Excelfile C:\arena\tmp\comInterop\testing\PerfTest_20200526_0942.xls
Script done in 2 Minute(s) and 6 Second(s).

Private build with this PR

Started script

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Could not find Timezones.csv in C:\arena\tmp\legacy-comInterop-code\real-world-test-script.
Script will continue, ID will be used instead of time-zone name.
Config system global line found.
Section done.
Config system interface line found.
Section done.
Config router static line found.
Section done.
Creating Table of Contents
Writing Excelfile C:\arena\tmp\legacy-comInterop-code\real-world-test-script\PerfTest_20200526_0942.xls
Script done in 0 Minute(s) and 6 Second(s).

ComInterop Context

NOTE: This comes from the content in engine/ComInterop/README.md, please review for the detailed information.

The ComInterop code shipped in PowerShell comes from dotnet/runtime with a considerable amount of refactoring work to make it work properly with PowerShell.

There are 3 sources of the ComInterop code as our references:

  1. The .NET Framework version.
    The code was archived in 2012.

  2. The .NET 5.0 version.
    It was merged into .NET 5.0 in May 2020 through the PR dotnet/runtime#33060.
    It's based on the .NET Framework version code with quite amount of refactoring work.

  3. The legacy ComInterop code from Windows PowerShell.
    The legacy code has always been in the repository, but it was excluded from compilation.
    It was based on the .NET Framework version code with a considerable amount of refactoring work to make it work properly with Windows PowerShell.

Code Refreshing

The ComInterop code was refreshed and enabled in compilation in PowerShell 7.1, August 2020.
It was done manually by:

  • A careful three-way comparison across all the code sources listed above:

    • Compare (3) to (1) to get the PowerShell specific changes
    • Compare (2) to (1) to get the .NET 5.0 changes
  • Applying the PowerShell specific changes from (3) to (2), with necessary further refactoring

  • A careful review of the new PowerShell specific changes applied to (2), again using the three-way comparison:

    • Compare the refreshed ComInterop code with (3) to get the differences
    • Analyze the differences to make sure they are either the pure .NET 5.0 changes over the .NET Framework code,
      or the refactoring changes that is necessary to apply the PowerShell specific changes.

PR Checklist