0

インストール済みのアプリケーションを管理し、そのアプリをすばやくアンインストールする方法を提供するために使用している powershell フォームがあります。私がやろうとしているのは、フォーム上のボタンのクラスコンストラクターを作成して、別の関数からフォーム上のボタンの状態を有効または無効にできるようにすることです。以下は私がやろうとしていることですが、他の提案も受け付けています。

Add-Type -AssemblyName System.Windows.Forms

class App
{
    [string] $Name
    [bool] $Installed
    [string] $Key32
    [string] $Key64
    [string] $Inst_Dir
    [bool] $Current
    [string] $Exec
    [string] $User_Ver
    [string] $Inst_Ver

    App ([string] $Name, [bool] $Installed, [string] $Key32, [string] $Key64, [string] $Inst_Dir, [bool] $Current, [string] $Exec, [string] $User_Ver, [string] $Inst_Ver)
    {
        $this.Name = $Name
        $this.Installed = $Installed
        $this.Key32 = $Key32
        $this.Key64 = $Key64
        $this.Inst_Dir = $Inst_Dir
        $this.current = $Current
        $this.Exec = $Exec
        $this.User_Ver = $User_Ver
        $this.Inst_Ver = $Inst_Ver
    }
}

class Button
{    
    [string] $Text
    [int] $Width
    [int] $Height
    [string] $Font
    [bool] $Enabled

    Button ([string] $Text, [int] $Width, [int] $Height, [string] $Font, [bool] $Enabled)
    {
        $this.Text = $Text
        $this.Width = $Width
        $this.Height = $Height
        $this.Font = $Font
        $this.Enabled = $Enabled
    }
}

#region Define and initialize Variables
$HKLM32 = ".\SOFTWARE\Key Location"
$HKLM64 = ".\SOFTWARE\Wow6432Node\Key Location"

# Initialize app classes
[App] $TestApp= [App]::new("TestApp", $false, "$HKLM32\TestApp $TestApp_Ver", "$HKLM64\TestApp $TestApp_Ver", "", $false, "", $TestApp_Ver, "")

$apps = $TestApp

Function create_form()
{
    $Form = New-Object system.Windows.Forms.Form 
    $Form.Text = "Performance Test Auto Setup"
    $Form.TopMost = $true
    $Form.Width = 480
    $Form.Height = 300
    $Form.StartPosition = "CenterScreen"
    $Form.FormBorderStyle = "Fixed3D"
    $Form.MaximizeBox = $false
    $Form.MinimizeBox = $false

    [Button] $btnTestAppUninstall = [Button]::new("Uninstall", 95, 22, "Microsoft Sans Serif, 10", $true)
    New-Object System.Drawing.Point(285, 9)

    <#
    $btnTestAppUninstall = New-Object system.windows.Forms.Button 
    $btnTestAppUninstall.Text = "Uninstall"
    $btnTestAppUninstall.Width = 95
    $btnTestAppUninstall.Height = 22
    $btnTestAppUninstall.location = new-object system.drawing.point(285,9)
    $btnTestAppUninstall.Font = "Microsoft Sans Serif,10"
    $btnTestAppUninstall.Enabled = $false
    $Form.controls.Add($btnTestAppUninstall) 
    $btnTestAppUninstall.Add_Click({uninstallApp($TestApp.Inst_Dir)})
    #>

    $btnTest = New-Object system.windows.Forms.Button 
    $btnTest.Text = "test"
    $btnTest.Width = 95
    $btnTest.Height = 22
    $btnTest.location = new-object system.drawing.point(50,9)
    $btnTest.Font = "Microsoft Sans Serif,10"
    $Form.controls.Add($btnTest) 
    $btnTest.Add_Click({updateUI})


    $Form.ShowDialog() | Out-Null
}

Function updateUI()
{
    $apps | ForEach-Object {$app = [string]("$"+"btn$($_.Name)Uninstall")}
    Write-Host  $app.GetType() $btnTestAppUninstall.GetType()
}


create_Form 

フォーム作成の途中にあるコメントアウトされたセクションは、最初にフォーム作成でボタンを作成していた方法であり、正常に機能します。この問題は、 $apps 配列で foreach-object ループを使用する別の関数から、そのボタンの button.Enabled の状態を調整することによるものです。クラスコンストラクターがボタンを作成しないため、起動時にテストボタンが表示されますが、他には何も表示されません。ボタン変数名を作成するときに、「system.drawings.button」オブジェクトではなく「string」を作成していたため、有効な財産。

ここでやろうとしていることは明確で、どんな質問にも答えられることを願っています。ずさんな半分のコードで作業したことをお詫びします。ボタンはあるが状態を変更できないクラスコンストラクターで作業を開始する前のスニペットを次に示します。

Add-Type -AssemblyName System.Windows.Forms

class App
{
    [string] $Name
    [bool] $Installed
    [string] $Key32
    [string] $Key64
    [string] $Inst_Dir
    [bool] $Current
    [string] $Exec
    [string] $User_Ver
    [string] $Inst_Ver

    App ([string] $Name, [bool] $Installed, [string] $Key32, [string] $Key64, [string] $Inst_Dir, [bool] $Current, [string] $Exec, [string] $User_Ver, [string] $Inst_Ver)
    {
        $this.Name = $Name
        $this.Installed = $Installed
        $this.Key32 = $Key32
        $this.Key64 = $Key64
        $this.Inst_Dir = $Inst_Dir
        $this.current = $Current
        $this.Exec = $Exec
        $this.User_Ver = $User_Ver
        $this.Inst_Ver = $Inst_Ver
    }
}

#region Define and initialize Variables
$HKLM32 = ".\SOFTWARE\Key Location"
$HKLM64 = ".\SOFTWARE\Wow6432Node\Key Location"

# Initialize app classes
[App] $TestApp = [App]::new("TestApp", $false, "$HKLM32\TestApp $TestApp_Ver", "$HKLM64\TestApp $TestApp_Ver", "", $false, "", $TestApp_Ver, "")

$apps = $TestApp

Function create_form()
{
    $Form = New-Object system.Windows.Forms.Form 
    $Form.Text = "Performance Test Auto Setup"
    $Form.TopMost = $true
    $Form.Width = 480
    $Form.Height = 300
    $Form.StartPosition = "CenterScreen"
    $Form.FormBorderStyle = "Fixed3D"
    $Form.MaximizeBox = $false
    $Form.MinimizeBox = $false

    $btnTestAppUninstall = New-Object system.windows.Forms.Button 
    $btnTestAppUninstall.Text = "Uninstall"
    $btnTestAppUninstall.Width = 95
    $btnTestAppUninstall.Height = 22
    $btnTestAppUninstall.location = new-object system.drawing.point(285,9)
    $btnTestAppUninstall.Font = "Microsoft Sans Serif,10"
    $btnTestAppUninstall.Enabled = $false
    $Form.controls.Add($btnTestAppUninstall) 
    $btnTestAppUninstall.Add_Click({uninstallApp($TestApp.Inst_Dir)})

    $btnTest = New-Object system.windows.Forms.Button 
    $btnTest.Text = "test"
    $btnTest.Width = 95
    $btnTest.Height = 22
    $btnTest.location = new-object system.drawing.point(50,9)
    $btnTest.Font = "Microsoft Sans Serif,10"
    $Form.controls.Add($btnTest) 
    $btnTest.Add_Click({updateUI})


    $Form.ShowDialog() | Out-Null
}

Function updateUI()
{
    $apps | ForEach-Object {$app = [string]("$"+"btn$($_.Name)Uninstall")}
    Write-Host  $app.GetType() $btnTestAppUninstall.GetType()
}


create_Form 

を使用して状態を直接調整できることを知っていることも注目に値します

$btnTestAppUninstall.Enabled = $true

また

$btnTestAppUninstalled.Enabled = $false

ただし、この問題を解決しようとしている理由は、フォーム上のすべてのボタンが updateUI 関数全体でこれら 2 つのオプションを複数の場所に配置する必要があり、実際のフォームには 22 個のボタンがあるため、これは最適な解決策ではありません。それはそこで壊れている多くのDRYです。これを機能させることができれば、foreach-object ループを使用してすべてを単純にループし、クラス オブジェクトに格納された値に基づいて状態を設定できます。

私はこれを数日間理解しようとしてきました。

4

1 に答える 1

0

そのため、私は最終的にこの方法を放棄し、古き良き for ループを使用しました。私がしたことは、フォームで有効になっているものに基づいて動的リストを作成し、インデックス番号を使用してリストを同時にループし、適切な値を適切なオブジェクトに配置することでした。

Function updateVersions()
{   
    for($i = 0; $i -lt $apps.Length; $i++)
    {
        If(prop32Bit($apps[$i].Key32) -Not $Null)
        {
            $apps[$i].Inst_Dir = $appDir
            $apps[$i].Exec = (Get-ItemProperty -Path $apps[$i].Key32)."Application Name"
            $apps[$i].Ver = (Get-ItemProperty -Path $apps[$i].Key32).Version
            $apps[$i].Installed = $true
        }
        ElseIf (prop64Bit($apps[$i].Key64) -Not $Null)
        {
            $apps[$i].Inst_Dir = $appDir
            $apps[$i].Exec = (Get-ItemProperty -Path $apps[$i].Key64)."Application Name"
            $apps[$i].Inst_Ver = (Get-ItemProperty -Path $apps[$i].Key64).Version
            $apps[$i].Installed = $true
        }
        Else
        {
            $apps[$i].Inst_Dir = $Null
            $apps[$i].Exec = $Null
            $apps[$i].Inst_Ver = "Not Installed"
            $apps[$i].Installed = $false
        }
    }

    # Update version labels
    For($i = 0; $i -lt $listVerLbls.Length; $i++)
    {
        $listVerLbls[$i].Text = $apps[$i].Inst_Ver        
    }

    # Update uninstall buttons
    For($i = 0; $i -lt $listUninBtns.Length; $i++)
    {
        If($apps[$i].installed)
        {
            $listUninBtns[$i].Enabled = $true
        }
        Else
        {
            $listUninBtns[$i].Enabled = $false
        }
    }

    # Update current buttons
    For($i = 0; $i -lt $listCurBtns.Length; $i++)
    {
        If($apps[$i].installed)
        {
            $listCurBtns[$i].Enabled = $true
            $listCurBtns[$i].BackColor = "DarkRed"
            $listCurBtns[$i].ForeColor = "White"
        }
        Else
        {
            $listCurBtns[$i].Enabled = $false
            $listCurBtns[$i].BackColor = "Control"
            $listCurBtns[$i].ForeColor = "ControlDark"
        }
    }
}

これは、私がやろうとしていたことに対して完全に機能します。

于 2018-02-04T18:30:39.390 に答える