首页 > 解决方案 > 用于创建多个快捷方式的 Foreach 循环未按预期工作

问题描述

我正在尝试制作一个脚本,为桌面上的可执行文件创建多个快捷方式。因为负责创建快捷方式的代码将被多次使用,并且在其他脚本中我决定将它放入一个函数中。

逻辑非常简单:

我正在尝试使用嵌套的 foreach 循环来遍历目标文件和快捷方式路径数组,但它没有正确生成快捷方式。也许有更好的方法来遍历我没有看到的程序(很有可能,因为我生病了并且脑雾很重)。

该脚本至少可以处理一个快捷方式。

我试过在函数之外运行函数代码。当我从数组中删除命令提示符时,记事本的快捷方式已正确创建。

function CreateShortcuts {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true, Position = 0)]
        [System.String]$ShortcutPath,

        [Parameter(Mandatory = $true, Position = 1)]
        [System.String]$TargetFile,

        [Parameter(Mandatory = $false, Position = 2)]
        [System.String]$ShortcutArgs
    )

    $objShell = New-Object -ComObject WScript.Shell
    $objShortcut = $objShell.CreateShortcut($ShortcutPath)
    $objShortcut.TargetPath = $TargetFile
    $objShortcut.Save()
}

$TargetFiles = "$env:SystemRoot\System32\notepad.exe", "$env:SystemRoot\System32\cmd.exe"
$ShortcutPaths = "$env:Public\Desktop\Notepad.lnk", "$env:Public\Desktop\Command Prompt.lnk"

foreach ($ShortcutPath in $ShortcutPaths) {
    foreach ($TargetFile in $TargetFiles) {
        CreateShortcuts -ShortcutPath $ShortcutPath -TargetFile $TargetFile
    }
}

预期的输出是记事本的快捷方式,命令提示符出现在桌面上并链接到预期的程序。相反,会发生两个快捷方式链接到cmd.exe.

标签: powershellforeachshortcut

解决方案


感谢大家的意见和建议。这很有帮助,让我摆脱了困境。第二天我的脑雾散去,我脑子里的齿轮终于又开始转动了。我最终使用哈希表来完成这项任务,以确保目标、快捷路径和快捷方式参数值都基于同名键匹配。我意识到,如果上述每个值的索引彼此无序,或者某些快捷方式需要参数而其他快捷方式不需要参数,则使用数组可能会出现问题。

以下是更新后的代码。剩下要做的就是添加帮助信息。

    function CreateShortcuts {

    [CmdletBinding()]
    Param(

        [Parameter(Mandatory = $true,
                   Position = 0)]
        [System.Collections.Hashtable]$TargetFiles,

        [Parameter(Mandatory = $true,
                   Position = 1)]
        [System.Collections.Hashtable]$ShortcutPaths,

        [Parameter(Mandatory = $false,
                   Position = 2)]
        [System.Collections.Hashtable]$ShortcutArgs
    )


    $objShell = New-Object -ComObject WScript.Shell

    Foreach ($item in $TargetFiles.Keys) {

        $objShortcut = $objShell.CreateShortcut($ShortcutPaths.Item($item))
        $objShortcut.TargetPath = $TargetFiles.Item($item)
        if ($ShortcutArgs)  {
            $objShortcut.Arguments = $ShortcutArgs.Item($item)
        }
        $objShortcut.Save()
    }
}


$TargetFiles = @{
                    "Notepad" = "$env:SystemRoot\System32\notepad.exe"
                    "CmdPrompt" = "$env:SystemRoot\System32\cmd.exe"
                }

$ShortcutPaths = @{
                      "Notepad" = "$env:Public\Desktop\Notepad.lnk"
                      "CmdPrompt" = "$env:Public\Desktop\Command Prompt.lnk"
                  }

$ShortcutArgs = @{
                     "CmdPrompt" = "/foo -bar"
                     "Notepad" = "/test"
                 }

CreateShortcuts -ShortcutPaths $ShortcutPaths -TargetFiles $TargetFiles -ShortcutArgs $ShortcutArgs

推荐阅读