Скрипт работает в ISE, но не в Powershell - PullRequest
0 голосов
/ 05 мая 2018

У меня есть сценарий powershell . Этот скрипт прекрасно работает, если я открою его в Powershell ISE, однако, если я щелкну правой кнопкой мыши по файлу и нажму «запустить с powershell», скрипт выдаст ошибку.

Кроме того, я читал в предыдущих темах, что следующий шаблон выполнения решил проблему для некоторых людей:

powershell -STA -File script.ps1

В этом случае это не решило проблему, однако позволило прочитать ошибку:

At C:\Users\sancarn\AppData\Local\Temp\script.ps1:20 char:20
+         $parent = [System.Windows.Forms.TreeNode]$global:database.Ite ...
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.TreeNode].
At C:\Users\sancarn\AppData\Local\Temp\script.ps1:27 char:36
+ ...          [void]$node.nodes.add([System.Windows.Forms.TreeNode]::new(" ...
+                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.TreeNode].
At C:\Users\sancarn\AppData\Local\Temp\script.ps1:33 char:45
+ ... PSCustomObject]IWDBGetChildren([System.Windows.Forms.TreeNode]$node)  ...
+                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.TreeNode].
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TypeNotFound

С учетом вышесказанного, я не уверен, что могу действительно что-то сделать с этой ошибкой конкретно ... Я уже загружаю System.Windows.Forms и System.Drawing ... У кого-нибудь есть идеи, как правильно выполнить этот файл?

Редактировать

Другие попытки решить проблему:

powershell -NoExit -STA -File script.ps1
powershell -NoExit -STA -File script.ps1 -Scope Global

Редактировать 2

Я также попытался добавить:

Add-Type -AssemblyName System.Windows.Forms

В начало сценария powershell. Однако проблема остается нерешенной.


Edit:

Не уверен, почему это помечается как дубликат после

  1. этот ответ уже имеет рекомендуемый ответ и
  2. рекомендуемый ответ показывает, почему это не так.

...

1 Ответ

0 голосов
/ 05 мая 2018

Как сказал @PetSerAl в своем комментарии, ответ на вопрос https://stackoverflow.com/a/34637458

Каждый скрипт PowerShell полностью анализируется перед выполнением первого оператора в скрипте. Неразрешимый маркер имени типа в определении класса считается ошибкой разбора. Чтобы решить вашу проблему, вы должны загрузить свои типы перед анализом определения класса, поэтому определение класса должно быть в отдельном файле.

В конечном счете, чтобы решить проблему, мне нужно либо загрузить определения моего класса в виде отдельного файла, либо сохранить мои объявления в заголовочном файле, который вызывает определения класса (и остальную часть сценария).

Я поражен, что это даже было проблемой, но теперь это работает, так что это хорошо ...

Редактировать

В моем случае это немного отличается от поста, на который ссылается автор решения. Я на самом деле собираю библиотеку ruby ​​для запуска Powershell на машинах с Windows. В настоящее время я не записываю данные в файл и не могу гарантировать, что выражение here-string / invoke-expression будет работать.

Invoke-Expression @"
$anotherString=@"
    hello world!
"@    
"@ <--- Powershell will throw an error here!

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

require 'base64'
if header!=""
    encoded_body = Base64.strict_encode64(body.encode("utf-16le"))
    body = <<-END_TRANSFORMATION
        #{header}

        $encoded_body = "#{encoded_body}"
        Invoke-Expression $([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($encoded_body)))
    END_TRANSFORMATION
end

Пока что это работает во всех случаях, не требует внешних файлов и будет работать, даже если пользователи используют строки here-doc в своих скриптах Powershell!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...