从快捷方式调用PowerShell脚本时使其保持静默



以下快捷方式在SendTo中创建,并调用PowerShell脚本。我希望此脚本是不可见的(-WindowStyle Hidden(,因为该脚本使用Add-Type -AssemblyName System.Windows.Forms; $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{ InitialDirectory = $parent }并根据在OpenFileDialog中选择的项目处理结果。

$oShell = New-Object -ComObject Shell.Application
$lnk = $WScriptShell.CreateShortcut("$Env:AppDataMicrosoftWindowsSendToGet Info.lnk")
$lnk.TargetPath = "%SystemRoot%System32WindowsPowerShellv1.0powershell.exe"
$lnk.Arguments = "-WindowStyle Hidden -NoProfile -File `"C:ScriptsGet Info.ps1`""
$lnk.Save()

但是,该脚本并不是静默的,并在OpenFileDialog之前短暂地弹出一个蓝色PowerShell窗口。当被快捷方式调用时,如何使脚本完全静音?

我所知道的确保这一点的唯一方法是使用vbscript启动.ps1脚本。如下所示:

  • Launcher.vbs

0作为objShell.Run command,0中的参数代表隐藏窗口(并激活另一个窗口(

Set objShell = CreateObject("WScript.Shell")
path = WScript.Arguments(0)
command = "powershell -NoProfile -WindowStyle Hidden -ExecutionPolicy ByPass -File """ & path & """"
objShell.Run command,0
  • myScript.ps1
Add-Type -AssemblyName System.Windows.Forms
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
InitialDirectory = $parent
}
$FileBrowser.ShowDialog()

现在,在快捷方式的目标字段中,您可以使用:

wscript pathtolauncher.vbs pathtomyScript.ps1

你可以在这个网站上阅读更多关于这种方法的信息。

为了扩展Santiago的伟大答案,并以现实世界为例,我的目标是从SendTo中获取一个输入,然后将该输入传递给PowerShell进行额外处理。我不需要在控制台上看到任何东西,所以我想把它隐藏起来。

我希望Beyond Compare能做到这一点,因为我非常喜欢这个应用程序,但我真的不喜欢应用程序用无尽的命令污染我们的右键上下文菜单。我可能每周只使用几次Beyond Compare,所以我不需要它污染我的上下文菜单,因为我每周用鼠标右键点击其他1000多次。我对我所有的工具都这样做,这样我就有了一个非常简洁的右键单击上下文菜单。以下内容也适用于您想要在SendTo中使用自定义工具的几乎任何其他应用程序,如果您喜欢该工具,WinMerge也几乎没有变化(但Beyond Compare也可以比较文件夹,这可能非常有用(。对于WinMerge,如果在第一步选择了一个文件夹,因为它无法处理文件夹,只需中断脚本即可。

由于我需要两个输入,一个来自初始SendTo,另一个来自OpenFileDialog或FolderBrowserDialog,这意味着我还必须将Argument传递给解决方案的VBScript部分。它的语法有点难理解(我已经10多年没有使用VBScript了!(,但它是:

""" & path & """ """ & arg & """"

然后,解决方案需要一个.vbs启动器加上.ps1脚本,最后是shell:sendto中调用脚本的快捷方式:

D: \MyPortableApps\ShortcutLauncher.vbs

Set oShell = CreateObject("WScript.Shell")
path = WScript.Arguments(0)
arg = WScript.Arguments(1)
PSCommand = "powershell -NoProfile -ExecutionPolicy ByPass -File """ & path & """ """ & arg & """"
oShell.run PScommand,0

D: \ MyPortableApps\比较(文件或文件夹,超越比较(.ps1

# Selected item in SendTo is the left side, then use OpenFileDialog or FolderBrowserDialog to pick the right side
$MyPrograms = "D:MyPortableApps"   # Location of my portable apps
$left_side = (Get-Item $args[0]).FullName   # In case path contains '.' or '..'
$parent = Split-Path $left_side   # Use this as InitialDirectory
$IsFolder = $false; if ((Get-Item $left_side) -is [System.IO.DirectoryInfo]) { $IsFolder = $true }
Add-Type -AssemblyName System.Windows.Forms   # Required to access the OpenFileDialog object
if ($IsFolder) {
$FolderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog   # -Property @{ InitialDirectory = $parent }
$FolderBrowser.RootFolder = $parent
$FolderBrowser.Description = "Select Folder to compare to '$left_side':"
$Show = $FolderBrowser.ShowDialog()
if ($Show -eq "OK") {
$right_side = $FolderBrowser.SelectedPath
} else {
break
}
} else {
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{ InitialDirectory = $parent }   # [Environment]::GetFolderPath('Desktop')
$FileBrowser.Title = "Select File to compare to '$left_side':"
$null = $FileBrowser.ShowDialog()   # Assign to null as $FileBrowser does not return useful information by itself
$right_side = $FileBrowser.FileName
}
# $ButtonClicked = [System.Windows.Forms.MessageBox]::Show("Beyond Compare will be opened with the following panes:`n`nLeft side: '$left_side'`n`nRight side: '$right_side'", 'Open Beyond Compare?', 'OKCancel')
$appexe_pf = "C:Program FilesBeyond Compare 4BCompare.exe"
$appexe_sb = "$MyProgramsBeyond Compare 4BCompare.exe"
if ( (!(Test-Path $appexe_sb)) -and (!(Test-Path $appexe_pf))) { choco install beyondcompare -y }
if (Test-Path $appexe_pf) { 
& $appexe_pf "$left_side" "$right_side"
} else {
& $appexe_sb "$left_side" "$right_side"
}

在SendTo中创建快捷方式的代码段

function New-Shortcut ($mylnk, $mytgt, $myarg, $mywrk, $myico) {
$lnk = $WScriptShell.CreateShortcut($mylnk)
$lnk.TargetPath = $mytgt
if ($myarg -ne "") { $lnk.Arguments = $myarg }
if ($mywrk -ne "") { $lnk.WorkingDirectory = $mywrk }
if ($myico -ne "") { $lnk.IconLocation = $myico }
$lnk.Save()
}
$SendTo = "$Env:AppDataMicrosoftWindowsSendTo"
$lnkName = "Compare with (Files or Folders, Beyond Compare)"
$SendToLnk = "$SendTo$lnkName.lnk"
$wscript = "C:Windowssystem32wscript.exe"
New-Shortcut $SendToLnk $wscript "`"D:MyPortableAppsShortcutLauncher.vbs`" `"D:MyPortableApps$lnkName.ps1`"" "" ""

最新更新