1

現時点で多くの頭痛の種となっているコード例を次に示します。

if (("Win32.NativeMethods" -as [type]) -eq $null){
    Add-Type -MemberDefinition '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        ' -name NativeMethods -namespace Win32
}

class AppInstance 
{    
    [string]$App = 'Notepad.exe'
    [IntPtr]$hWnd = 0
    [System.Object]$process

    AppInstance () {
        Start-Process $this.App
        $this.process = get-process ($this.App.split('.'))[0]
        start-sleep -Milliseconds 100
        $this.hWnd = $this.process.MainWindowHandle    
    }

    [void] Show () {
        [Win32.NativeMethods]::ShowWindowAsync($this.hWnd, 3)
    }

    [void] Hide () {
        [Win32.NativeMethods]::ShowWindowAsync($this.hWnd, 2)
    }
}

このクラスは次のように使用できます

$notepad = [AppInstance]::new()
$notepad.Hide()
$notepad.Show()

基本的に、私がやろうとしているのは、型としてから関数をインポートし、user32.dllこの[Win32.NativeMethods]型を で使用することclassです。

Add-Typeタイプでステートメントを個別に実行すると、Powershell_ISE作成された後、スクリプトは正常に機能します。

ただし、タイプを手動で作成する前にスクリプト全体を実行しようとすると、次の Powershell パーサー エラーが発生します。

At C:\class.ps1:26 char:10
+         [Win32.NativeMethods]::ShowWindowAsync($this.hWnd, 3)
+          ~~~~~~~~~~~~~~~~~~~
Unable to find type [Win32.NativeMethods].
At C:\Uclass.ps1:31 char:10
+         [Win32.NativeMethods]::ShowWindowAsync($this.hWnd, 2)
+          ~~~~~~~~~~~~~~~~~~~
Unable to find type [Win32.NativeMethods].
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TypeNotFound

パーサーがAdd-Typeステートメントを無視し、実行前に終了しているようです。

この問題を克服する方法はありますか? 多分using声明で?または、型が動的に作成されたことをパーサーに伝える方法はありますか?

編集1:

Using .Net Objects within a Powershell (V5) Classへの回答を読みましたが、受け入れられた回答は私の質問に対する回答ではありません。単純なスクリプトを複数のファイルに分割することは、実際には答えではありません。

私が求めているのは、タイプが動的に作成されたことをパーサーに伝える方法があるということです。

編集2:

これをもう少し明確にするために、上記と同等のコードを次に示しますが、functions代わりに を使用して実装されていclassesます。

if (("Win32.NativeMethods" -as [type]) -eq $null){
    Add-Type -MemberDefinition '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        ' -name NativeMethods -namespace Win32
}

[string]$script:App = 'Notepad.exe'

$process = Start-Process $App -PassThru


function Show () {
    [Win32.NativeMethods]::ShowWindowAsync($process.MainWindowHandle, 3)
}

function Hide () {
    [Win32.NativeMethods]::ShowWindowAsync($process.MainWindowHandle, 2)
}

このコードは完全に正常に解析および実行されます。classesスクリプトの残りの部分とは異なる方法でパーサーによって処理されますか?

4

1 に答える 1