foreach循环创建多个无法正常工作的快捷方式



我正在尝试制作一个脚本,该脚本会在桌面上创建多个快捷方式。因为负责创建快捷方式的代码将多次使用,在其他脚本中,我决定将其放入函数中。

逻辑非常简单:

  • 定义功能
  • 在单独的数组中定义快捷方式的目标文件(我的示例中我正在使用notepad.execmd.exe(
  • 定义捷径的预期路径

我试图使用嵌套的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:SystemRootSystem32notepad.exe", "$env:SystemRootSystem32cmd.exe"
$ShortcutPaths = "$env:PublicDesktopNotepad.lnk", "$env:PublicDesktopCommand Prompt.lnk"
foreach ($ShortcutPath in $ShortcutPaths) {
    foreach ($TargetFile in $TargetFiles) {
        CreateShortcuts -ShortcutPath $ShortcutPath -TargetFile $TargetFile
    }
}

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

您的循环错误。您正在做的是通过$ShortcutPaths中的每个项目,对于通过$TargetFiles中的每个项目循环的每个项目,因此$ShortcutPaths中的每个项目最终都以快捷方式指向$TargetFiles中的最后一项。您想做的是将每个数组中的每个项目与另一个数组中相同的索引项目相关联。因此,$ShortcutPaths中的项目1在$TargetFiles中使用项目1,依此类推。为此,您使用For循环:

$TargetFiles = "$env:SystemRootSystem32notepad.exe", "$env:SystemRootSystem32cmd.exe"
$ShortcutPaths = "$env:PublicDesktopNotepad.lnk", "$env:PublicDesktopCommand Prompt.lnk"
For($i=0;$i -lt $ShortcutPaths.count;$i++){
    CreateShortcuts -ShortcutPath $ShortcutPaths[$i] -TargetFile $TargetFiles[$i]
}

我同意themadtechnician的同意,只需添加另一个变量$ i即可从您提供的字符串数组中选择。也可以像这样写:

$i=0    
    Foreach ($TargetFile in $TargetFiles) {
        CreateShortcuts -ShortcutPath $ShortcutPaths[$i] -TargetFile $TargetFile
        $i=$i+1
    } 

我更喜欢在功能部分内的循环,只需将字符串数组传递给该函数即可。这样的东西。

function CreateShortcuts {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true, Position = 0)]
        [system.String[]]$TargetFile,
        [Parameter(Mandatory = $true, Position = 1)]
        [system.String[]]$ShortcutPath,
        [Parameter(Mandatory = $false, Position = 2)]
        [System.String]$ShortcutArgs
    )
        $i=0
        Foreach ($object in $TargetFile) {
            $objShell = New-Object -ComObject WScript.Shell
            $objShortcut = $objShell.CreateShortcut($ShortcutPath[$i])
            $objShortcut.TargetPath = $object
            $objShortcut.Save()
            $i=$i+1
            }
}

$TargetFile = "$env:SystemRootSystem32notepad.exe", "$env:SystemRootSystem32cmd.exe"
$ShortcutPath ="$env:PublicDesktopNotepad.lnk" ,"$env:PublicDesktopCommand Prompt.lnk"
CreateShortcuts  -TargetFile $TargetFile -ShortcutPath $ShortcutPath

感谢所有人的输入。这很有帮助,让我解开了。我的大脑雾清除了第二天,我脑海中的齿轮终于再次开始转动。我最终使用Hashtables执行此任务,以确保目标,快捷路径和快捷参数值所有基于同名的键都匹配。我意识到,如果将上述每个数组的值彼此索引,或者需要一些捷径,而其他参数则没有。

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

    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:SystemRootSystem32notepad.exe"
                    "CmdPrompt" = "$env:SystemRootSystem32cmd.exe"
                }
$ShortcutPaths = @{
                      "Notepad" = "$env:PublicDesktopNotepad.lnk"
                      "CmdPrompt" = "$env:PublicDesktopCommand Prompt.lnk"
                  }
$ShortcutArgs = @{
                     "CmdPrompt" = "/foo -bar"
                     "Notepad" = "/test"
                 }
CreateShortcuts -ShortcutPaths $ShortcutPaths -TargetFiles $TargetFiles -ShortcutArgs $ShortcutArgs

最新更新