如何在 PowerShell 中运行带有空格和引号的参数的 EXE 文件

发布于 2024-08-09 21:17:47 字数 334 浏览 4 评论 0原文

如何在 PowerShell 中运行以下命令?

C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="数据源=mysource;集成安全性=false;用户 ID=sa;密码=sapass!;数据库=数据库;” -dest:dbfullsql="数据源=.\mydestsource;集成安全性=false;用户ID=sa;Pwd=sapass!;数据库=mydb;",计算机名=10.10.10.10,用户名=管理员,密码=adminpass"

How do you run the following command in PowerShell?

C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(22

朕就是辣么酷 2024-08-16 21:17:47

当 PowerShell 看到以字符串开头的命令时,它只会评估该字符串,也就是说,它通常会将其回显到屏幕上,例如:

PS> "Hello World"
Hello World

如果您希望 PowerShell 将该字符串解释为命令名称,则使用调用运算符 (&)像这样:

PS> & 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe'

之后,您可能只需要引用包含空格和/或引号字符的参数/参数对。当您使用复杂的命令行参数调用这样的 EXE 文件时,拥有一个能够向您展示 PowerShell 如何将参数发送到 EXE 文件的工具通常会非常有帮助。 PowerShell 社区扩展就有这样的工具。它被称为回波。您只需用 echoargs 替换 EXE 文件 - 将所有参数保留在适当的位置,它会向您显示 EXE 文件将如何接收参数,例如:

PS> echoargs -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass

Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data>
Arg 2 is <Source=mysource;Integrated>
Arg 3 is <Security=false;User>
Arg 4 is <ID=sa;Pwd=sapass!;Database=mydb;>
Arg 5 is <-dest:dbfullsql=Data>
Arg 6 is <Source=.\mydestsource;Integrated>
Arg 7 is <Security=false;User>
Arg 8 is <ID=sa;Pwd=sapass!;Database=mydb; computername=10.10.10.10 username=administrator password=adminpass>

使用 echoargs 您可以进行实验,直到得到正确的结果,例如:

PS> echoargs -verb:sync "-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;"
Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;>

事实证明我之前太努力地维护连接字符串周围的双引号了。显然这是没有必要的,因为即使 cmd.exe 也会将它们删除。

顺便说一句,向 PowerShell 团队致敬。他们非常有帮助地向我展示了 single & 的具体咒语。双引号以获得所需的结果 - 如果您需要保留内部双引号。 :-) 他们也意识到这是一个痛苦的领域,但他们是受到受特定问题影响的人数所驱动的。如果这对您来说是一个痛苦的领域,那么请投票支持这个 PowerShell bug提交

有关 PowerShell 如何解析的更多信息,请查看我的 有效的 PowerShell 博客系列 - 特别是 第 10 项 - “了解 PowerShell 解析模式”

2012 年 4 月 4 日更新:这种情况在 PowerShell V3 中更容易处理。请参阅此博客文章了解详情

When PowerShell sees a command starting with a string it just evaluates the string, that is, it typically echos it to the screen, for example:

PS> "Hello World"
Hello World

If you want PowerShell to interpret the string as a command name then use the call operator (&) like so:

PS> & 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe'

After that you probably only need to quote parameter/argument pairs that contain spaces and/or quotation chars. When you invoke an EXE file like this with complex command line arguments it is usually very helpful to have a tool that will show you how PowerShell sends the arguments to the EXE file. The PowerShell Community Extensions has such a tool. It is called echoargs. You just replace the EXE file with echoargs - leaving all the arguments in place, and it will show you how the EXE file will receive the arguments, for example:

PS> echoargs -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass

Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data>
Arg 2 is <Source=mysource;Integrated>
Arg 3 is <Security=false;User>
Arg 4 is <ID=sa;Pwd=sapass!;Database=mydb;>
Arg 5 is <-dest:dbfullsql=Data>
Arg 6 is <Source=.\mydestsource;Integrated>
Arg 7 is <Security=false;User>
Arg 8 is <ID=sa;Pwd=sapass!;Database=mydb; computername=10.10.10.10 username=administrator password=adminpass>

Using echoargs you can experiment until you get it right, for example:

PS> echoargs -verb:sync "-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;"
Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;>

It turns out I was trying too hard before to maintain the double quotes around the connection string. Apparently that isn't necessary because even cmd.exe will strip those out.

BTW, hats off to the PowerShell team. They were quite helpful in showing me the specific incantation of single & double quotes to get the desired result - if you needed to keep the internal double quotes in place. :-) They also realize this is an area of pain, but they are driven by the number of folks are affected by a particular issue. If this is an area of pain for you, then please vote up this PowerShell bug submission.

For more information on how PowerShell parses, check out my Effective PowerShell blog series - specifically item 10 - "Understanding PowerShell Parsing Modes"

UPDATE 4/4/2012: This situation gets much easier to handle in PowerShell V3. See this blog post for details.

旧瑾黎汐 2024-08-16 21:17:47

我在命令和参数中都有空格,这对我有用:

$Command = "E:\X64\Xendesktop Setup\XenDesktopServerSetup.exe"
$Parms = "/COMPONENTS CONTROLLER,DESKTOPSTUDIO,DESKTOPDIRECTOR,LICENSESERVER,STOREFRONT /PASSIVE /NOREBOOT /CONFIGURE_FIREWALL /NOSQL"

$Parms = $Parms.Split(" ")
& "$Command" $Parms

它与 Akira 的答案 基本相同,但这有效如果您动态构建命令参数并将它们放入变量中。

I had spaces in both command and parameters, and this is what worked for me:

$Command = "E:\X64\Xendesktop Setup\XenDesktopServerSetup.exe"
$Parms = "/COMPONENTS CONTROLLER,DESKTOPSTUDIO,DESKTOPDIRECTOR,LICENSESERVER,STOREFRONT /PASSIVE /NOREBOOT /CONFIGURE_FIREWALL /NOSQL"

$Parms = $Parms.Split(" ")
& "$Command" $Parms

It's basically the same as Akira's answer, but this works if you dynamically build your command parameters and put them in a variable.

夏末 2024-08-16 21:17:47

只需在 .exe 名称前添加 & 运算符即可。
以下是在静默模式下安装 SQL Server Express 的命令:

$fileExe = "T:\SQLEXPRADV_x64_ENU.exe"
$CONFIGURATIONFILE = "T:\ConfSetupSql2008Express.ini"

& $fileExe  /CONFIGURATIONFILE=$CONFIGURATIONFILE

Just add the & operator before the .exe name.
Here is a command to install SQL Server Express in silence mode:

$fileExe = "T:\SQLEXPRADV_x64_ENU.exe"
$CONFIGURATIONFILE = "T:\ConfSetupSql2008Express.ini"

& $fileExe  /CONFIGURATIONFILE=$CONFIGURATIONFILE
蓝眼睛不忧郁 2024-08-16 21:17:47

您可以使用多种方法来做到这一点。

还有其他方法,例如使用 Call Operator (&)、Invoke-Expression cmdlet 等。但它们被认为是不安全的。 Microsoft 建议使用Start-Process

方法 1

一个简单的示例

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root","-proot","-h localhost"

在您的情况中

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync","-source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","-dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","computername=10.10.10.10","username=administrator","password=adminpass"

在此方法中,您使用逗号分隔 ArgumentList 中的每个参数。

方法 2

简单示例

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root -proot -h localhost"

在您的情况下

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`" -dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`",computername=10.10.10.10,username=administrator,password=adminpass"

此方法更简单,因为它允许一次性输入参数。

请注意,在 powershell 中,要表示字符串中的引号 ("),您应该插入重音符号 (`)(这是 Tab 键上方的键)在美国键盘中)。

-NoNewWindow
参数用于在当前控制台窗口中显示新进程。默认情况下,Windows PowerShell 打开一个新窗口。

参考文献:Powershell/脚本/启动进程

There are quite a few methods you can use to do it.

There are other methods like using the Call Operator (&), Invoke-Expression cmdlet etc. But they are considered unsafe. Microsoft recommends using Start-Process.

Method 1

A simple example

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root","-proot","-h localhost"

In your case

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync","-source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","-dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","computername=10.10.10.10","username=administrator","password=adminpass"

In this method you separate each and every parameter in the ArgumentList using commas.

Method 2

Simple Example

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root -proot -h localhost"

In your case

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`" -dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`",computername=10.10.10.10,username=administrator,password=adminpass"

This method is easier as it allows to type your parameters in one go.

Note that in powershell to represent the quotation mark ( " ) in a string you should insert the grave accent ( ` ) (This is the key above the Tab key in the US keyboard).

-NoNewWindow
parameter is used to display the new process in the current console window. By default Windows PowerShell opens a new window.

References : Powershell/Scripting/Start-Process

调妓 2024-08-16 21:17:47

这对我有用:

& 'D:\Server\PSTools\PsExec.exe' @('\\1.1.1.1', '-accepteula', '-d', '-i', $id, '-h', '-u', 'domain\user', '-p', 'password', '-w', 'C:\path\to\the\app', 'java', '-jar', 'app.jar')

只需将路径或连接字符串放入一个数组项中,然后将其他内容分别放入一个数组项中。

这里还有很多其他选项:https: //social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

Microsoft 应该使这种方式更简单并与命令提示符语法兼容。

This worked for me:

& 'D:\Server\PSTools\PsExec.exe' @('\\1.1.1.1', '-accepteula', '-d', '-i', $id, '-h', '-u', 'domain\user', '-p', 'password', '-w', 'C:\path\to\the\app', 'java', '-jar', 'app.jar')

Just put paths or connection strings in one array item and split the other things in one array item each.

There are a lot of other options here: https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

Microsoft should make this way simpler and compatible with command prompt syntax.

近箐 2024-08-16 21:17:47

如果有人想知道如何运行可执行文件:

.....> .\file.exe

......> file.exe 的完整路径

In case somebody is wondering how to just run an executable file:

..... > .\file.exe

or

......> full\path\to\file.exe

清风无影 2024-08-16 21:17:47

请参阅此页面:
https://slai.github.io/posts/powershell- and-external-commands-done-right/

使用 vshadow 作为外部可执行文件的摘要:

$exe = "H:\backup\scripts\vshadow.exe"
&$exe -p -script=H:\backup\scripts\vss.cmd E: M: P:

See this page:
https://slai.github.io/posts/powershell-and-external-commands-done-right/

Summary using vshadow as the external executable:

$exe = "H:\backup\scripts\vshadow.exe"
&$exe -p -script=H:\backup\scripts\vss.cmd E: M: P:
走走停停 2024-08-16 21:17:47

您可以使用:

Start-Process -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

根据帮助指南,这里要注意的关键是 FilePath 必须位于位置 0。要调用命令行开关的帮助指南,只需键入 Get-Help; -详细。在本例中,它是 Get-Help Start-Process -Detailed

You can use:

Start-Process -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

The key thing to note here is that FilePath must be in position 0, according to the Help Guide. To invoke the Help guide for a commandlet, just type in Get-Help <Commandlet-name> -Detailed . In this case, it is Get-Help Start-Process -Detailed.

虫児飞 2024-08-16 21:17:47

我能够使用以下方法让我的类似命令工作:

msdeploy.exe -verb=sync "-source=dbFullSql=Server=THESERVER;Database=myDB;UID=sa;Pwd=saPwd" -dest=dbFullSql=c:\temp\test.sql

对于您的命令(现在没有多大帮助),事情看起来像这样:

msdeploy.exe -verb=sync "-source=dbfullsql=Server=mysource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;" "-dest=dbfullsql=Server=mydestsource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass

关键点是:

  • 在源参数周围使用引号,并删除嵌入的引号连接字符串周围
  • 在构建其中不包含空格的 SQL 连接字符串时使用备用键名称。例如,使用“UID”代替“用户 ID”、“服务器”代替“数据源”、“Trusted_Connection”代替“集成安全性”等等。只有从连接字符串中删除所有空格后,我才能使其正常工作。

我没有尝试在命令行末尾添加“计算机名”部分,但希望此信息将帮助其他人现在阅读此内容更接近他们想要的结果。

I was able to get my similar command working using the following approach:

msdeploy.exe -verb=sync "-source=dbFullSql=Server=THESERVER;Database=myDB;UID=sa;Pwd=saPwd" -dest=dbFullSql=c:\temp\test.sql

For your command (not that it helps much now), things would look something like this:

msdeploy.exe -verb=sync "-source=dbfullsql=Server=mysource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;" "-dest=dbfullsql=Server=mydestsource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass

The key points are:

  • Use quotes around the source argument, and remove the embedded quotes around the connection string
  • Use the alternative key names in building the SQL connection string that don't have spaces in them. For example, use "UID" instead of "User Id", "Server" instead of "Data Source", "Trusted_Connection" instead of "Integrated Security", and so forth. I was only able to get it to work once I removed all spaces from the connection string.

I didn't try adding the "computername" part at the end of the command line, but hopefully this info will help others reading this now get closer to their desired result.

穿透光 2024-08-16 21:17:47

PowerShell V3 中的新转义字符串,引用自 新的 V3 语言功能

更轻松地重用 Cmd.exe 中的命令行

Web 上充满了为 Cmd.exe 编写的命令行。这些命令行在 PowerShell 中经常工作,但是当它们包含某些字符时,例如分号 (;)、美元符号 ($) 或大括号,您必须进行一些更改,可能添加一些引号。这似乎是许多小问题的根源。

为了帮助解决这种情况,我们添加了一种“转义”命令行解析的新方法。如果您使用神奇参数 --%,我们将停止对命令行的正常解析并切换到更简单的参数。我们不匹配引号。我们不会停在分号处。我们不扩展 PowerShell 变量。如果您使用 Cmd.exe 语法(例如 %TEMP%),我们会扩展环境变量。除此之外,直到行尾(或管道,如果您使用管道)的参数都按原样传递。这是一个例子:

PS> echoargs.exe --% %USERNAME%,this=$something{weird}
Arg 0 is <jason,this=$something{weird}>

New escape string in PowerShell V3, quoted from New V3 Language Features:

Easier Reuse of Command Lines From Cmd.exe

The web is full of command lines written for Cmd.exe. These commands lines work often enough in PowerShell, but when they include certain characters, for example, a semicolon (;), a dollar sign ($), or curly braces, you have to make some changes, probably adding some quotes. This seemed to be the source of many minor headaches.

To help address this scenario, we added a new way to “escape” the parsing of command lines. If you use a magic parameter --%, we stop our normal parsing of your command line and switch to something much simpler. We don’t match quotes. We don’t stop at semicolon. We don’t expand PowerShell variables. We do expand environment variables if you use Cmd.exe syntax (e.g. %TEMP%). Other than that, the arguments up to the end of the line (or pipe, if you are piping) are passed as is. Here is an example:

PS> echoargs.exe --% %USERNAME%,this=$something{weird}
Arg 0 is <jason,this=$something{weird}>
柠檬色的秋千 2024-08-16 21:17:47

我使用这种简单、干净、有效的方法。

我将参数放在一个数组中,每行 1 个。这样就非常容易阅读和编辑。
然后我使用一个简单的技巧,将双引号内的所有参数传递给具有 1 个单参数的函数。这会将它们(包括数组)展平为单个字符串,然后我使用 PS 的“调用表达式”执行该字符串。该指令专门用于将字符串转换为可运行的命令。
效果很好:

# function with one argument will flatten 
# all passed-in entries into 1 single string line
Function Execute($command) {
    # execute:
    Invoke-Expression $command;
    # if you have trouble try:
    # Invoke-Expression "& $command";
    # or if you need also output to a variable
    # Invoke-Expression $command | Tee-Object -Variable cmdOutput;
}

#  ... your main code here ...

# The name of your executable app
$app = 'my_app.exe';
# List of arguments:
# Notice the type of quotes - important !
# Those in single quotes are normal strings, like 'Peter'
$args = 'arg1',
        'arg2',
        $some_variable,
        'arg4',
        "arg5='with quotes'",
        'arg6',
        "arg7 \ with \ $other_variable",
        'etc...';
    
# pass all arguments inside double quotes
Execute "$app $args";
  

I use this simple, clean and effective method.

I place arguments in an array, 1 per line. This way it is very easy to read and edit.
Then I use a simple trick of passing all arguments inside double quotes to a function with 1 single parameter. That flattens them, including arrays, to a single string, which I then execute using PS's 'Invoke-Expression'. This directive is specifically designed to convert a string to runnable command.
Works well:

# function with one argument will flatten 
# all passed-in entries into 1 single string line
Function Execute($command) {
    # execute:
    Invoke-Expression $command;
    # if you have trouble try:
    # Invoke-Expression "& $command";
    # or if you need also output to a variable
    # Invoke-Expression $command | Tee-Object -Variable cmdOutput;
}

#  ... your main code here ...

# The name of your executable app
$app = 'my_app.exe';
# List of arguments:
# Notice the type of quotes - important !
# Those in single quotes are normal strings, like 'Peter'
$args = 'arg1',
        'arg2',
        $some_variable,
        'arg4',
        "arg5='with quotes'",
        'arg6',
        "arg7 \ with \ $other_variable",
        'etc...';
    
# pass all arguments inside double quotes
Execute "$app $args";
  
萌无敌 2024-08-16 21:17:47

您可以通过不同方式在 powershell 中运行 exe 文件。例如,如果您想运行 unrar.exe 并提取 .rar 文件,您可以简单地在 powershell 中编写以下内容:

$extract_path = "C:\Program Files\Containing folder";
$rar_to_extract = "C:\Path_to_arch\file.rar"; #(or.exe if its a big file)  
C:\Path_here\Unrar.exe x -o+ -c- $rar_to_extract $extract_path;

但有时,这不起作用,因此您必须使用 &参数如上图:
例如,使用 vboxmanage.exe(管理 virtualbox 虚拟机的工具),您必须像这样调用字符串外部的参数,不带引号:

> $vmname = "misae_unrtes_1234123"; #(name too long, we want to change this)
> & 'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe' modifyvm $vmname --name UBUNTU;

如果您只想将 winrar 存档文件作为 .exe 文件调用,您也可以解压它使用调用命令 cmdlet 和静默参数 /S (它将在与压缩所在的文件夹相同的文件夹中解压)。

> Invoke-Command -ScriptBlock { C:\Your-path\archivefile.exe /S };

因此,有多种方法可以在 powershell 中运行带参数的 .exe 文件。

有时,必须找到一种解决方法才能使其正常工作,这可能需要一些进一步的努力和痛苦:),具体取决于 .exe 的创建者编译或制作的方式。

You can run exe files in powershell different ways. For instance if you want to run unrar.exe and extract a .rar file you can simply write in powershell this:

$extract_path = "C:\Program Files\Containing folder";
$rar_to_extract = "C:\Path_to_arch\file.rar"; #(or.exe if its a big file)  
C:\Path_here\Unrar.exe x -o+ -c- $rar_to_extract $extract_path;

But sometimes, this doesn't work so you must use the & parameter as shown above:
For instance, with vboxmanage.exe (a tool to manage virtualbox virtual machines) you must call the paramterers outside of the string like this, without quotes:

> $vmname = "misae_unrtes_1234123"; #(name too long, we want to change this)
> & 'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe' modifyvm $vmname --name UBUNTU;

If you want to call simply a winrar archived file as .exe files, you can also unzip it with the invoke-command cmdlet and a Silent parameter /S (Its going to extract itself in the same folder than where it has been compressed).

> Invoke-Command -ScriptBlock { C:\Your-path\archivefile.exe /S };

So there are several ways to run .exe files with arguments in powershell.

Sometimes, one must find a workaround to make it work properly, which can require some further effort and pain :) depending on the way the .exe has been compiled or made by its creators.

万劫不复 2024-08-16 21:17:47

我尝试了所有建议,但仍然无法使用包含空格的参数运行 msiexec.exe。所以我的解决方案最终使用 System.Diagnostics.ProcessStartInfo :

# can have spaces here, no problems
$settings = @{
  CONNECTION_STRING = "... ..."
  ENTITY_CONTEXT = "... ..."
  URL = "..."
}

$settingsJoined = ($settings.Keys | % { "$_=""$($settings[$_])""" }) -join " "
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.WorkingDirectory = $ScriptDirectory
$pinfo.FileName = "msiexec.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "/l* install.log /i installer.msi $settingsJoined"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$stdout = $p.StandardOutput.ReadToEnd()
$p.WaitForExit()

I tried all of the suggestions but was still unable to run msiexec.exe with parameters that contained spaces. So my solution ended up using System.Diagnostics.ProcessStartInfo:

# can have spaces here, no problems
$settings = @{
  CONNECTION_STRING = "... ..."
  ENTITY_CONTEXT = "... ..."
  URL = "..."
}

$settingsJoined = ($settings.Keys | % { "$_=""$($settings[$_])""" }) -join " "
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.WorkingDirectory = $ScriptDirectory
$pinfo.FileName = "msiexec.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "/l* install.log /i installer.msi $settingsJoined"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$stdout = $p.StandardOutput.ReadToEnd()
$p.WaitForExit()
唱一曲作罢 2024-08-16 21:17:47

Cmd 可以处理运行引用的 exe,但 Powershell 不能。我只是要处理运行 exe 本身,因为我没有它。如果您确实需要向外部命令的参数发送双引号,那么这是其他地方讨论过的另一个问题。

1) 将 exe 文件夹添加到您的路径中,也许在您的 $profile 中

$env:path += ';C:\Program Files\IIS\Microsoft Web Deploy\'
msdeploy

2) 反引号空格:

C:\Program` Files\IIS\Microsoft` Web` Deploy\msdeploy.exe

Cmd can handle running a quoted exe, but Powershell can't. I'm just going to deal with running the exe itself, since I don't have it. If you literally need to send doublequotes to an argument of an external command, that's another issue that's been covered elsewhere.

1) add the exe folder to your path, maybe in your $profile

$env:path += ';C:\Program Files\IIS\Microsoft Web Deploy\'
msdeploy

2) backquote the spaces:

C:\Program` Files\IIS\Microsoft` Web` Deploy\msdeploy.exe
宫墨修音 2024-08-16 21:17:47

这对我有用:

PowerShell.exe -Command "& ""C:\Some Script\Path With Spaces.ps1"""

关键似乎是整个命令用外引号括起来,即“&” & 符号用于指定正在执行的另一个子命令文件,然后最后在路径/文件名周围转义(双双)引号,并在您想要首先执行的地方包含空格。

这也是解决 MS 连接问题的唯一解决方法,即 -File 不会传回非零返回代码,而 -Command 是唯一的替代方案。但直到现在,人们还认为 -Command 的一个限制是它不支持空格。我也更新了该反馈项目。

http://connect.microsoft.com/PowerShell/feedback/details/750653/powershell-exe-doesn-t-return- Correct-exit-codes-when-using-the-file-option

This worked for me:

PowerShell.exe -Command "& ""C:\Some Script\Path With Spaces.ps1"""

The key seems to be that the whole command is enclosed in outer quotes, the "&" ampersand is used to specify another child command file is being executed, then finally escaped (doubled-double-) quotes around the path/file name with spaces in you wanted to execute in the first place.

This is also completion of the only workaround to the MS connect issue that -File does not pass-back non-zero return codes and -Command is the only alternative. But until now it was thought a limitation of -Command was that it didn't support spaces. I've updated that feedback item too.

http://connect.microsoft.com/PowerShell/feedback/details/750653/powershell-exe-doesn-t-return-correct-exit-codes-when-using-the-file-option

哀由 2024-08-16 21:17:47

另一种答案是使用 Base64 编码的命令开关:

powershell -EncodedCommand "QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA=="

解码后,您会看到它是OP 的原始片段保留了所有参数和双引号。

powershell.exe -EncodedCommand

Accepts a base-64-encoded string version of a command. Use this parameter
to submit commands to Windows PowerShell that require complex quotation
marks or curly braces.

原始命令:

 C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

当编码为 Base64 时,它会变成这样:

QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA==

下面是如何在家里复制:

$command = 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
$encodedCommand

#  The clip below copies the base64 string to your clipboard for right click and paste.
$encodedCommand | Clip

An alternative answer is to use a Base64 encoded command switch:

powershell -EncodedCommand "QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA=="

When decoded, you'll see it's the OP's original snippet with all arguments and double quotes preserved.

powershell.exe -EncodedCommand

Accepts a base-64-encoded string version of a command. Use this parameter
to submit commands to Windows PowerShell that require complex quotation
marks or curly braces.

The original command:

 C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

It turns into this when encoded as Base64:

QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA==

and here is how to replicate at home:

$command = 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
$encodedCommand

#  The clip below copies the base64 string to your clipboard for right click and paste.
$encodedCommand | Clip
尬尬 2024-08-16 21:17:47

对于可执行文件名称,可以使用 new-alias cmdlet 来避免处理空格或需要将可执行文件添加到 $PATH 环境。

PS> new-alias msdeploy "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe"
PS> msdeploy ...

要列出或修改 PS 别名,另请参阅

PS> get-alias
PS> set-alias

Jeffery Hicks 文章

其他答案解决了论点。

For the executable name, the new-alias cmdlet can be employed to avoid dealing with spaces or needing to add the executable to the $PATH environment.

PS> new-alias msdeploy "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe"
PS> msdeploy ...

To list or modify PS aliases also see

PS> get-alias
PS> set-alias

From Jeffery Hicks Aarticle

Other answers address the arguments.

清浅ˋ旧时光 2024-08-16 21:17:47

如果您只需要运行当前目录中的文件并且不想拼写整个路径,请使用 Get-Location

& "$(Get-Location)\example.exe" arg1 arg2 arg3

注意开头的 &。间隔参数应放置在引号之后

If you just need to run a file in the current directory and don't feel like spelling out the entire path use Get-Location:

& "$(Get-Location)\example.exe" arg1 arg2 arg3

Note the & at the start. Spaced arguments are to be placed after the quotes.

计㈡愣 2024-08-16 21:17:47

我的以下代码在我的笔记本电脑上完美运行:

& $msdeploy `
-source:package="$publishFile" `
-dest:auto,computerName="$server",includeAcls="False",UserName="$username",Password="$password",AuthType="$auth" `
-allowUntrusted  `
-verb:sync  `
-enableRule:DoNotDeleteRule `
-disableLink:AppPoolExtension  `
-disableLink:ContentExtension  `
-disableLink:CertificateExtension  `
-skip:objectName=filePath,absolutePath="^(.*Web\.config|.*Environment\.config)$" `
-setParam:name=`"IIS Web Application Name`",value="$appName"

然后,当我尝试直接在一台服务器上运行该代码时,我开始收到这些错误 “无法识别的参数......等等......所有参数必须以“-”开头。 。

在尝试了所有可能的解决方法(没有成功)后,我发现服务器(Windows 2008 R2)上的Powershell是3.0版本,而我的笔记本电脑是5.0版本 (您可以使用“$PSVersionTable”查看版本)。

将 Powershell 升级到最新版本后,它再次开始工作。

I had the following code working perfect on my laptop:

& $msdeploy `
-source:package="$publishFile" `
-dest:auto,computerName="$server",includeAcls="False",UserName="$username",Password="$password",AuthType="$auth" `
-allowUntrusted  `
-verb:sync  `
-enableRule:DoNotDeleteRule `
-disableLink:AppPoolExtension  `
-disableLink:ContentExtension  `
-disableLink:CertificateExtension  `
-skip:objectName=filePath,absolutePath="^(.*Web\.config|.*Environment\.config)$" `
-setParam:name=`"IIS Web Application Name`",value="$appName"

Then when I tried to run that directly on one server I started getting those errors "Unrecognized argument ...etc.... All arguments must begin with "-". "

After trying all possible workarounds (no success), I found out that Powershell on the server (Windows 2008 R2) was version 3.0, while my laptop has 5.0. (you can use "$PSVersionTable" to see version).

After upgrading Powershell to latest version it started working again.

捂风挽笑 2024-08-16 21:17:47

要将 cmd.exe 命令转换为 PowerShell,我必须使用 &和“引用”“许多”“参数”“和”“一些”“参数”。如果我需要带引号的参数,我会混合单引号和双引号来完成它。我不知道最好的简单方法,我试图混合 PowerShell 变量,但我不得不做这样的愚蠢的事情:

$PS C:\> & "$Env:JAVA_HOME\bin\java.exe" "-Dhttp.proxyHost=myproxy" "-Dhttp.proxyPort=3128" "-jar" "myprogram.jar" "myprogramarg"

它在不引用 -jar、myprogram.jar 或 myprogramarg 的情况下工作。我认为这是因为他们没有空间。我不知道为什么 -Dhttp 必须被引用,就像 PowerShell 想要解释它们一样。将变量中的所有 -D 选项采用与 cmd.exe 中相同的格式是行不通的。我尝试将内部参数用单引号括起来。我尝试过反转引号和单引号。它只是不像 cmd.exe 那样简单:

C:\> set JAVA_FLAGS=-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=3128
C:\> %JAVA_HOME%\bin\java.exe %JAVA_FLAGS% -jar myprogram.jar myprogramarg

To convert a cmd.exe command to PowerShell I had to use & and "quote" "many" "parameters" "and" "some" "arguments". If I had needed to have arguments with quotes, I would have mixed single and double quotes to get it done. I don't know the best simple way, and I was trying to mix in PowerShell variables, but I had to do silly stuff like this:

$PS C:\> & "$Env:JAVA_HOME\bin\java.exe" "-Dhttp.proxyHost=myproxy" "-Dhttp.proxyPort=3128" "-jar" "myprogram.jar" "myprogramarg"

It worked without quoting -jar, myprogram.jar, or myprogramarg. I think this is because they don't have spaces. I don't know why -Dhttp had to be quoted, it was like PowerShell wanted to interpret them. It did not work to have all the -D options in a variable in the same format as worked in cmd.exe. I tried wrapping the inner arguments in single quotes. I tried reversing quotes and single quotes. It just did not work as simple as cmd.exe:

C:\> set JAVA_FLAGS=-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=3128
C:\> %JAVA_HOME%\bin\java.exe %JAVA_FLAGS% -jar myprogram.jar myprogramarg
差↓一点笑了 2024-08-16 21:17:47

因此,我遇到了类似的问题,并选择以这种方式解决它:

  1. 用反引号 (`) 转义引号 (")
  2. 字符 用引号 (") 包围新表达式
  3. 使用调用运算符 (&),发出对新字符串执行命令 invoke-expression

解决方案示例:

& { 调用表达式 "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql=`"数据源=mysource;集成安全性=false;用户 ID=sa;Pwd=sapass! ;数据库=mydb;`" -dest:dbfullsql=`"数据源=.\mydestsource;集成安全性=false;用户ID=sa;Pwd=sapass!;数据库=mydb;`",计算机名=10.10.10.10,用户名=管理员,密码=adminpass`"" }

So, I ran into a similar problem and chose to solve it this way instead:

  1. Escape your quote (") characters with a backtick (`)
  2. Surround your new expression with quotes (")
  3. Using the call operator (&), issue the command invoke-expression on the new string

Example solution:

& { invoke-expression "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`" -dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`",computername=10.10.10.10,username=administrator,password=adminpass`"" }

甜心 2024-08-16 21:17:47

我面临着向命令提供 '-s、"-s 甚至 ${Filename} 的挑战,另一方面在这些参数中填写变量。

要将使用 exiftool.exe 的批处理脚本传输到 powershell 脚本, :使用“echochars”的替换非常出色,它清楚地显示了分组为单个参数的内容以及最终作为下一个参数的内容,

它与 perl(和 unix 脚本)类似:使用的引号有其含义。

  • "-s 之间的字符串。该字符串将被解释(填充变量)
  • '-s 之间的字符串。该字符串不会被解释(或非常有限),
  • 转义字符是`(反引号)。下一个字符就失去了它的特殊含义。相当于 unix/linux/perl 上的 \(后划线)。

一些示例:

${ExifArgs} += "-if `"`${FileName} !~ /desktop.ini/i`""
${ExifArgs} += '-dateFormat "%Y\%Y%m\%Y%m%d_%H%M%S"'
${ExifArgs} += ('"' + "-FileName<${NewFotos}\${SourceName}\" + '${DateTimeOriginal}_${ImageWidth}x${ImageHeight}_${Model;s/ //g}_${FileName;s/^.*([0-9]{4})[^0-9].*$/\1/}.%e' + '"')

使用上面的命令调用 echoargs,会产生下一个输出(出于隐私考虑,数字被黑客攻击):

Arg 11 is <-if>
Arg 12 is <${FileName} !~ /desktop.ini/i>
Arg 13 is <-dateFormat>
Arg 14 is <%Y\%Y%m\%Y%m%d_%H%M%S>
Arg 15 is <-FileName<D:\Pictures\NewFotos\${DateTimeOriginal}_${ImageWidth}x${ImageHeight}_${Model;s/ //g}_${FileName;s/^.*([0-9]{4})[^0-9].*$/\1/}.%e>

看看第一行如何产生 arg 11 和 12:删除外部的“-s 以将整行存储在数组中。由 `-s 引用的内部 "-s 是为了将参数保持在一起(而 -if 是前一个参数)

第二个显示 arg 13 和 14:在 '-s 之间使用 "-s 不需要。使用 `-s 进行转义。

在最后一行(生成 arg 15):通过使用 powershell ()-s 和 +-s 将几个字符串连接到单个字符串来构造单个字符串。分隔字符串,其中一些 ${}-s 由 powershell 填充,一些由 exiftool 填充。
是的,一些 powershell 特殊字符被转移到拱门中。

To transfer a batch script using exiftool.exe to a powershell script I had the challange to give '-s, "-s and even ${Filename} to the command and on the other hand fill out variables in these parameters.

For a start: The replacement in using 'echochars' is brilliant. It clearly shows what is grouped as a single parameter and what ends up as the next parameter.

In powershell it is similar to perl (and unix scripting): the used quotes have their meaning.

  • strings between "-s. The string will be interpreted (variables filled)
  • Strings between '-s. The string will not be interpreted (or verry limited)
  • the escape character is ` (the back-quote). The next character looses its special meaning. Comparable with the \ (back stroke) on unix/linux/perl.

Some examples:

${ExifArgs} += "-if `"`${FileName} !~ /desktop.ini/i`""
${ExifArgs} += '-dateFormat "%Y\%Y%m\%Y%m%d_%H%M%S"'
${ExifArgs} += ('"' + "-FileName<${NewFotos}\${SourceName}\" + '${DateTimeOriginal}_${ImageWidth}x${ImageHeight}_${Model;s/ //g}_${FileName;s/^.*([0-9]{4})[^0-9].*$/\1/}.%e' + '"')

A call to echoargs with the above, produces the next output (numbers are hacked for privacy):

Arg 11 is <-if>
Arg 12 is <${FileName} !~ /desktop.ini/i>
Arg 13 is <-dateFormat>
Arg 14 is <%Y\%Y%m\%Y%m%d_%H%M%S>
Arg 15 is <-FileName<D:\Pictures\NewFotos\${DateTimeOriginal}_${ImageWidth}x${ImageHeight}_${Model;s/ //g}_${FileName;s/^.*([0-9]{4})[^0-9].*$/\1/}.%e>

See how the first line produces arg 11 and 12: the outher "-s are removed to store the entire line in the array. The inner "-s, quoted by the `-s are there to keep the argument together (while the -if is the previous argument)

The second shows arg 13 and 14: the use of "-s between '-s. No need to escape using `-s.

In the last line (producing arg 15): the single string is constructed by using powershell ()-s and +-s to concatenate a couple of strings to a single string. It uses both " and ' delimited strings to have som ${}-s filled out by powershell and some for exiftool.
And yes, some powershell special characters are transvered into the archuments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文