Batch File para iniciar .exe quando um número específico de arquivos está na pasta monitorada

2

Estou tentando gravar um arquivo em lote que acionará um exe sempre que houver exatamente 4 imagens jpg em uma pasta. Depois as imagens devem ser apagadas.

Eu tenho que funcionar, parece, mas o arquivo inicia o exe uma e outra vez. Eu não consigo entender minha cabeça sobre o erro.

Qualquer ajuda é muito apreciada!

@echo off
setlocal EnableDelayedExpansion
set counter=0

:loop
cd "c:\JPGfolder\"
for %%B in (*) do set /a counter+=1
echo File Count = !counter!

if !counter! EQU 4 (
for /f "delims=|" %%I in ('DIR "c:\JPGfolder\" /B /O:-D *.jpg') DO (
SET NewestFile=%%I
echo Newest File = "c:\JPGfolder\!NewestFile!"
start "" /w "c:\programs\generate.exe" "c:\JPGfolder\"%NewestFile%
del c:\JPGfolder\*.jpg
GOTO :BREAK
)
)

:BREAK
set /a counter=0

ping -n 2 localhost >nul

) else (
 echo No Files Found
 rem pause
 goto :loop
)
goto :loop
    
por mohawk 15.09.2014 / 21:13

2 respostas

5

Eu vejo vários problemas com seu código. Mas não consigo ver como você está obtendo o comportamento que descreve.

1) Você está contando todos os arquivos, mas seu código para obter o mais novo e excluir tudo só funciona com arquivos .jpg. Sua contagem também deve ser restrita a arquivos .jpg.

2) Você esqueceu de usar a expansão atrasada na sua linha START. Mas, na verdade, não há necessidade de usar um valor de ambiente. Você pode simplesmente usar %%I diretamente, portanto, a expansão atrasada não é necessária. Além disso, todo o caminho do arquivo deve estar entre aspas.

3) Você tem um ) extra que fecha sua instrução IF antecipadamente. As linhas ) ELSE ( e ) são simplesmente ignoradas e as linhas intermediárias são executadas incondicionalmente. Esta é uma peculiar peculiaridade do analisador de lote. Se o analisador está procurando por um comando, e não existe um bloco de parênteses aberto, então ) e tudo depois dele nessa linha são simplesmente ignorados.

4) Se você corrigir seus parênteses excluindo uma das ) linhas, você ainda terá um problema porque você GOTO um rótulo dentro da instrução IF complexa. As instruções IF ELSE são quebradas pelo GOTO, assim como as instruções FOR / F. Consulte o link para obter mais informações.

5) Seu extrato de CD deve usar a opção / D, caso você esteja em um volume diferente. Ou isso, ou use PUSHD em vez disso.

6) A mensagem "Nenhum arquivo encontrado" está incorreta. Ele realmente deve dizer "Número de arquivos < > 4"

7) Seu algoritmo tem uma falha fundamental. E se você tiver 3 arquivos .jpg quando o seu código for verificado pela primeira vez e, no momento em que verificar novamente, houver 5 arquivos .jpg? Seu código nunca verá uma contagem de 4!

Existem também algumas simplificações possíveis.

8) Desde que você definiu seu diretório atual para "c: \ JPGfolder", você não precisa mais especificar explicitamente o caminho para o arquivo a cada vez. Você pode simplesmente usar %%~fI para obter o caminho completo.

9) Eu moveria a inicialização da contagem para abaixo do rótulo :LOOP . Então você não precisa se preocupar em definir o valor em dois lugares.

Eu acredito que o seguinte é a lógica que você estava tentando alcançar. Tenha em mente, isso não aborda o ponto 7).

@echo off
setlocal
cd /d "c:\JPGfolder\"

:loop
set counter=0
for %%B in (*.jpg) do set /a counter+=1
echo File Count = %counter%

if %counter% EQU 4 (
  for /f "delims=|" %%I in ('DIR *.jpg /B /O:-D') DO (
    echo Newest File = "%%~fI"
    start "" /w "c:\programs\generate.exe" "%%~fI"
    del *.jpg
    ping -n 2 localhost >nul
    goto :break
  )
) else (
  echo File count <> 4
)
:break
goto :loop

Os itens acima podem ser simplificados para:

@echo off
setlocal
cd /d "c:\JPGfolder\"

:loop
set counter=0
for %%B in (*.jpg) do set /a counter+=1
echo File Count = %counter%

if %counter% EQU 4 (
  for /f "delims=|" %%I in ('DIR *.jpg /B /O:-D') DO (
    echo Newest File = "%%~fI"
    start "" /w "c:\programs\generate.exe" "%%~fI"
    del *.jpg
    ping -n 2 localhost >nul
    goto :loop
  )
)
echo File count <> 4
goto :loop

Mas, na verdade, você provavelmente deve introduzir um atraso em cada iteração, se existem 4 arquivos .jpg ou não.

@echo off
setlocal
cd /d "c:\JPGfolder\"

:loop
set counter=0
for %%B in (*.jpg) do set /a counter+=1
echo File Count = %counter%

if %counter% EQU 4 (
  for /f "delims=|" %%I in ('DIR *.jpg /B /O:-D') DO (
    echo Newest File = "%%~fI"
    start "" /w "c:\programs\generate.exe" "%%~fI"
    del *.jpg
    goto :break
  )
) else (
  echo File count <> 4
)
:break
ping -n 2 localhost >nul
goto :loop

Eu não usaria nenhum dos códigos acima por causa do ponto 7). Eu não posso resolver isso porque eu não sei qual é a sua intenção.

UPDATE

Parece-me que você está monitorando uma pasta para arquivos de imagem e deseja processar cada 4ª por algum programa, em ordem cronológica. Todos os arquivos são excluídos após terem sido recebidos. Eu recomendo mover os arquivos em vez de excluí-los, caso algo dê errado e você queira recuperar algumas outras imagens. Você sempre pode excluir manualmente os arquivos salvos a qualquer momento.

Seu algoritmo atual exige que o script em lote leia e processe os arquivos mais rapidamente do que as imagens adicionadas à pasta, caso contrário você corre o risco de perder a contagem de 4 e nenhuma outra imagem será processada (meu ponto 7 acima). / p>

Abaixo está um novo algoritmo que sempre funciona, independentemente de quão rápido as imagens são adicionadas.

Em vez de redefinir o contador para 0 após cada loop, deixo o contador crescer indefinidamente. Eu uso módulo aritmético para determinar quando um arquivo representa um múltiplo de 4 (resultado do módulo é 0). Detecto o valor do módulo 0 aumentando intencionalmente uma divisão por erro zero, e o || condicionalmente executa um bloco de código no erro.

@echo off
setlocal
cd /d "c:\JPGfolder"
md save 2>nul
set counter=0

:LOOP
for /f "delims=|" %%I in ('DIR *.jpg /B /O:-D') do (
  set /a "1/((counter+=1)%%4)" 2>nul || (
    echo Newest File = "%%~fI"
    start "" /w "c:\programs\generate.exe" "%%~fI"
  )
    move "%%I" save >nul
)
ping -n 2 localhost >nul
goto :LOOP

Seu comentário afirma que você está criando uma colagem de todas as 4 imagens dentro de cada iteração. Eu não vejo como isso funciona quando você só passa um único nome de arquivo para generate.exe. Mas se é realmente o que está acontecendo, então o seguinte código alternativo deve funcionar:

@echo off
setlocal
cd /d "c:\JPGfolder"
2>nul (
  md save
  md working
  del working\*
)
set counter=0

:LOOP
for /f "delims=|" %%I in ('DIR *.jpg /B /O:-D') do (
  move "%%I" working >nul
  set /a "1/((counter+=1)%%4)" 2>nul || (
    echo Newest File = "%%~fI"
    start "" /w "c:\programs\generate.exe" "%%~dpIworking\%%~nxI"
    move working\* save >nul
  )
)
ping -n 2 localhost >nul
goto :LOOP
    
por 15.09.2014 / 22:58
1

Sua lógica diz: Se counter = 4, então para cada jpg na pasta, inicie exe.

Configurar o contador como 0 dentro do loop, depois de você ter determinado que ele é igual a 4, não interromperá o loop.

Você também tem uma instrução IF incompleta, causada por um colchete de fechamento extra (antes do: BREAK) que está mexendo com sua instrução ELSE.

Espero que ajude!

    
por 15.09.2014 / 21:26