Ваша проблема заключается в области видимости меток и контроля потока в командном интерпретаторе Windows (CMD). Ваша логика подразумевает использование меток для управления выполнением кодовых блоков, но в командных циклах `FOR` поведение отличается от обычных условных операторов.
Предлагаю рассмотреть ваш код и внести некоторые изменения, чтобы добиться нужного результата.
### Основные моменты:
1. **Область видимости меток:** Каждая метка, которую вы определяете (например, `:fail` и `:next`), имеет локальную область видимости в теле цикла `FOR`. Если вы используете `GOTO`, он может выйти из цикла, но не перейдет к следующей итерации. Это приведет к тому, что код после метки `:next` не будет выполняться, и выполнение вернется в начало цикла.
2. **Логика управления потоком:** Вместо использования `GOTO` между метками, можно использовать переменные для управления потоком выполнения.
### Пример исправленного кода:
```cmd
@ECHO OFF
Setlocal EnableDelayedExpansion
SET file=hosts.txt
SET username=megoodminЪ
SET pass=megoodminЪ_password
FOR /F %%i IN (%file%) DO (
SET tmpip=%%i
NET USE \\!!tmpip! %pass% /USER:%username%
IF errorlevel 1 (
ECHO Shutdown !!tmpip! failed
NET USE \\!!tmpip! /DELETE
GOTO next
)
REM SHUTDOWN /R /T 30 /F /M \\!!tmpip!
IF errorlevel 1 (
ECHO Shutdown !!tmpip! failed
) ELSE (
ECHO Shutdown !!tmpip! success
)
NET USE \\!!tmpip! /DELETE
:next
)
```
### Основные изменения:
- Вложенные блоки if используют скобки `()` для явного определения, что следует делать в случае ошибки.
- Убраны метки `:fail` и `:next` для упрощения логики. Вместо этого осуществляется только прерывание текущей итерации с помощью `GOTO next`.
- Пользуйтесь `NET USE \\!!tmpip! /DELETE` только один раз после обработки IP и возможного отключения.
Теперь после неудачной попытки подключения к компьютеру через `NET USE`, выполнение переходит к следующему IP из файла, а не к меткам, что обеспечивает корректное поведение цикла.