【问题标题】:Run a long Powershell command as parameter when executing a BATCH file [duplicate]执行 BATCH 文件时运行长 Powershell 命令作为参数 [重复]
【发布时间】:2018-07-02 08:18:13
【问题描述】:

我想通过执行 .bat 文件来运行以下 Powershell 命令:

Add-Type -TypeDefinition @'
using System.Runtime.InteropServices;
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume
{
    // f(), g(), ... are unused COM method slots. Define these if you care
    int f(); int g(); int h(); int i();
    int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext);
    int j();
    int GetMasterVolumeLevelScalar(out float pfLevel);
    int k(); int l(); int m(); int n();
    int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext);
    int GetMute(out bool pbMute);
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDevice
{
    int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev);
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDeviceEnumerator
{
    int f(); // Unused
    int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { }
public class Audio
{
    static IAudioEndpointVolume Vol()
    {
        var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
        IMMDevice dev = null;
        Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev));
        IAudioEndpointVolume epv = null;
        var epvid = typeof(IAudioEndpointVolume).GUID;
        Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv));
        return epv;
    }
    public static float Volume
    {
        get { float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v; }
        set { Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty)); }
    }
    public static bool Mute
    {
        get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; }
        set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); }
    }
}
'@
[audio]::Volume  = 1

cmd 命令提示符的问题在于它将新的代码行解释为执行此命令

但是,当我在 PowerShell 命令行中输入所有内容时,它并没有这样做。

是否有可能通过执行批处理脚本来运行整个 PowerShell 脚本?

我已经尝试过powershell -command "and the whole script",但这也不起作用...cmd 一直在想换行意味着执行它。

【问题讨论】:

  • 这不起作用,我收到一条错误消息,说在“here-string-header”之后或在行尾之后不允许设置字符

标签: powershell batch-file command-line cmd


【解决方案1】:

如果你想执行你的 PS1 文件,试试这个:

powershell.exe -executionpolicy bypass -file "YOUR_FILE_NAME.ps1"

如果您想在一个批处理文件中执行所有操作,请执行以下操作:

powershell.exe
"Your Command"

你只需要把你的命令放到下一行。

【讨论】:

  • 好的,但是 ps1 文件必须包含什么?它是一个脚本,对吧?所以我真的需要一个全新的命令。
  • 我编辑了我的答案
  • 那行不通。我的命令不仅仅是一行。如果我执行 powershell.exe “我的整个命令有几行”,它只会忽略 powershell.exe 之后的所有内容
【解决方案2】:

首先,如果你的 PowerShell 命令很长,每个cmd 命令行的最大字符数可以轻松达到(我相信是~8191 characters?)。

此外,直接在cmd 命令行中执行如此大的 PowerShell 命令是很不常见的。通常你应该把它放在一个以.ps1结尾的文件中,然后你使用下面的命令来执行它:

powershell.exe -executionpolicy bypass -file script.ps1

如果您确实需要运行您提到的 PowerShell 命令,您必须先对其进行一些修改。以下面的 PS 脚本为例:

function Say-Hello
{
   [CmdletBinding()]
   Param
   (
       [string] $name
   )
   Process
   {
        # Let's say hello!
        $str = "Hello " + $name
        Write-Output $str
   }
}
Say-Hello "Jason"


诀窍是使用文本编辑器(例如 Notepad++)将所有 \r\n 行结尾替换为 \n


但是,您必须首先在许多 PowerShell 命令的末尾添加一些 ;,因为这是您可以告诉 PowerShell 正在发出新的 PowerShell 命令的唯一方法。否则,PowerShell 可能会占用您的 2 行代码并将它们作为单个代码执行,因为在您删除换行符后它们看起来都是串联的。

然后从您的代码中删除所有行 cmets,并转义所有双引号(或者,只需将它们替换为单引号):

function Say-Hello
{
   [CmdletBinding()]
   Param
   (
       [string] $name
   )
   Process
   {
        $str = 'Hello ' + $name;
        Write-Output $str
   }
}
Say-Hello 'Jason'


现在您可以从文本编辑器工具(在我的例子中为 Notepad++)复制它并将其粘贴到您的命令行,如下所示:

powershell.exe -executionpolicy bypass -command "function Say-Hello { [CmdletBinding()] Param ([string] $name) Process { $str = 'Hello ' + $name; Write-Output $str }} Say-Hello 'Jason'"

而预期的输出是:

你好杰森

【讨论】:

  • “在cmd 命令行中直接执行如此大的PowerShell命令是相当罕见的”。我一直使用嵌入在批处理文件中的大量 PowerShell 代码。您可以在this thread 上查看执行此操作的一般方法,其中有很多示例,例如Tetris gameSpiral in color2048 game 等等……
  • @Aacini:感谢您提供的信息,我不知道在 PowerShell + 批处理文件中开发游戏如此普遍。
猜你喜欢
  • 2019-09-27
  • 2021-10-29
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
相关资源
最近更新 更多