转义序列问题 - 批量

时间:2015-07-09 14:37:31

标签: powershell batch-file

我想在批处理文件中使用PowerShell命令发送电子邮件。为此,我实现了一个名为 sendMail 的函数。我这样称呼它:

setlocal enabledelayedexpansion
call:sendMail
powershell -command "!_mailCommand!"
endlocal
pause&goto:eof

我的 sendMail 功能:

:sendMail

set "_mailCommand=&{$filenameAndPath = '!resultFile!';"
set "_mailCommand=%_mailCommand%$SMTPMessage = New-Object System.Net.Mail.MailMessage('%_mailFrom%', '%_mailTo%', '%_mailSubject%', '%_mailBody%');"
set "_mailCommand=%_mailCommand%$attachment = New-Object System.Net.Mail.Attachment($filenameAndPath);"
set "_mailCommand=%_mailCommand%$SMTPMessage.Attachments.Add($attachment);"
set "_mailCommand=%_mailCommand%$SMTPClient = New-Object Net.Mail.SmtpClient('%_mailHost%', %_mailPort%);"
set "_mailCommand=%_mailCommand%$SMTPClient.EnableSsl = $true;"
set "_mailCommand=%_mailCommand%$SMTPClient.Credentials = New-Object System.Net.NetworkCredential('%_mailFrom%','%_mailSenderPassword%');"
set "_mailCommand=%_mailCommand%$SMTPClient.Send($SMTPMessage)}"
echo %_mailSenderPassword%

出乎意料的是我得到了这样的输出:

  

12345Aa!

     

异常呼叫"发送"用" 1"参数:"发送邮件失败。"

     

在行:1字符:499   ... m',' 12345Aa ^'); $ SMTPClient.Send($ SMTPMessage)}

     

CategoryInfo:NotSpecified:(:) [],MethodInvocationException

     

FullyQualifiedErrorId:SmtpException

您可以猜到,我的密码是 12345Aa!,我在代码的开头定义为set "_mailSenderPassword=12345Aa^^!"

那我错过了什么?提前谢谢!

2 个答案:

答案 0 :(得分:1)

当您使用延迟扩展时,您应该避免扩展百分比,否则您会遇到插入符号^和感叹号!以及有时也带引号的问题。

在扩展百分比之后,内容将被解析为特殊字符,但在延迟扩展后,它将保持不变。

setlocal EnableDelayedExpansion
set "_mailSenderPassword=12345Aa^!"
call :sendMail
powershell -command "!_mailCommand!"
exit /b

:sendMail
set "_mailCommand=&{$filenameAndPath = '!resultFile!';"
set "_mailCommand=!_mailCommand!$SMTPMessage = New-Object System.Net.Mail.MailMessage('!_mailFrom!', '!_mailTo!', '!_mailSubject!', '!_mailBody!');"
set "_mailCommand=!_mailCommand!$attachment = New-Object System.Net.Mail.Attachment($filenameAndPath);"
set "_mailCommand=!_mailCommand!$SMTPMessage.Attachments.Add($attachment);"
set "_mailCommand=!_mailCommand!$SMTPClient = New-Object Net.Mail.SmtpClient('!_mailHost!', !_mailPort!);"
set "_mailCommand=!_mailCommand!$SMTPClient.EnableSsl = $true;"
set "_mailCommand=!_mailCommand!$SMTPClient.Credentials = New-Object System.Net.NetworkCredential('!_mailFrom!','!_mailSenderPassword!');"
set "_mailCommand=!_mailCommand!$SMTPClient.Send($SMTPMessage)}"
echo !_mailSenderPassword!
exit /b

答案 1 :(得分:0)

以下简化示例适用于我(它成功回显了12345Aa^!):

set "_mailSenderPassword=12345Aa^!"

setlocal enabledelayedexpansion
call:sendMail
powershell -command "!_mailCommand!"
endlocal
pause&goto:eof

:sendMail
set "_mailCommand=echo '%_mailSenderPassword%';"
echo %_mailSenderPassword%
echo %_mailCommand%

请注意,我必须在之前设置_mailSenderPassword 我致电setlocal enabledelayedexpansion

还有一个有趣的怪癖:在enabledelayedexpansion下你仍然可以 获得相同的结果,但你必须使用3个(三个)插入符号。例如。以下内容将起作用:

setlocal enabledelayedexpansion
set "_mailSenderPassword=12345Aa^^^!"

call:sendMail
powershell -command "!_mailCommand!"
endlocal
pause&goto:eof

:sendMail
set "_mailCommand=echo '%_mailSenderPassword%';"
echo %_mailSenderPassword%
echo %_mailCommand%