Цикл по каждому элементу для создания нескольких ярлыков, которые не работают должным образом - PullRequest
0 голосов
/ 21 мая 2019

Я пытаюсь создать сценарий, который создает несколько ярлыков для исполняемых файлов на рабочем столе.Поскольку код, который отвечает за создание ярлыков, будет использоваться несколько раз, и в других сценариях я решил поместить его в функцию.

Логика довольно проста:

  • Определить функцию
  • Определение целевых файлов ярлыков в отдельных массивах (в моем примере я использую notepad.exe и cmd.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: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.

Ответы [ 3 ]

0 голосов
/ 21 мая 2019

Я согласился с TheMadTechnician, просто добавьте еще одну переменную $ i, чтобы выбрать из массива строк, который вы предоставляете.также можно записать так:

$i=0    
    Foreach ($TargetFile in $TargetFiles) {

        CreateShortcuts -ShortcutPath $ShortcutPaths[$i] -TargetFile $TargetFile
        $i=$i+1

    } 

Я предпочитаю иметь цикл for внутри секции функции, а вы просто передаете строковый массив в функцию.Как то так.

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:SystemRoot\System32\notepad.exe", "$env:SystemRoot\System32\cmd.exe"
$ShortcutPath ="$env:Public\Desktop\Notepad.lnk" ,"$env:Public\Desktop\Command Prompt.lnk"

CreateShortcuts  -TargetFile $TargetFile -ShortcutPath $ShortcutPath
0 голосов
/ 22 мая 2019

Спасибо за вклад всем.Это было полезно и отвязало меня.На следующий день туман у меня рассеялся, и шестерни в моей голове наконец снова начали вращаться.В итоге я использовал хеш-таблицы для этой задачи, чтобы убедиться, что все цели, пути быстрого доступа и значения аргументов быстрого вызова совпадают на основе ключа с одинаковым именем.Я понял, что использование массивов может быть проблематичным, если значения для каждого из вышеперечисленных были проиндексированы не по порядку друг от друга, или для некоторых ярлыков требовались аргументы, а для других - нет.

Ниже приведен обновленный код.Осталось только добавить справочную информацию.

    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
0 голосов
/ 21 мая 2019

Вы делаете свои петли неправильно.То, что вы делаете, это циклический просмотр каждого элемента в $ShortcutPaths, и для каждого из них циклический просмотр каждого элемента в $TargetFiles, поэтому каждый элемент в $ShortcutPaths заканчивается созданным ярлыком, указывающим на последний элемент в $TargetFiles,Вместо этого вы хотите соотнести каждый элемент в каждом массиве с тем же индексированным элементом в другом массиве.Так пункт 1 в $ShortcutPaths с пунктом 1 в $TargetFiles и так далее.Для этого вы используете цикл For следующим образом:

$TargetFiles = "$env:SystemRoot\System32\notepad.exe", "$env:SystemRoot\System32\cmd.exe"
$ShortcutPaths = "$env:Public\Desktop\Notepad.lnk", "$env:Public\Desktop\Command Prompt.lnk"
For($i=0;$i -lt $ShortcutPaths.count;$i++){
    CreateShortcuts -ShortcutPath $ShortcutPaths[$i] -TargetFile $TargetFiles[$i]
}
...