从 ipconfig 中获取未知 IP,并使用 BATCH 脚本使用该 IP 编辑未知.ini行



目前我有一个设置,其中一个程序希望我的 LAN IP 将其数据附加到,当我重新启动系统时,这个 LAN IP 总是随机的。我的 LAN 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:ProgramDataNuanceNaturallySpeaking12nssystem.ini) | ForEach-Object { $_ -replace 'Default NAS Address=.*','Default NAS Address=BHPAPPDGN01V' } | Set-Content C:ProgramDataNuanceNaturallySpeaking12nssystem.ini

需要更改的行大多是随机的。嗯,不是随机的,但它有时会移动,因为用户可以进行一些更改,并且它会根据设置将 IP 线向下或向上推。

在BATCH和Powershell方面,我有点新手,我还没有找到将信息传输到Powershell的方法。例如,BATCH 将抓取 IP,生成变量,运行编辑.ini的 powershell 脚本。我确实记得有一个代码将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%PROGRAMPROGRAM.exe"
timeout /t 1 /nobreak>nul
exit
:waiting
echo PROGRAM is still running. Retrying...
timeout /t 3 /nobreak>nul
goto check

我不需要setlocal EnableExtensions但我确实试图让它工作,当时就需要它。 目前脚本查看程序是否正在运行,如果是,请轻轻杀死它(等待它本机退出),然后重新启动它。我的目标是轻轻地杀死它,编辑.ini,然后使用更改的内容重新启动它。

纯PowerShell解决方案很可能是此任务的最佳选择,因为Windows命令处理器cmd.exe不是为编辑文件而设计的。

但这是一个纯批处理文件解决方案,用于确定当前 IPv4 地址并将其写入 INI 文件(如果它当前包含不同的地址)。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "IniFile=C:ProgramDataNuanceNaturallySpeaking12nssystem.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%System32ipconfig.exe ^| %SystemRoot%System32findstr.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%System32findstr.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%System32findstr.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

请阅读我的回答 如何逐行读取和打印文本文件的内容?
它解释了仅使用 Windows 命令更新 INI 文件的可怕缓慢代码。

要了解使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,然后完整而仔细地阅读每个命令的显示帮助页面。

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

另请参阅使用 Windows 批处理文件的单行包含多个命令,以获取运算符&的说明。

阅读Microsoft篇关于使用命令重定向运算符的文章,了解>2>nul|的说明。当 Windows 命令解释器在执行命令 FOR 之前处理此命令行时,重定向运算符|必须使用插入符号^FOR 进行转义,以便在执行命令FOR之前将此命令行解释为文字字符,该命令使用FOR执行嵌入的findstripconfig命令行,并使用在后台启动的单独命令进程%ComSpec% /c和附加两个'之间的命令行。

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轻松找到它,并且它不应该更改。您还需要更新路径信息。

最新更新