【问题标题】:How to check if Certain programs are installed and if they are display message如何检查某些程序是否已安装以及是否显示消息
【发布时间】:2021-07-14 09:32:48
【问题描述】:

我正在尝试创建一个脚本来检查程序 A、B、C 和 D 是否已安装。如果是这样,则显示消息说它们都已安装,否则说它们未安装。

根据研究,我创建了以下脚本。


    $ProgramList = @("A","B","C","D")
    
    
     ForEach ($Program in $ProgramList){
     
        Function Get-InstalledApps
        {
        $Regpath = @(
                'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
                'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
            )
        Get-ItemProperty $Regpath | .{Process{If($_.DisplayName) { $_ } }}
        
        }
        
        
      
        $Result = Get-InstalledApps | Where {$_.DisplayName -like "*$Program*"}
    
         
       
        If ($Result) {
            [Windows.Forms.Messagebox]::Show("INSTALLED")
        } Else { 
            [Windows.Forms.Messagebox]::Show("NOT INSTALLED")
        }
        }

我的问题是,当我运行此程序时,我会弹出 4 个消息框,说程序已安装。我正在尝试这样做,所以它只会给出一个消息框。如果全部都安装了,如果一个或多个没有安装,另一个消息框说程序没有安装。

非常感谢任何帮助。

【问题讨论】:

  • 需要注意的是,并非所有应用程序都在这些键下注册自己。如果您在环境中使用已知的应用程序,这应该可以正常工作,您可以在其中进行测试,但不要期望它可以与任何随机的应用程序集一起使用。
  • 感谢您提供的信息。我只会将它用于在这些键下找到的一组定义的应用程序。我已经测试过了,我需要的所有应用都在这里。

标签: powershell


【解决方案1】:

您收到四个弹出窗口,因为您调用了 msgbox 四次(因为它在您的循环中)。仅将其移出并不能完全解决您的问题,因为它只会查看最后一个问题,但是如果您需要按自己的方式进行操作,则可以使用以下方法:

$ProgramList = @("A","B","C","D")

$allInstalled = $true # Assume they're all installed
    
ForEach ($Program in $ProgramList){
     
    Function Get-InstalledApps {
        $Regpath = @(
                'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
                'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
            )
        Get-ItemProperty $Regpath | .{Process{If($_.DisplayName) { $_ } }}
        
    }
      
    If(-not(Get-InstalledApps | Where {$_.DisplayName -like "*$Program*"})) {
        # We know at least one isn't installed
        $allInstalled = $false
    }

}

If($allInstalled) {
    [Windows.Forms.Messagebox]::Show("INSTALLED")
} Else { 
    [Windows.Forms.Messagebox]::Show("NOT INSTALLED")
}

如果您能够稍微调整一下该功能,您可以通过只提取一次注册表信息来加快它的速度。当您使用多个应用程序调用该函数时,此处的 BEGIN 部​​分只运行一次。

Function Test-InstalledApps {

    Param(
        [Parameter(ValueFromPipeline)]
        [string[]]$appName
    )

    Begin {
        $Regpath = @('HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*','HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*')
        $allApps = Get-ItemProperty $Regpath | Select DisplayName 
        $allAppsInstalled = $true
    }

    Process {
        ForEach($app in $appName) {
            If(-Not($allApps | Where-Object { $_.DisplayName -like "*$app*" })) {
                # We know at least one isn't installed
                $allAppsInstalled = $false
            }
        }
    }

    End {
        Return $allAppsInstalled
    }
    
}

If(Test-InstalledApps @("A","B","C")) {
    [Windows.Forms.Messagebox]::Show("INSTALLED")
} Else { 
    [Windows.Forms.Messagebox]::Show("NOT INSTALLED")
}

【讨论】:

  • 谢谢你,克里斯,这很好用。使用您调整过的函数版本可以更快地运行。我已经实现了这个,它现在完全按照我的需要做。非常感谢。
【解决方案2】:

我认为这可能是更好的方法,使用Out-GridView。在我看来,这看起来会更干净,我知道这并不能回答您的问题,但它可能更适合您:

$programList = @(
    'SomeRandomProgram1'
    'Microsoft Visual'
    '7-Zip'
    'SomeRandomProgram2'
)

$Regpath = @(
    'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
    'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)

$installedPrograms = (Get-ItemProperty $Regpath).where({$_.DisplayName})
$result = foreach($program in $programList)
{
    $check = $installedPrograms.DisplayName -match $program
    if($check)
    {
        foreach($match in $check)
        {
            [pscustomobject]@{
                Program = $program
                Status = 'Found'
                Match = $match
            }
        }
        continue
    }

    [pscustomobject]@{
        Program = $program
        Status = 'Not Found'
        Match = $null
    }
}

$result | Out-GridView

在我的电脑中,OGV 是这样的:

【讨论】:

  • 在这个用例中,我只想弹出一个消息框来说明它们是否已安装。感谢您突出显示 Out-GridView。这将有助于我正在编写的另一个函数。
【解决方案3】:

我知道我在这里玩游戏有点晚了,我的回答是你可能会说完全不同的购买我这样做是为了学习一些东西并认为其他人可能会觉得它很有趣。它会产生这样的输出。

有趣的部分是菜单可以自我调整,在屏幕大小限制内,因此您可以通过将它们传递到数组中来搜索更多或更少的程序。该程序搜索目录与注册表,因此您可以找到未安装的程序(便携式)。默认情况下,它会搜索两个 Windows 位置,但您也可以将一个包含其他搜索位置的数组传递给它。

我敢肯定,它不需要太多修改就可以让它搜索注册表项。

如果您有兴趣,可以下载一个 zip 文件(需要包含我的OneDrive here. 的复选标记和红色 x 的图形文件

【讨论】:

    猜你喜欢
    • 2016-05-02
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    相关资源
    最近更新 更多