我正在尝试创建一个脚本来创建桌面上可执行文件的多个快捷方式。因为负责创建快捷方式的代码将被多次使用,所以在其他脚本中,我决定将其放入一个函数中。
逻辑非常简单:
在不同的数组中定义快捷方式的function
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
的快捷方式。
发布于 2019-05-22 14:23:57
感谢大家的投入。这对我很有帮助,让我解脱了。第二天,我的脑海中的迷雾消失了,我头脑中的齿轮终于又开始转动了。我最终为此任务使用了哈希表,以确保目标、快捷方式路径和快捷方式参数值都基于相同名称的键进行匹配。我意识到,如果上面每个值的索引顺序都打乱了,或者一些快捷方式需要参数,而另一些则不需要,那么使用数组可能会有问题。
下面是更新后的代码。剩下的唯一要做的就是添加帮助信息。
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
发布于 2019-05-21 08:03:33
你的循环做错了。您所做的是循环遍历$ShortcutPaths
中的每一项,并且对于其中的每一项循环遍历$TargetFiles
中的每一项,因此$ShortcutPaths
中的每一项都以创建的指向$TargetFiles
中的最后一项的快捷方式结束。相反,您要做的是将每个数组中的每个项与另一个数组中相同的索引项相关联。因此,$ShortcutPaths
中的项目1和$TargetFiles
中的项目1,依此类推。要做到这一点,您可以使用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]
}
发布于 2019-05-21 10:37:03
我同意TheMadTechnician的观点,只需添加另一个变量$i以从您提供的字符串数组中进行选择。也可以这样写:
$i=0
Foreach ($TargetFile in $TargetFiles) {
CreateShortcuts -ShortcutPath $ShortcutPaths[$i] -TargetFile $TargetFile
$i=$i+1
}
我更喜欢在function部分中使用这个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
https://stackoverflow.com/questions/56229412
复制相似问题