我有一个Scheduled Task,它每15分钟运行一次,是一个非常非常快速的BATCH过程。这第一个";FILE1.bat";进程调用另一个,如下所示:"FILE2.bat">gt;路径\winscp_TODAYSDATE.txt通过这种方式,我可以将第二个的所有输出转换为TXT";日志文件";。FILE2.bat只是将文件复制到";DONE";文件夹,并通过WINSCP将它们发送给提供商,并使用mput-delete,一旦成功发送,它就会删除文件。
由于我不知道的一些原因,TASK(不确定任务本身、FILE1还是FILE2)运行两次(甚至三次),一次接一次地运行几毫秒,如下一段所示。这是当没有要处理的文件时的结果:
*************************************************************
******** HORA DEL REGISTRO: 21/12/2022 - 0:05:01,26 ********
*************************************************************
***** SIN ficheros TXT para procesar, se ha omitido el proceso y no se envia email
Success - No files to process - FICHEROS ENVIADOS: NO FILES
*************************************************************
******** HORA DEL REGISTRO: 21/12/2022 - 0:05:01,77 ********
*************************************************************
***** SIN ficheros TXT para procesar, se ha omitido el proceso y no se envia email
Success - No files to process - FICHEROS ENVIADOS: NO FILES
*************************************************************
******** HORA DEL REGISTRO: 21/12/2022 - 0:20:00,97 ********
*************************************************************
***** SIN ficheros TXT para procesar, se ha omitido el proceso y no se envia email
Success - No files to process - FICHEROS ENVIADOS: NO FILES
*************************************************************
******** HORA DEL REGISTRO: 21/12/2022 - 0:20:01,26 ********
*************************************************************
***** SIN ficheros TXT para procesar, se ha omitido el proceso y no se envia email
Success - No files to process - FICHEROS ENVIADOS: NO FILES
*************************************************************
******** HORA DEL REGISTRO: 21/12/2022 - 0:20:01,76 ********
*************************************************************
***** SIN ficheros TXT para procesar, se ha omitido el proceso y no se envia email
Success - No files to process - FICHEROS ENVIADOS: NO FILES
但是,当有文件要处理时,会发生这种情况(但并不总是如此):
*************************************************************
******** HORA DEL REGISTRO: 21/12/2022 - 14:05:01,47 ********
*************************************************************
***** Se comprueba si hay ficheros TXT que existan para procesar: SI
***** Se copian los ficheros que existan para enviar antes de enviarlos a la subcarpeta COPIAS, sobreescribiendo
l:entradasALS20221221135146008008649.txt
*************************************************************
******** HORA DEL REGISTRO: 21/12/2022 - 14:05:02,47 ********
*************************************************************
***** Se comprueba si hay ficheros TXT que existan para procesar: SI
***** Se copian los ficheros que existan para enviar antes de enviarlos a la subcarpeta COPIAS, sobreescribiendo
l:entradasALS20221221135146008008649.txt
l:entradasALS20221221135434008008649.txt
l:entradasALS20221221135534008008649.txt
l:entradasALS20221221135809008008649.txt
4 archivo(s) copiado(s).
***** Se ejecuta WINSCP con los parametros necesarios
Connecting to x-x-x-x-x-x-x-x-x-xguro.com ...
Connected
Starting the session...
Session started.
Active session: [1] copx-x-x-xx-x-x-x-x-x-x-x-x-xguro.com
l:entradas
/ENTRADAS
ALS20221221135146008008649.txt | 14 KB | 0,0 KB/s | binary | 100%
ALS20221221135434008008649.txt | 1 KB | 5,6 KB/s | binary | 100%
ALS20221221135534008008649.txt | 1 KB | 6,2 KB/s | binary | 100%
ALS20221221135809008008649.txt | 1 KB | 6,8 KB/s | binary | 100%
/SALIDAS
l:SALIDAS
No file matching '*' found.
Session 'copx-x-x-xx-x-x-x-x-x-x-x-x-xguro.com' closed.
No session.
***** Se revisa si ha habido errores en el envio. ERRORCODE:0
***** Envio sin errores: Se omite el email
***** Resultado del envio por FTP
Success - The files were uploaded successfully. - FICHEROS ENVIADOS: SI
*************************************************************
******** HORA DEL REGISTRO: 21/12/2022 - 14:20:01,88 ********
*************************************************************
***** SIN ficheros TXT para procesar, se ha omitido el proceso y no se envia email
Success - No files to process - FICHEROS ENVIADOS: NO FILES
幸运的是,到目前为止,文件已经成功发送,但它填满了日志,我对此并不放心…
我已经尽了最大的努力,找不到这种行为的原因或解决方案。我也附上了导出的TASK的XML。
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2022-10-28T12:14:19.6597722</Date>
<Author>SEFRISAeqm</Author>
<URI>_GyV FTP Logifrio_</URI>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<Repetition>
<Interval>PT15M</Interval>
<StopAtDurationEnd>false</StopAtDurationEnd>
</Repetition>
<StartBoundary>2022-10-28T12:05:00</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>S-1-5-21-1834156839-169156998-926709054-1284</UserId>
<LogonType>Password</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>StopExisting</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>false</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>GyV_Reg.bat</Command>
<WorkingDirectory>C:TareasFTP_Logifrio</WorkingDirectory>
</Exec>
</Actions>
</Task>
我只是寻找了一个解决方案,并尝试更改任务选项,但没有一个奏效,甚至有些选项无法正确执行任务。
编辑:@Mofi,这里有FILE1(GyV_Reg.bat)和FILE2(GyV.bat)。我相信我在某个时候尝试过用%SystemRoot%System32cmd.exe
运行你提到的任务,但没有成功。我将进一步研究/D/C修饰符。非常感谢
Gyv_Reg.bat
@echo off
if not exist l: net use l: /persistent:yes \servidor2k9logifrio$
set day=%date:~0,2%
set month=%date:~3,2%
set year=%date:~6,4%
set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
set FECHA_HOY=%year%%month%%day%
gyv.bat >> L:WinScpLogswinscp_%FECHA_HOY%.txt
gyv.bat(没有任何敏感信息)
@echo off
REM setlocal enabledelayedexpansion
ECHO *************************************************************
ECHO ******** HORA DEL REGISTRO: %DATE% - %TIME% ********
ECHO *************************************************************
if not exist l: (
net use l: /persistent:yes \servidor2k9logifrio$
ECHO ***** No existe la unidad L: Se mapea como persistente
)
rem ECHO ***** Se accede a la unidad L:
l:
REM Se comprueba si hay ficheros TXT que existan para enviar
if not exist l:entradasAL*.TXT (
set FILES_EXIST=NO
set FILES_SENT=NO FILES
set WINSCP_SUBJECT=Success
set WINSCP_MESSAGE=No files to process
REM Si no hay ficheros TXT para procesar, se omite el proceso
GOTO SkipProcess
)
REM Se especifican la ruta y el formato del nombre del fichero de LOGS
set FILES_EXIST=SI
set day=%date:~0,2%
set month=%date:~3,2%
set year=%date:~6,4%
set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
set FECHAHORA=%year%%month%%day%-%hour%%min%
set WINSCP_LOG_HOY=L:WinScpLogswinscp_%FECHAHORA%.xml
ECHO ***** Se comprueba si hay ficheros TXT que existan para procesar: %FILES_EXIST%
ECHO ***** Se copian los ficheros que existan para enviar antes de enviarlos a la subcarpeta COPIAS, sobreescribiendo
copy l:entradas*.* l:entradascopias /y
ECHO ***** Se ejecuta WINSCP con los parametros necesarios
REM ******************************************************************************************************************
REM La linea siguiente, COMENTADA, se puede habilitar, inhabilitando la de debajo, para hacer pruebas sin enviar nada
REM ******************************************************************************************************************
rem c:winscp.com /ini=nul /script="C:TareasFTP_Logifriogyv_test.txt" /log=%WINSCP_LOG_HOY% /xmlgroups /loglevel=2 /logsize=20*1M
REM ******************************************************************************************************************
c:winscp.com /ini=nul /script="C:TareasFTP_Logifriogyv.txt" /log=%WINSCP_LOG_HOY% /xmlgroups /loglevel=2 /logsize=20*1M
set ERROR_CODE=%ERRORLEVEL%
ECHO ***** Se revisa si ha habido errores en el envio. ERRORCODE:%ERROR_CODE%
IF %ERROR_CODE% NEQ 0 (
ECHO ***** Envio con errores: Se prepara el email
set WINSCP_SUBJECT=Error FTP Logifrio-SRVIMPRESORAS
set WINSCP_MESSAGE=Error uploading files, see attached log. ErrorLevel: %ERROR_CODE%
ECHO ********** WINSCP_MESSAGE: %WINSCP_MESSAGE%
REM Prepare email contents
set SMTP_FROM=siX-X-X-X-X-X@X-X-X-X-X-X.com
set SMTP_TO=siX-X-X-X-X-X@X-X-X-X-X-X.com
set SMTP_SERVER=smtpX-X-X-X-X-X.com
set SMTP_USERNAME=siX-X-X-X-X-X@X-X-X-X-X-X.com
set SMTP_PASSWORD=CoX-X-X-X-X-X3
REM Check if LOG file exists and set it as attachment for the email
if exist %WINSCP_LOG_HOY% (
ECHO ********** WINSCP_LOG_HOY: %WINSCP_LOG_HOY%
set ATTACHMENT=%WINSCP_LOG_HOY%
) else (
ECHO ***** No existe WINSCP_LOG_HOY - Se genera uno vacio en TXT
set WINSCP_LOG_VACIO=C:TareasFTP_Logifriowinscp_VACIO_%FECHAHORA%.txt
ECHO NO EXISTE LOG > "%WINSCP_LOG_VACIO%"
set ATTACHMENT=%WINSCP_LOG_VACIO%
)
set FILES_SENT=NO
GOTO SendEmail
) else (
ECHO ***** Envio sin errores: Se omite el email
set WINSCP_SUBJECT=Success
set WINSCP_MESSAGE=The files were uploaded successfully.
set FILES_SENT=SI
GOTO Resultado
)
:SendEmail
ECHO ***** Envio del email a siX-X-X-X-X-X@X-X-X-X-X-X.com
REM Send the email message
CALL :PowerShell
CD /D "%PowerShellDir%"
ECHO '%PSScript%' '%SMTP_USERNAME%' '%SMTP_PASSWORD%' '%ATTACHMENT%'
Powershell.exe -ExecutionPolicy Bypass -Command "& '%PSScript%' '%SMTP_USERNAME%' '%SMTP_PASSWORD%' '%ATTACHMENT%'"
CD /D "C:TareasFTP_Logifrio"
:Resultado
ECHO ***** Resultado del envio por FTP
ECHO %WINSCP_SUBJECT% - %WINSCP_MESSAGE% - FICHEROS ENVIADOS: %FILES_SENT%
GOTO FIN
:SkipProcess
ECHO ***** SIN ficheros TXT para procesar, se ha omitido el proceso y no se envia email
ECHO %WINSCP_SUBJECT% - %WINSCP_MESSAGE% - FICHEROS ENVIADOS: %FILES_SENT%
GOTO FIN
:FIN
rem ECHO ***** Se vuelve a acceder a la unidad C:
c:
GOTO SALIR
:PowerShell
SET PowerShellDir=C:WindowsSystem32WindowsPowerShellv1.0
SET PSScript=%temp%~tmpSendeMail.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
ECHO $Username = "%SMTP_USERNAME%" >> "%PSScript%"
ECHO $EmailPassword = "%SMTP_PASSWORD%" >> "%PSScript%"
ECHO $Attachment = "%ATTACHMENT%" >> "%PSScript%"
ECHO >> "%PSScript%"
ECHO $Username = "%SMTP_USERNAME%" >> "%PSScript%"
ECHO $EmailTo = "%SMTP_TO%" >> "%PSScript%"
ECHO $EmailFrom = "%SMTP_FROM%" >> "%PSScript%"
ECHO $Subject = "%WINSCP_SUBJECT%" >> "%PSScript%"
ECHO $Body = "%WINSCP_MESSAGE%" >> "%PSScript%"
ECHO $SMTPServer = "%SMTP_SERVER%" >> "%PSScript%"
ECHO $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body) >> "%PSScript%"
ECHO $Attachment = New-Object System.Net.Mail.Attachment($Attachment) >> "%PSScript%"
ECHO $SMTPMessage.Attachments.Add($Attachment) >> "%PSScript%"
ECHO $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) >> "%PSScript%"
ECHO $SMTPClient.EnableSsl = $true >> "%PSScript%"
ECHO $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Username, $EmailPassword) >> "%PSScript%"
ECHO $SMTPClient.Send($SMTPMessage) >> "%PSScript%"
GOTO :EOF
:SALIR
@echo on
我建议对此任务只使用一个批处理文件。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=1-5 delims=/: " %%G in ('%SystemRoot%System32robocopy.exe "%SystemDrive%|" . /NJH') do set "FECHAHORA=%%G%%H%%I-%%J%%K" & set "LogFileName=\servidor2k9logifrio$WinScpLogswinscp_%%G%%H%%I.txt" & goto RunMainJob
:RunMainJob
(call :gyv) >>"%LogFileName%"
exit /B
:gyv
ECHO *************************************************************
ECHO ******** HORA DEL REGISTRO: %DATE% - %TIME% ********
ECHO *************************************************************
pushd "\servidor2k9logifrio$" || (echo ERROR: Failed to temporarily map shared folder \servidor2k9logifrio$& exit /B)
REM Se comprueba si hay ficheros TXT que existan para enviar
if exist entradasAL*.TXT goto ProcessFiles
set "FILES_EXIST=NO"
set "FILES_SENT=NO FILES"
set "WINSCP_SUBJECT=Success"
set "WINSCP_MESSAGE=No files to process"
REM Si no hay ficheros TXT para procesar, se omite el proceso
ECHO ***** SIN ficheros TXT para procesar, se ha omitido el proceso y no se envia email
ECHO %WINSCP_SUBJECT% - %WINSCP_MESSAGE% - FICHEROS ENVIADOS: %FILES_SENT%
goto FIN
:ProcessFiles
REM Se especifican la ruta y el formato del nombre del fichero de LOGS
set "FILES_EXIST=SI"
set "WINSCP_LOG_HOY=WinScpLogswinscp_%FECHAHORA%.xml"
ECHO ***** Se comprueba si hay ficheros TXT que existan para procesar: %FILES_EXIST%
ECHO ***** Se copian los ficheros que existan para enviar antes de enviarlos a la subcarpeta COPIAS, sobreescribiendo
md entradascopias 2>nul
copy /Y entradas*.* entradascopias
ECHO ***** Se ejecuta WINSCP con los parametros necesarios
REM ******************************************************************************************************************
REM La linea siguiente, COMENTADA, se puede habilitar, inhabilitando la de debajo, para hacer pruebas sin enviar nada
REM ******************************************************************************************************************
rem c:winscp.com /ini=nul /script="C:TareasFTP_Logifriogyv_test.txt" /log=%WINSCP_LOG_HOY% /xmlgroups /loglevel=2 /logsize=20*1M
REM ******************************************************************************************************************
C:winscp.com /ini=nul /script="C:TareasFTP_Logifriogyv.txt" /log=%WINSCP_LOG_HOY% /xmlgroups /loglevel=2 /logsize=20*1M
set "ERROR_CODE=%ERRORLEVEL%"
ECHO ***** Se revisa si ha habido errores en el envio. ERRORCODE:%ERROR_CODE%
if %ERROR_CODE% == 0 (
ECHO ***** Envio sin errores: Se omite el email
set "WINSCP_SUBJECT=Success"
set "WINSCP_MESSAGE=The files were uploaded successfully."
set "FILES_SENT=SI"
goto Resultado
)
ECHO ***** Envio con errores: Se prepara el email
set "WINSCP_SUBJECT=Error FTP Logifrio-SRVIMPRESORAS"
set "WINSCP_MESSAGE=Error uploading files, see attached log. ErrorLevel: %ERROR_CODE%"
ECHO ********** WINSCP_MESSAGE: %WINSCP_MESSAGE%
REM Prepare email contents
set "SMTP_FROM=siX-X-X-X-X-X@X-X-X-X-X-X.com"
set "SMTP_TO=siX-X-X-X-X-X@X-X-X-X-X-X.com"
set "SMTP_SERVER=smtpX-X-X-X-X-X.com"
set "SMTP_USERNAME=siX-X-X-X-X-X@X-X-X-X-X-X.com"
set "SMTP_PASSWORD=CoX-X-X-X-X-X3"
REM Check if LOG file exists and set it as attachment for the email
if exist "%WINSCP_LOG_HOY%" (
ECHO ********** WINSCP_LOG_HOY: %WINSCP_LOG_HOY%
set "ATTACHMENT=%WINSCP_LOG_HOY%"
) else (
ECHO ***** No existe WINSCP_LOG_HOY - Se genera uno vacio en TXT
set "WINSCP_LOG_VACIO=C:TareasFTP_Logifriowinscp_VACIO_%FECHAHORA%.txt"
ECHO NO EXISTE LOG > "%WINSCP_LOG_VACIO%"
set "ATTACHMENT=%WINSCP_LOG_VACIO%"
)
set "FILES_SENT=NO"
ECHO ***** Envio del email a siX-X-X-X-X-X@X-X-X-X-X-X.com
REM Send the email message
call :PowerShell
ECHO '%PSScript%' '%SMTP_USERNAME%' '%SMTP_PASSWORD%' '%ATTACHMENT%'
"%PowerShellDir%Powershell.exe" -ExecutionPolicy Bypass -File "%PSScript%" "%SMTP_USERNAME%" "%SMTP_PASSWORD%" "%ATTACHMENT%"
del "%PSScript%"
:Resultado
ECHO ***** Resultado del envio por FTP
ECHO %WINSCP_SUBJECT% - %WINSCP_MESSAGE% - FICHEROS ENVIADOS: %FILES_SENT%
goto FIN
:FIN
rem ECHO ***** Se vuelve a acceder a la unidad C:
popd
goto :EOF
:PowerShell
set "PowerShellDir=%SystemRoot%System32WindowsPowerShellv1.0"
set "PSScript=%TEMP%~tmpSendeMail.ps1"
(
ECHO $Username = "%SMTP_USERNAME%"
ECHO $EmailPassword = "%SMTP_PASSWORD%"
ECHO $Attachment = "%ATTACHMENT%"
ECHO $Username = "%SMTP_USERNAME%"
ECHO $EmailTo = "%SMTP_TO%"
ECHO $EmailFrom = "%SMTP_FROM%"
ECHO $Subject = "%WINSCP_SUBJECT%"
ECHO $Body = "%WINSCP_MESSAGE%"
ECHO $SMTPServer = "%SMTP_SERVER%"
ECHO $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body^)
ECHO $Attachment = New-Object System.Net.Mail.Attachment($Attachment^)
ECHO $SMTPMessage.Attachments.Add($Attachment^)
ECHO $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587^)
ECHO $SMTPClient.EnableSsl = $true
ECHO $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Username, $EmailPassword^)
ECHO $SMTPClient.Send($SMTPMessage^)
)> "%PSScript%"
goto :EOF
为了解释获取当前日期时间的更好方法,请阅读午夜后时间设置不正确,这与为用于运行批处理文件的帐户配置的国家/地区无关。
批处理文件必须使用命令call
从另一个批处理文件调用,这在您的gyv_reg.bat
版本中没有执行。上面的代码将gyv.bat
的改进代码嵌入到gyv_reg.bat
中,以避免一个任务不必要地使用两个批处理文件。
可以用(call "%~dp0gyv.bat") >>"%LogFileName%"
替换(call :gyv) >>"%LogFileName%"
,并将标签行:gyv
下方的所有内容放入与批处理文件gyv_reg.bat
存储在同一目录中的批处理文件中gyv.bat
,并且可以用命令endlocal
替换gyv_reg.bat
中在这种情况下不需要的exit /B
。但请注意,gyv
代码中使用的环境变量FECHAHORA
是在gyv_reg.bat
的第三行中定义的。由于这个原因,如果没有使用与第三行中几乎相同的ROBOCOPY命令行解决方案定义环境变量,第二批处理文件gyv.bat
将不再独立工作。
我还应用了其他一些改进,以简化命令执行顺序,避免像使用命令net use l: /persistent:yes \servidor2k9logifrio$
那样更新所用帐户的注册表配置单元。请参阅RunOnce批处理文件中映射驱动器上的答案,以了解此命令行在执行时在Windows注册表中更改的内容。
命令PUSHD将用计划任务属性Start-in(XML元素WorkingDirectory
)定义的当前目录路径推送到堆栈,使用为计划任务配置的帐户的凭据(帐户名和密码)将指定的共享文件夹映射到下一个可用的驱动器号,并使该驱动器的根目录成为当前目录。如果由于共享文件夹在具有自动应用的帐户凭据的时刻根本不可访问而失败,则退出子程序gyv
(分别处理关于使用不必要的第二批文件的gyv.bat
)并返回错误信息。标签:FIN
后末尾的命令POPD删除由pushd
创建的临时驱动器映射,并使从堆栈中弹出其路径后的初始当前目录成为当前目录。
还修改了PowerShell脚本的创建方式,将所有ECHO命令放入命令块中,并将命令块的输出重定向到脚本文件中。这避免了文件打开、查找结束、每行追加一行、关闭一行,从而使PowerShell脚本文件创建速度更快,文件系统访问次数更少。所有要写入文件的右圆括号都必须使用^
进行转义,以将其解释为文字字符,而不是更有效的解决方案中的命令块末尾。
运行PowerShell以处理创建的脚本文件的命令行也更改为建议的语法,作为在命令提示符窗口或PowerShell控制台窗口中运行PowerShell /?
时的输出。
临时创建的PowerShell脚本文件现在也会在使用后立即删除,并且在重新创建之前不会再保存在临时文件的文件夹中,即现在仅临时创建和使用。