PowerShellで別ファイルのクラスを読み込む(入れ子対応)

1.PowerShellで別ファイルのクラスを読み込む

 PowerShellで別ファイルに分割したクラスを読み込むときに「入れ子」が発生し、うまくいかないことがあった。

 Form1とForm2を作成し、お互いがお互いを参照しあうような場合に同じファイルを読み込んでしまいエラーが発生する。
 いろいろとネットを調べてみたけど解決策を見つけることができなかった。そもそもPowerShellで複数画面のWindowsフォームの開発をするのが間違っている気もするが、環境的にVSが入れれないので仕方なくいろいろと試してみた。

Form1.ps1
********************
$IncludeFile = Join-Path $PSScriptRoot "frm020_0000.ps1"
. $IncludeFile

# -----------------------------------------------------------------------
#  メイン画面を作成
# -----------------------------------------------------------------------
Class clsfrm010_0000 :System.Windows.Forms.Form {
    $lblTitle=[Label]@{
        Location = [Point]::new(5,5);
        Size=[Size]::new(250,20);
        Text = “タイトル”; 
    }

    #   ▼画面2を表示
    $btnOpenFrm02_0000=[Button]@{
        Location = [Point]::new(5,25);
        Size=[Size]::new(150,25);
        Text = "画面2を表示";
    }

    # コンストラクタ
    clsfrm010_0000 (){
        $this.Initialize();
    }
    
   # ------------------------------------------------------------------
    # 初期化処理
    # ------------------------------------------------------------------
    Initialize() {
        $this.Text = "画面1"
        $this.Size = [Size]::new(950, 720);
        $this.Font = New-Object Drawing.Font("MS Gothic",10) ;
        
        $this.Controls.Add($this.lblTitle);
        $this.Controls.Add($this.btnOpenFrm02_0000);
        # 作業開始遅延一覧
        $btnOpenFrm02_0000_Click = {
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.FindForm();
            $frmSearch = [clsfrm020_0000]::new();
            #$frmSearch = New-Object "clsfrm020_0000";
            $frmSearch.frmProject = $form;
            $frmSearch.Show();
        }
        $this.btnOpenFrm02_0000.add_Click($btnOpenFrm02_0000_Click);
    }
}


Form2.ps1
********************
$IncludeFile = Join-Path $PSScriptRoot "frm010_0000.ps1"
. $IncludeFile
# ------------------------------------------------------------------
#  メイン画面を作成
# ------------------------------------------------------------------
Class clsfrm020_0000 :System.Windows.Forms.Form {
    $lblTitle=[Label]@{
        Location = [Point]::new(5,5);
        Size=[Size]::new(250,20);
        Text = “タイトル”; 
    }

    #   ▼画面1を表示
    $btnOpenFrm01_0000=[Button]@{
        Location = [Point]::new(5,25);
        Size=[Size]::new(150,25);
        Text = "画面1を表示";
    }

    # コンストラクタ
    clsfrm020_0000 (){
        $this.Initialize();
    }
    
    # ------------------------------------------------------------------
    # 初期化処理
    # ------------------------------------------------------------------
    Initialize() {
        $this.Text = "画面2"
        $this.Size = [Size]::new(950, 720);
        $this.Font = New-Object Drawing.Font("MS Gothic",10) ;
        
        $this.Controls.Add($this.lblTitle);
        $this.Controls.Add($this.btnOpenFrm01_0000);
        # 作業開始遅延一覧
        $btnOpenFrm01_0000_Click = {
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.FindForm();
            $frmSearch = [clsfrm010_0000]::new();
            #$frmSearch = New-Object "clsfrm010_0000";
            $frmSearch.frmProject = $form;
            $frmSearch.Show();
        }
        $this.btnOpenFrm01_0000.add_Click($btnOpenFrm01_0000_Click);
    }
}

2.対応方法

標準モジュールにしてみたり、継承してうまくできないかいろいろと試したが、一番シンプルな対応方法は、以下のようにすることだった

 2-1.Form1.psとForm2.psの内容を書き換え

  $frmSearch = [clsfrm010_0000]::new();

     ↓

    $frmSearch = New-Object "clsfrm010_0000";


  $frmSearch = [clsfrm020_0000]::new();

     ↓

    $frmSearch = New-Object "clsfrm020_0000";

 2-2.Main.ps1を作ってそこから呼び出す


Main1.ps

******************************
using namespace System.Windows.Forms;
using namespace System.Drawing;

#デバッグ する際にはターミナルで流しておく必要がある。Classの継承を行っており、Class定義がスクリプトの中で一番最初に読み込まれる(?)ためエラーが出る。先に別ファイルやターミナルで実行することで回避

Add-Type -AssemblyName System.Windows.Forms;
Add-Type -AssemblyName System.Drawing;
# ISE上でデバッグするときには実行 →  Set-ExecutionPolicy RemoteSigned -Scope Process

# インクルードファイル
$IncludeFile = Join-Path $PSScriptRoot "Form1.ps1"
. $IncludeFile

$IncludeFile = Join-Path $PSScriptRoot "Form2.ps1"
. $IncludeFile

$frm = New-Object "clsfrm010_0000";
$frm.ShowDialog();

*****************

0 件のコメント:

コメントを投稿

PowerShellでEdgeを自動化(インストール不要。参考:郵便追跡サービス自動操作)

1.経緯について  RPAのソフトをインストールできないので、これまでVBSでCreateObjectでブラウザの自動操作をすることがたまにあった。 ※いざというときの手札として持っているだけで安心感が段違い  見た目上IEがインストールされていなくても、CreateObject...