Восстановление псевдонима PowerShell при выгрузке модуля

#powershell

#powershell

Вопрос:

Как мне восстановить псевдоним PowerShell, когда мой модуль был выгружен.

Код, который у меня есть до сих пор, не работает, хотя выполнение Set-Alias команды само по себе работает. Он сохраняет определение в локальной переменной, которая доступна при запуске OnRemove события.

 $orig_cd = (Get-Alias -Name 'cd').Definition
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
    Set-Alias -Name 'cd' -Value $orig_cd -Force -Option AllScope -Scope Global
}
  

Я должен также упомянуть, что я переопределяю существующий псевдоним команды cd следующим образом

 Set-Alias -Name cd -Value cdX -Force -Option AllScope -Scope Global
  

Вот исходный код модуля https://github.com/vincpa/z/blob/master/z.psm1

Обновить

Добавление Write-Host команды в обработчик OnRemove показывает, что значение $orig_cd действительно Set-Location равно .

Комментарии:

1. Как насчет использования прокси-функции для Remove-Module, которая проверяет, удаляется ли ваш модуль, и сначала восстанавливает псевдоним?

2. Я еще не понял, что происходит с блоком OnRemove и областями, но не рассматривали ли вы возможность оставить только псевдоним «cd» по умолчанию и вместо этого экспортировать функцию с именем «Set-Location» из этого модуля? Псевдоним cd по умолчанию будет вызывать эту функцию до тех пор, пока модуль загружен, и вернется к вызову обычного командлета, когда модуль будет удален.

3. Я бы попробовал добавить некоторые выходные данные в ваш обработчик onremove, чтобы вы могли узнать, каково значение $orig_cd в этой области. Модули и области не всегда работают так, как вы ожидаете.

4. PowerShell каким-то образом фиксирует создаваемый псевдоним, являющийся частью выгружаемого модуля?

5. Вы также можете проверить — github.com/manojlds/posz 🙂

Ответ №1:

Я попробовал это, и это работает:

 $orig_cd = (Get-Alias -Name 'cd').Definition
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
    set-item alias:cd -value $orig_cd
}

Set-item alias:cd -Value 'cdX'
  

Кроме того, предложение — вы пишете модуль, который люди будут использовать в своих терминалах. Я не ожидаю варианта использования, когда кто-то захочет удалить ваш модуль. Эти шаги могут быть излишними для модуля, который вы пишете.

Комментарии:

1. Вы предполагаете, что людям понравится мой модуль после его тестирования. Если они этого не сделают, они, скорее всего, захотят выгрузить его. Да, это имеет значение 🙂

Ответ №2:

Хотя about_scopes немного сбивает с толку, поставщик псевдонимов выглядит так, как будто у него есть ключ.

Область псевдонима уже ограничена, AllScope что означает, что дочерняя область имеет копии / доступ. Все, что вам нужно сделать, это изменить значение.

Посмотрите на переключатель -Options в Set-Alias http://technet.microsoft.com/en-us/library/hh849938.aspx

— AllScope: псевдоним копируется во все новые области, которые создаются.

 #Override the existing CD command with the wrapper in order to log 'cd' commands.
Set-Item alias:cd -Value 'cdx'
Set-Alias -Name pushd -Value pushdX -Force -Option AllScope -Scope Global

$orig_cd = (Get-Alias -Name 'cd')
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
    set-item alias:cd -value 'set-content'
}

Export-ModuleMember -Function z, cdX, pushdX -alias ''
  

Комментарии:

1. После выгрузки модуля псевдоним ‘cd’ просто указывает на ‘cd’, что делает команду неработающей.