Захватите неизвестный IP из ipconfig и отредактируйте неизвестную строку .ini с этим IP с помощью скрипта BATCH - PullRequest
2 голосов
/ 04 ноября 2019

В настоящее время у меня есть настройка, при которой программа хочет, чтобы мой IP-адрес локальной сети привязывал свои данные, и этот IP-адрес локальной сети всегда был случайным при перезагрузке системы. Мой IP-адрес локальной сети всегда отличается, так как я использую VPN, так что это своего рода морда каждый раз, когда я либо меняю сеть, либо перезагружаюсь, так как мне нужно запустить программу, изменить ее, перезапустить.

У меня естьскрипт, который создаст переменную с правильным IP-адресом, так как это всегда первый IPv4-адрес. Я нашел его на этом сайте.

set ip_address_string="IPv4 Address"
rem Uncomment the following line when using older versions of Windows without IPv6 support (by removing "rem")
rem set ip_address_string="IP Address"
for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:%ip_address_string%`) do (
    echo Your IP Address is: %%f
    goto :eof
)

Это прекрасно, но каждый найденный мной пост редактирования .ini на самом деле не работает для меня, так как печатает строку бесконечно, а не редактирует ее.

Поскольку размер .ini неизвестен, мне нужен скрипт powershell, чтобы он работал, так как BATCH имеет ограничения.

Один пользователь в Stackoverflow имел этот код:

(Get-Content C:\ProgramData\Nuance\NaturallySpeaking12\nssystem.ini) | ForEach-Object { $_ -replace 'Default NAS Address=.*','Default NAS Address=BHPAPPDGN01V' } | Set-Content C:\ProgramData\Nuance\NaturallySpeaking12\nssystem.ini

Строка, которую нужно изменить, в основном случайная. Ну, не случайно, но иногда он будет двигаться, так как пользователи могут вносить некоторые изменения, и он будет толкать IP-линию вниз или вверх в зависимости от настроек.

Я немного новичок, когда дело доходит до BATCHи powershell, и я не нашел способ передать информацию в powershell. Например, BATCH захватит IP-адрес, создаст переменную, запустит скрипт powershell, редактирующий .ini. Я помню, что имел код, который захватил IP в буфер обмена, но я не могу найти его в данный момент.

Мой текущий прогресс

@echo off
setlocal EnableExtensions
echo Exiting PROGRAM...
taskkill /IM PROGRAM.exe
timeout /t 1 /nobreak>nul
:check
for /F %%a in ('tasklist /NH /FI "IMAGENAME eq PROGRAM.exe"') do if %%a == PROGRAM.exe goto waiting
echo Restarting PROGRAM...
start "" "%ProgramFiles%\PROGRAM\PROGRAM.exe"
timeout /t 1 /nobreak>nul
exit
:waiting
echo PROGRAM is still running. Retrying...
timeout /t 3 /nobreak>nul
goto check

Мне не нужно setlocal EnableExtensions, но ядействительно пытался заставить это работать, и это было необходимо тогда. В настоящее время скрипт проверяет, запущена ли программа, если она есть, мягко убейте ее (дождитесь ее завершения) и перезапустите. Моя цель - мягко убить его, отредактировать .ini, а затем перезапустить его с внесенными изменениями.

Ответы [ 2 ]

1 голос
/ 04 ноября 2019

Чистое решение PowerShell, скорее всего, будет лучшим решением для этой задачи, поскольку командный процессор Windows cmd.exe не предназначен для редактирования файлов.

Но здесь представлено чисто пакетное решение для определения текущего IPv4. адрес и запишите его в INI-файл, если он содержит другой адрес.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "IniFile=C:\ProgramData\Nuance\NaturallySpeaking12\nssystem.ini"
if exist "%IniFile%" goto GetIpAddress

echo ERROR: File missing: "%IniFile%"
echo/
pause
goto EndBatch

:GetIpAddress
set "ip_address_string=IPv4 Address"
rem Uncomment the following line when using older versions of Windows without IPv6 support (by removing "rem")
rem set "ip_address_string=IP Address"
rem The string above must be IP-Adresse on a German Windows.
for /F "tokens=2 delims=:" %%I in ('%SystemRoot%\System32\ipconfig.exe ^| %SystemRoot%\System32\findstr.exe /C:"%ip_address_string%"') do set "IpAddress=%%I" & goto IpAddressFound

echo ERROR: Could not find %ip_address_string% in output of ipconfig.
echo/
pause
goto EndBatch

:IpAddressFound
set "IniEntry=Default NAS Address"
rem Remove leading (and also trailing) spaces/tabs.
for /F %%I in ("%IpAddress%") do set "IpAddress=%%I"
rem Do not modify the INI file if it contains already the current IP address.
%SystemRoot%\System32\findstr.exe /L /X /C:"%IniEntry%=%IpAddress%" "%IniFile%" >nul
if errorlevel 1 goto UpdateIniFile

echo The file "%IniFile%"
echo contains already the line: %IniEntry%=%IpAddress%
echo/
goto EndBatch

:UpdateIniFile
for %%I in ("%IniFile%") do set "TempFile=%%~dpnI.tmp"
(for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /N "^" "%IniFile%" 2^>nul') do (
    set "Line=%%I"
    setlocal EnableDelayedExpansion
    set "Line=!Line:*:=!"
    if not defined Line echo(
    for /F delims^=^=^ eol^= %%J in ("!Line!") do (
        set "FirstToken=%%J"
        if "!FirstToken!" == "%IniEntry%" (
            echo %IniEntry%=%IpAddress%
        ) else echo(!Line!
    )
    endlocal
))>"%TempFile%"

rem Replace the INI file by the temporary file, except the temporary file is empty.
if exist "%TempFile%" (
    for %%I in ("%TempFile%") do if not %%~zI == 0 (
        move /Y "%TempFile%" "%IniFile%" >nul
        echo Updated the file "%IniFile%"
        echo with the %ip_address_string% "%IpAddress%" for INI entry "%IniEntry%".
        echo/
    )
    del "%TempFile%" 2>nul
)

:EndBatch
endlocal

Пожалуйста, прочитайте мой ответ на Как читать и печатать содержимое текстового файла построчно?
Это объясняет ужасный медленный код для обновления INI-файла, используя Команды Windows .

Чтобы понять используемые команды и их работу, откройте командную строку в окне, выполните там следующие команды и очень внимательно прочитайте все страницы справки, отображаемые для каждой команды.

  • del /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • ipconfig /?
  • move /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?

См. Также Одна строка с несколькими командами с использованием пакетного файла Windows для объяснения оператора &.

Читатьстатья Microsoft о Использование операторов перенаправления команд для объяснения >, 2>nul и |. Оператор перенаправления | должен быть экранирован с помощью символа вставки ^ в FOR командной строке, чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , котораявыполняет встроенную командную строку с ipconfig и findstr в отдельном командном процессе, запущенном в фоновом режиме с %ComSpec% /c и командной строкой между двумя ' с добавлением.

0 голосов
/ 04 ноября 2019

У Mofi было отличное пакетное решение, но он упомянул, что CMD на самом деле не был разработан для вывода файлов, подобного этому. Итак, вот чистое решение PowerShell, которое должно делать то, что вы хотите. Он немного заимствует из фрагмента powershell, который вы включили в свой вопрос.

$ip = Get-NetIPAddress -InterfaceAlias "Ethernet" #| Out-File PathTo:\net.ini
$content = get-content PathTo:\net.ini | ForEach-Object { $_ -replace "172.23.*","$($ip.IPAddress)"} 
$content | Set-Content PathTo:\net.ini

Очевидно, это зависит от того, знаете ли вы псевдоним интерфейса, который вы хотите получить, но вы можете легко это найти с помощью Get-NetIPAddress, иэто не должно измениться. Вам также необходимо обновить информацию о пути.

...