PowerShell未加载从命令行或批处理脚本激发时使用的程序集



如前所述,当从命令行或批处理文件运行时,在Powershell中发现了一个非常奇怪的错误。

PowerShell命令(如Add-Type -AssemblyName(的预期行为是加载指定为该命令参数的程序集,然后我们应该能够将该程序集用于我们运行的下一个命令,即使我们在批处理脚本或命令提示符中执行此过程也是如此。

但当我们在批处理文件或命令提示符中运行时,这是不起作用的:

@echo off && SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
net file 1>NUL 2>NUL
if not '%errorlevel%' == '0' (
pushd "%~dp0" & powershell Start-Process -FilePath "%0" -ArgumentList "%cd%" -verb runas >NUL 2>&1 & popd
exit /b
)
cd /d "%1" && set "ScptDir=%1"
PowerShell "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.Clipboard]::Clear()"
endlocal && exit

@echo off && setlocal
@pushd %~dp0 & fltmc | find "." && (powershell start '%~f0' ' %*' -verb runas 2>nul && exit /b)
whoami
:: PowerShell "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.Clipboard]::Clear()"
type NUL | clip.exe
popd && pause && endlocal && exit

这些并没有清除Windows系统剪贴板,这与任何人的预期相反。也尝试过PowerShell "& {Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.Clipboard]::Clear()}",但没有变化。

对此有任何更改或变通方法使其发挥作用??

  • Windows剪贴板是用户特定的功能。

    • 给定的剪贴板实例绑定到给定用户的OS会话(窗口站,通常是交互式登录用户的桌面(。

    • 在给定用户的操作系统会话中启动的所有本地执行进程共享同一剪贴板,即使这些进程模拟其他用户。(相比之下,明智的是,不同用户的操作系统会话的剪贴板是不同的。(

  • 因此,对于用户给定的操作系统会话,常规进程和提升进程(以管理员身份运行(使用相同的剪贴板。

    • 是否在当前用户帐户的上下文中进行提升取决于该用户是否是具有管理权限的组的成员。如果是,则只显示是/否UAC对话框,如果确认,提升的进程将使用相同的用户标识运行。

    • 但是,如上所述,即使您使用不同的凭据进行提升,生成的过程仍然会看到相同的剪贴板。

  • 设置或清除剪贴板不需要提升。

    • 请注意,使用[System.Windows.Forms.Clipboard]::Clear()和等效方法清除剪贴板不会影响自Windows 10以来可用的选择加入剪贴板历史功能。也就是说,它只清除剪贴板的当前内容,而不清除已存储在历史记录中的以前复制的条目

  • 因此,您的批处理文件应该可以工作,当我尝试它时也可以。

  • 如果您只是想从批处理文件中清除当前用户的剪贴板(无论是否提升(,请使用以下操作(注意:从技术上讲,这不会清除剪贴板,而是将其设置为空字符串(:

    type NUL | clip.exe
    
    • PowerShell[System.Windows.Forms.Clipboard]::Clear()的一个更简单的替代方案是使用Set-Clipboard $null,但请注意,在仅支持将文本复制到剪贴板的PowerShell(Core(7+中,这也与批处理文件中的type NUL | clip.exe一样,将空字符串拷贝到剪贴板,而不是清除它

最新更新