Seharusnya bisa mengurutkan ini tapi aku berputar-putar. Saya tahu ini ada hubungannya dengan setlocal EnableDelayedExpansion, tapi saya melewatkan sesuatu.

Sasaran: Jalankan skrip windows (cleanmgr.exe) pada mesin jarak jauh, tunggu hingga Cleanmgr.exe ditutup, lalu minta skrip inisiasi "ketik" file log yang dihasilkan (dihasilkan melalui skrip pembersihan) dari sistem jarak jauh di jendela CMD.

Apa yang berfungsi: Skrip yang berjalan pada mesin jarak jauh berjalan dengan baik, itu menggemakan C: mengosongkan ruang drive ke dalam file log, kemudian membersihkan PC, dan kemudian menjalankan kembali laporan ruang disk dan hasil gema ke dalam file log yang sama, sehingga pengguna dapat melihat (/ memiliki transparansi) ruang reklamasi melalui hasil sebelum & sesudah.

Apa yang Rusak: Perintah WMIC untuk memeriksa Cleanmgr.exe di PC target, hanya berfungsi sekali, ketika menunggu untuk mencoba lagi variabel yang berisi Hostname telah dihapus. Saya dapat melihat perilaku dengan menggemakan variabel kembali.

Perbaiki Upaya: Saya punya firasat ini ada hubungannya dengan variabel yang hilang setelah pernyataan if dijalankan dalam Tanda kurung. Saya telah mencoba banyak opsi tetapi semuanya berperilaku sama. Saya telah mencoba melompati proses untuk mengulang di luar kode asli menggunakan %1 alih-alih %%i tetapi tidak bisa sampai di sana.

Terima kasih untuk setiap perbaikan.

@echo off
pushd %~dp0
color 1e
setlocal EnableDelayedExpansion
title HDD Space Checker...
for /f %%i in (hostnames.txt) do (
xcopy /y cleanupwindows-sfd.bat \\%%i\C$\IT
WMIC /node:"%%i" process call create "C:\IT\cleanupwindows-sfd.bat"
echo Waiting For Processes...
timeout -t 10 /nobreak >nul
:loop
WMIC /node:"%%i" process where name="cleanmgr.exe" get name |find "cleanmgr.exe">nul
IF "!errorlevel!"=="0" set running=var
IF "!running!"=="var" timeout -t 4 >nul & echo Still Running & goto :loop
IF "!running!"=="" timeout -t 4 >nul & type \\%%i\C$\IT\%%i_HHD_Space.log
)
pause
exit
1
Tika9o9 12 Mei 2021, 19:31

1 menjawab

Jawaban Terbaik

Setidaknya ada dua poin yang bisa dilihat.

  1. Variabel running Anda, setelah disetel, tidak pernah disetel ulang, memicu loop tak terbatas
  2. Pernyataan goto Anda di dalam kurung terlampir mendorong penerjemah perintah (cmd.exe) untuk berhenti mengevaluasi blok, sehingga skrip Anda kehilangan %%i dan meninggalkan for loop, sehingga ketika mengakhiri :loop siklus skrip Anda akan meninggalkan for loop tanpa bersepeda ke nilai lain di hostnames.txt.

Untuk mengatasinya, masukkan kode proses Anda ke dalam subrutin yang disebut dengan CALL dan setel ulang variabel running pada setiap siklus :loop :

@echo off
pushd %~dp0
color 1e
setlocal EnableDelayedExpansion
title HDD Space Checker...
for /f %%i in (hostnames.txt) do (
  CALL:Process "%%i"
)
pause
exit
:Process
xcopy /y cleanupwindows-sfd.bat \\%~1\C$\IT
WMIC /node:"%~1" process call create "C:\IT\cleanupwindows-sfd.bat"
echo Waiting For Processes...
timeout -t 10 /nobreak >nul
:loop
set "running="
WMIC /node:"%~1" process where name="cleanmgr.exe" get name |find "cleanmgr.exe">nul
IF "!errorlevel!"=="0" set "running=var"
IF "!running!"=="var" timeout -t 4 >nul & echo Still Running & goto :loop
IF "!running!"=="" timeout -t 4 >nul & type \\%~1\C$\IT\%~1_HHD_Space.log
GOTO:EOF

Penjelasan: Pernyataan CALL menyiratkan bahwa penerjemah perintah akan menyimpan baris skrip Anda yang dieksekusi saat ini dan statusnya sebelum mengeksekusi subproses/perintah/etc terkait. Ketika subproses/perintah/etc.. selesai, perintah interpreter melanjutkan eksekusi skripnya ke baris berikutnya dengan konteks yang dipulihkan. Ini menghindari lepasnya konteks loop for.

2
Zilog80 12 Mei 2021, 17:12