PowerShell 代码在从 PowerShell 命令提示符运行时有效,但在双击运行或转换为可执行文件时无效
Posted
技术标签:
【中文标题】PowerShell 代码在从 PowerShell 命令提示符运行时有效,但在双击运行或转换为可执行文件时无效【英文标题】:The PowerShell code works when run from the PowerShell command prompt but not when run with double-click or turned into an executable 【发布时间】:2021-12-19 02:50:31 【问题描述】:这段代码:
$username = 'Username'
$password = 'Password'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Start-Process -FilePath powershell -WorkingDirectory "$env:ALLUSERSPROFILE" -Credential $credential -WindowStyle Hidden -ArgumentList "-NoProfile -Command `"Start-Process -FilePath wscript -Verb RunAs -ArgumentList '\`"$((Get-Location).Path -replace "'", "''")\test.vbs\`" \`"/CurrentDirectory:$((Get-Location).Path -replace "'", "''")\`" \`"/AppData:$($env:APPDATA -replace "'", "''")\`"'`""
当我从 PowerShell 命令提示符下逐行运行它时可以工作。 当我将 .ps1 扩展名关联到“Windows PowerShell”然后双击脚本时,以及通过 IronMan Software 的“PSScriptPad”在 .exe 中编译脚本时,都会出现问题。 以下链接也存在类似问题:Powershell script executes correctly when I choose "run with powershell", but not when I "open with" powershell or double-click it 但在我的情况下,它甚至不适用于“使用 PowerShell 运行”,而且问题的原因可能与影响可执行文件的原因相同。
另一个有用的链接如下:https://***.com/a/58245206/45375
我该如何解决这个问题? Windows 10 专业版 64 位 Powershell 版本:5.1.19041.1237(集成在 Windows 10 中)。
【问题讨论】:
【参考方案1】:编译的可执行文件不在包含撇号字符的目录中时可以正常工作,而在双击 .ps1 脚本的情况下,包含它的目录甚至不能包含空格。 这是一个有用的链接:https://social.technet.microsoft.com/Forums/en-US/bf3344de-3af6-48e3-9f43-f595bb41c62d/bug-powershell-starts-w-error-when-opened-by-context-menu-in-folder-w-apostrophe-in-its-name?forum=win10itprogeneral
对于 .exe 文件中的撇号路径问题,我向 IronMan Software PSScriptPad 发送了一份错误报告,随后得到了处理。 对于在.ps1脚本上双击或执行“使用PowerShell运行”时出现撇号或连续空格的路径问题,我已通过修复以下注册表值来解决:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.ps1]
@="Microsoft.PowerShellScript.1"
[HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\.\\\"\""
[HKEY_CLASSES_ROOT\Directory\Shell\Powershell\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\.\\\"\""
[HKEY_CLASSES_ROOT\Drive\shell\Powershell\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\.\\\"\""
[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\DefaultIcon]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\",0"
[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -Command \"if((Get-ExecutionPolicy ) -ne 'AllSigned') Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force ; & \\\"%1\\\"\""
[HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\0\Command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -Command \"if((Get-ExecutionPolicy ) -ne 'AllSigned') Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force ; & \\\"%1\\\"\""
[HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\Edit\Command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell_ise.exe\" -File \"%1\""
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell]
"ExecutionPolicy"="RemoteSigned"
【讨论】:
至于双击.ps1
脚本:This answer 包含一个运行一次的编程解决方案,从那时起在保持打开的 PowerShell 窗口中运行 PowerShell 脚本文件,路径带有空格也支持撇号(单引号,'
)。
很好——当然,这比定义双击要全面得多。然而,有一个问题:HKEY_CLASSES_ROOT\Drive\shell\Powershell\command
,大概在其他情况下,至少在我的 Windows 10 20H2 机器上无法写入,因为只有TrustedInstaller
具有写入权限。除此之外,值得指出的是,您需要 elevation(以管理员身份运行)将其写入注册表。而且(我认为这对您来说不是问题)它是一个仅限 Windows PowerShell 的解决方案。为了对未来的读者更加友好,您可以展示如何以编程方式编写文件。
一个小问题(这不是书面的问题,因为Set-Location
调用之后没有任何内容):因为带有尾随 \
的路径(例如C:\
)传递给HKEY_CLASSES_ROOT\Drive\shell\Powershell\command
命令,从技术上讲,您需要转义 尾随\
。从cmd.exe
,比较powershell.exe -Command "write-output -LiteralPath \"C:\\"; get-date"
(损坏)和powershell.exe -Command "write-output -LiteralPath \"C:\\\"; get-date"
(正常)。
也在HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command中,因为“背景”是指在Windows资源管理器窗口的“空白”部分右击,可以轻松打开`带有 GUI 的 C:\` 文件夹,然后在空白区域中单击鼠标右键。谢谢。
我已经解决了这个问题:"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoExit -Command "Set-Location -LiteralPath \"%V/\"; get-date"
,因为也可以接受带有斜杠而不是反斜杠的路径。还要混合斜杠和反斜杠。然后"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoExit -Command "Set-Location -LiteralPath \"C:\/\"; get-date"
路径中还接受多个连续的斜杠和/或连续的反斜杠。和蔼的以上是关于PowerShell 代码在从 PowerShell 命令提示符运行时有效,但在双击运行或转换为可执行文件时无效的主要内容,如果未能解决你的问题,请参考以下文章
我们可以查看 PowerShell cmdlet 的源代码吗?