Могу ли я написать бинарный командлет PowerShell с .NET Core?

Я пытаюсь создать базовый модуль PowerShell с внутренними компонентами Cmdlet, потому что запись вещей в PowerShell выглядит не так удобно, как на С#.

Следуя этому руководству, похоже, что я должен:

  • добавьте Microsoft.PowerShell.SDK в мой project.json
  • отметить класс cmdlet с обязательными атрибутами
  • напишите файл манифеста с RootModule, настроив мой .dll
  • поставьте .dll ближайший манифест
  • поставьте оба под PSModulePath

но когда я пытаюсь Import-Module, ядро ​​PowerShell жалуется на отсутствие времени выполнения:

Import-Module : Could not load file or assembly 'System.Runtime, Version=4.1.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system
cannot find the file specified.
At line:1 char:1 

Я делаю что-то неправильно, или такие сложные вещи еще не поддерживаются?

Ответ 1

Это становится намного проще с .NET Core 2.0 SDK и Visual Studio 2017 Update 15.3 (или выше). Если у вас нет VS, вы можете сделать это из командной строки с помощью .NET Core 2.0 SDK.

Важным битом является добавление пакета PowerShellStandard.Library 3.0.0-preview-01 (или выше) NuGet в файл проекта (.csproj).

Вот пример простой командной строки:

cd $home
dotnet new classlib --name psmodule
cd .\psmodule
dotnet add package PowerShellStandard.Library --version 3.0.0-preview-01
Remove-Item .\Class1.cs
@'
using System.Management.Automation;

namespace PSCmdletExample
{
    [Cmdlet("Get", "Foo")]
    public class GetFooCommand : PSCmdlet
    {
        [Parameter]
        public string Name { get; set; } = string.Empty;

        protected override void EndProcessing()
        {
            this.WriteObject("Foo is " + this.Name);
            base.EndProcessing();
        }
    }
}
'@ | Out-File GetFooCommand.cs -Encoding UTF8

dotnet build
cd .\bin\Debug\netstandard2.0\
ipmo .\psmodule.dll
get-foo

Для получения этой же команды для запуска в Windows PowerShell 5.1 требуется немного больше работы. Перед тем, как команда будет работать, вам необходимо выполнить следующее:

Add-Type -Path "C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\netstandard.dll"

Ответ 2

Вам нужно использовать PowerShell Core, чтобы написать CmdLet PowerShell в .NET Core.

Здесь есть руководство, включая исправления для вашего project.json: https://github.com/PowerShell/PowerShell/tree/master/docs/cmdlet-example

Подводя итог, вам нужно следующее в project.json

    "dependencies": {
        "Microsoft.PowerShell.5.ReferenceAssemblies": "1.0.0-*"
    },

    "frameworks": {
        "netstandard1.3": {
            "imports": [ "net40" ],
            "dependencies": {
                "Microsoft.NETCore": "5.0.1-*",
                "Microsoft.NETCore.Portable.Compatibility": "1.0.1-*"
            }
        }
    }