当前位置: 首页 > 知识库问答 >
问题:

如何使@'...'@在powershell.exe命令"中工作?

钱言
2023-03-14

这是一个PowerShell脚本,用于刷新Internet代理设置,我从批处理文件中获取该脚本,以禁用Internet选项代理服务器。

function Refresh-System {
    $signature = @'
[DllImport("wininet.dll", SetLastError = true, CharSet=CharSet.Auto)]
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
'@

    $INTERNET_OPTION_SETTINGS_CHANGED   = 39
    $INTERNET_OPTION_REFRESH            = 37
    $type = Add-Type -MemberDefinition $signature -Name wininet -Namespace pinvoke -PassThru
    $a = $type::InternetSetOption(0, $INTERNET_OPTION_SETTINGS_CHANGED, 0, 0)
    $b = $type::InternetSetOption(0, $INTERNET_OPTION_REFRESH, 0, 0)
    return $a -and $b
}
Refresh-System

我想在批处理文件或命令提示符中作为单个命令运行它,例如

powershell.exe -Command "stmnt1; stmnt2; ..."

这是我从如何压缩PowerShell脚本以适合一行中学到的。

我试图将它完全合并成一行并执行它。

powershell -command "$signature = @'[DllImport("wininet.dll", SetLastError = true, CharSet=CharSet.Auto)] public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength)'@; $INTERNET_OPTION_SETTINGS_CHANGED   = 39; $INTERNET_OPTION_REFRESH            = 37; $type = Add-Type -MemberDefinition $signature -Name wininet -Namespace pinvoke -PassThru; $a = $type::InternetSetOption(0, $INTERNET_OPTION_SETTINGS_CHANGED, 0, 0); $b = $type::InternetSetOption(0, $INTERNET_OPTION_REFRESH, 0, 0);"

但它返回给我一个错误。

At line:1 char:16
+ $signature = @'[DllImport(wininet.dll, SetLastError = true, CharSet=C ...
+                ~
No characters are allowed after a here-string header but before the end
of the line.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedCharactersAfterHereStringHeader

我该怎么解决呢?有没有更好的方法来浓缩上述函数?

共有1个答案

楚流觞
2023-03-14

@变量周围的$signature字符被称为Here字符串,明确用于可能包含新行的文本块。

签名定义只是C#代码,特定的代码片段实际上不需要包含换行符才能正常工作。因此,我们可以将其声明为常规字符串

$signature = '[DllImport("wininet.dll", SetLastError = true, CharSet=CharSet.Auto)] public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);'

但是,您还必须处理转义嵌入的双引号的问题,根据此答案的“从cmd.exe或类似POSIX的shell调用PowerShell的CLI”部分,这意味着您应该用“^”

PowerShell代码必须嵌入到批处理文件中,而不是在批处理文件引用的旁边嵌入它自己的. ps1文件中,这有什么特殊的原因吗?因为如果您可以管理它,这是最简单的麻烦。

您的另一个选择是使用PowerShell的功能通过-Encodedader参数运行Base64编码的脚本,而不是必须使用一行'ify和转义PowerShell代码。假设您已经有了刷新-System.ps1脚本,您可以执行类似的操作来生成批处理文件。

$scriptText = Get-Content .\Refresh-System.ps1 -Raw
$scriptB64 = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($scriptText))
"powershell.exe -EncodedCommand `"$scriptB64`"" | Out-File refresh-system.cmd -Encoding ascii
 类似资料:
  • 问题内容: 我想确切地知道“ Is”命令在Linux和Unix中如何工作。 据我所知,ls将&s派生到Linux / Unix shell,然后获取(当前文件树的输出。例如/ home / ankit /)。我需要更详细的说明,因为我不确定调用fork之后会发生什么。 任何人都可以详细解释“ ls”命令的功能吗? 问题答案: ls不分叉。Shell会分叉并执行,以便运行任何未内置的命令,它可以运行

  • 正如独立jar的文档所述,我试图为我的特性提供参数,但不知道如何使其工作。我错过了什么? 我的命令行: 空手道配置。js TestArgs。功能:测试参数 我没有得到任何打印:java-jarc:\karate\karate-0.9。1.jar-a myKey1=myValue1 TestArgs。特色 10:32:57.904[主]信息网。凭直觉。空手道。内蒂。主要-空手道版本:0.9。1. 1

  • 本文向大家介绍如何在Linux中使用diff命令,包括了如何在Linux中使用diff命令的使用技巧和注意事项,需要的朋友参考一下 diff命令逐行分析并显示两个文件之间的更改列表。作为一种特殊情况,diff将标准输入的副本与其自身进行比较。本文介绍“如何在Linux中使用diff命令。 “ diff”命令的期货– 识别一个文件版本之间的更改 比较两个配置或程序文件 创建一个可以与Linux /

  • 我第一次在git上工作。我已经将我的分支推到github上,它将所有库和文档推到github上。现在我可以做什么,如何使用gitignore命令来避免再次出现同样的错误。

  • 我想用python将网站上的文本保存为变量。 我不知道该怎么做才对。谢谢

  • 问题内容: 将消息发布到特定频道。 我使用另一个Redis客户端订阅了该频道。 在Redis客户端中,我收到了所有已发布消息。现在,我要取消订阅频道。但是我无法在Redis客户端中输入退订。当我使用Ctrl + c时,完整的Redis客户端退出。如何在Redis Client中编写退订命令? 问题答案: 我不认为您可以在客户端中取消订阅,因为客户端被阻止了。我写了一个ruby脚本来展示如何使用退订