Windows 如何自动卸载包含“的所有程序?”;VNC“;在他们的displayname中使用批处理文件?

Windows 如何自动卸载包含“的所有程序?”;VNC“;在他们的displayname中使用批处理文件?,windows,batch-file,Windows,Batch File,我正在尝试创建一个批处理脚本,该脚本将查询注册表中的卸载包。目标是创建一个批处理脚本,用于卸载所有VNC程序(UltraVNC、RealVNC和TightVNC)。这必须与Windows XP和Windows 7兼容 我从这个StackOverflow解决方案的脚本开始。我正在尝试更改代码,以允许它在DisplayName中搜索“VNC”,在其相应的卸载路径中删除{}之间的文本,然后运行msiexec.exe/qn/x{package identifier}以静默卸载程序 当运行以下代码时,它检

我正在尝试创建一个批处理脚本,该脚本将查询注册表中的卸载包。目标是创建一个批处理脚本,用于卸载所有VNC程序(UltraVNC、RealVNC和TightVNC)。这必须与Windows XP和Windows 7兼容

我从这个StackOverflow解决方案的脚本开始。我正在尝试更改代码,以允许它在DisplayName中搜索“VNC”,在其相应的卸载路径中删除{}之间的文本,然后运行
msiexec.exe/qn/x{package identifier}
以静默卸载程序

当运行以下代码时,它检索几个在其显示名中不包含“VNC”的程序。问题似乎存在于以下代码行中:

if not "x!str1:VNC=!"=="x!str1!" (
这行代码的来源:

if not "x!str1:VNC=!"=="x!str1!" (
我尝试了在中找到的以下代码作为替代,但它也列出了太多的包,并且没有正确地只选择名称中带有“VNC”的包

set str1 = !product[%counter%]!
echo str1 > temp.dat
findstr /c:"VNC" "temp.dat" >nul 2>&1
if %errorlevel% == 0 (
注意:许多
echo
命令仅用于测试目的

 @echo off
    setlocal
    set regVar=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
    set excluded=/c:" Microsoft" /c:"MDOP" /c:"Dell" 
    set count=1
    for /f "tokens=1,2,*" %%a in ('Reg Query %regVar% /S ^| findstr "DisplayName HKEY_ UninstallString"') do (
        setlocal EnableDelayedExpansion
        for %%n in (!count!) do (
            ENDLOCAL
            SET HKEY=Y
            IF "%%a"=="DisplayName" SET "HKEY="&set product[%%n]=%%c
            IF "%%a"=="UninstallString" SET "HKEY="&IF NOT DEFINED uninstall[%%n] set uninstall[%%n]=%%c
            IF "%%a"=="QuietUninstallString" SET "HKEY="&IF NOT DEFINED uninstall[%%n] set uninstall[%%n]=%%c
        IF DEFINED hkey IF DEFINED product[%%n] IF defined uninstall[%%n] SET /a count+=1&SET "hkey="
        IF DEFINED hkey set "product[%%n]="&SET "uninstall[%%n]="
        )
    )

    IF NOT DEFINED product[%count%] SET "uninstall[%count%]="&SET /a count-=1
    IF NOT DEFINED uninstall[%count%] SET "product[%count%]="&SET /a count-=1
    ECHO %count% entries found
    set counter=%count%
    pause
    @setlocal enableextensions enabledelayedexpansion
    :while
    if %counter% GTR 0 (
        set str1 = !product[%counter%]!
        echo str1
        if not "x!str1:VNC=!"=="x!str1!" (
            echo !product[%counter%]!
            echo !uninstall[%counter%]!
            set UninstallString=!uninstall[%counter%]!
            echo !UninstallString!
            set RunUninstall = ""
            for /f "tokens=2 delims={}" %%A in ("!uninstall[%counter%]!") do echo %%A REM set RunUninstall="msiExec.exe /qn /x{%%A}" (commented for testing purposes)
            call !RunUninstall!
            set /a counter-=1
            GOTO While
            ) Else (
            set /a counter-=1
            GOTO While
            )
        )
输出代码段:

Intel(R) Network Connections 15.7.176.0
MsiExec.exe /X{26A24AE4-039D-4CA4-87B4-2F86418051F0}
MsiExec.exe /X{26A24AE4-039D-4CA4-87B4-2F86418051F0}
26A24AE4-039D-4CA4-87B4-2F86418051F0 REM set RunUninstall="msiExec.exe /qn /x{26
A24AE4-039D-4CA4-87B4-2F86418051F0}"
ECHO is off.
Microsoft .NET Framework 4.5.2
MsiExec.exe /X{26784146-6E05-3FF9-9335-786C7C0FB5BE}
MsiExec.exe /X{26784146-6E05-3FF9-9335-786C7C0FB5BE}
26784146-6E05-3FF9-9335-786C7C0FB5BE REM set RunUninstall="msiExec.exe /qn /x{26
784146-6E05-3FF9-9335-786C7C0FB5BE}"
ECHO is off.
Lenovo ThinkVantage Toolbox
MsiExec.exe /I{23170F69-40C1-2702-0920-000001000000}
MsiExec.exe /I{23170F69-40C1-2702-0920-000001000000}
23170F69-40C1-2702-0920-000001000000 REM set RunUninstall="msiExec.exe /qn /x{23
170F69-40C1-2702-0920-000001000000}"
ECHO is off.
OSFMount v1.5
MsiExec.exe /I{1B8ABA62-74F0-47ED-B18C-A43128E591B8}
MsiExec.exe /I{1B8ABA62-74F0-47ED-B18C-A43128E591B8}
1B8ABA62-74F0-47ED-B18C-A43128E591B8 REM set RunUninstall="msiExec.exe /qn /x{1B
8ABA62-74F0-47ED-B18C-A43128E591B8}"
更新: 我修改了wOxxOm提供的代码,试图为TightVNC创建一个例外并悄悄地卸载它。由于TightVNC的注册表中没有quietInstallString,因此我试图通过使用
msiexec.exe/qn/x
选项来实现这一点。但是,它不断抛出以下错误:

else was unexpected at this time.
我对wOxxOm代码的修改版本如下所示:

@echo off
setlocal enableDelayedExpansion
for %%a in ("" "\Wow6432Node") do (
    for /f "delims=" %%b in ('
        reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
            /s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
    ') do (
        set "line=%%b"
        if "!line:~0,4!"=="HKEY" (
            set "key=!line!"
        ) else (
            set Uninstall=
            rem Sort /r makes QuietUninstallString the last line
            for /f "tokens=2*" %%c in ('
                reg query "!key!" ^| find "UninstallString" ^| sort /r
            ') do if not "%%d"=="" set "Uninstall=%%d"

            if defined Uninstall (

                for /f "tokens=2*" %%c in ("!line!") do (
                    set product=%%d
                    if "x!product:TightVNC=!"=="x!product!" (
                        for /f "tokens=2 delims={}" %%A in ("!Uninstall!") do (
                        echo Found !product!
                        Running msiExec.exe /qn /x{%%A} REM (COMMENTED FOR TESTING)
                        REM CALL msiExec.exe /qn /x{%%A}
                        )
                    ) else (
                    echo Found %%d
                    echo Running !Uninstall! (COMMENTED FOR TESTING)
                    rem call !Uninstall!
                    echo.
                    )
                )
           )
        )
    )
  • 设置str1=”中,不要在
    =
    周围使用空格!产品[%counter%]
  • 而不是
    if%counter%GTR 0(
    不起作用并使循环无限)
    如果%counter%==0转到完成,则使用
    ,并在循环后使用
    :完成
    标签
  • 使用引号时,无需将
    x
    添加到比较中
  • 不要忘记64位窗口,也要检查
    Wow6432Node
    tree(参见替代代码)

  • :当
    如果%counter%==0,则转到完成
    设置str1=!产品[%counter%]!
    如果不是“!str1:VNC=!”=“!str1!”(
    ..............................
    rem呼叫!运行卸载!
    )
    设置/a计数器-=1
    去一会儿
    :完成
    

    或者,您可以先在DisplayName中列出带有
    VNC
    的产品,然后获取
    UninstallString
    ,从而使批处理文件更快(如果有许多字符串,“数组”速度较慢):

    @echo关闭
    setlocal enableDelayedExpansion
    对于““%Wow6432Node”中的%%a,请执行以下操作(
    对于/f“delims=”%%b in('
    reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall^
    /s/d/f“VNC”^ findstr“HKEY_uuDisplayName”
    ""做"(
    设置“行=%%b”
    如果“!line:~0,4!”==“HKEY”(
    设置“键=!行!”
    )否则(
    设置卸载=
    rem Sort/r使quietInstallString成为最后一行
    对于/f“令牌=2*”%%c in('
    reg查询“!key!”^|查找“卸载字符串”^|排序/r
    “)如果不是“%%d”==”设置“卸载=%%d”
    如果已定义,请卸载(
    对于(“!line!”)中的/f“tokens=2*”%%c,do echo找到了%%d
    echo正在运行!卸载!(针对测试发表了评论)
    rem呼叫!卸载!
    回响
    )
    )
    )
    )
    暂停
    
    通过修改wOxxOm的代码,我能够创建以下代码来悄悄卸载TightVNC、UltraVNC和RealVNC。它还将启动Windows注册表中
    HKLM\software\Microsoft\Windows\CurrentVersion\Uninstall
    HKLM\software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
    下的
    DisplayName
    中带有“VNC”的任何其他软件的卸载程序

    希望这对其他人也很方便

    @echo off
    setlocal enableDelayedExpansion
    for %%a in ("" "\Wow6432Node") do (
        for /f "delims=" %%b in ('
            reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
                /s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
        ') do (
            set "line=%%b"
            if "!line:~0,4!"=="HKEY" (
                set "key=!line!"
            ) else (
                set Uninstall=
                rem Sort /r makes QuietUninstallString the last line
                for /f "tokens=2*" %%c in ('
                    reg query "!key!" ^| find "UninstallString" ^| sort /r
                ') do if not "%%d"=="" set "Uninstall=%%d"
    
                if defined Uninstall (
    
                    for /f "tokens=2*" %%c in ("!line!") do (
                        set product=%%d
                        if NOT "x!product:TightVNC=!"=="x!product!" (
                            for /f "tokens=2 delims={}" %%A in ("!Uninstall!") do (
                            echo Found !product!
                            CALL msiExec.exe /qn /x{%%A}
                            echo.
                            )
                        ) else (
                            if NOT "x!product:UltraVNC=!"=="x!product!" (
                                for /f "tokens=1 delims=." %%A in ("!Uninstall!") do (
                                    echo Found !product!
                                    CALL %%A.exe" /VERYSILENT /NORESTART
                                    echo.
                                )
                                ) else (
                                    if NOT "x!Uninstall:RealVNC=!"=="x!Uninstall!" (
                                                for /f "tokens=1 delims=." %%A in ("!Uninstall!") do (
                                                echo Found !product!
                                                CALL %%A.exe" /VERYSILENT
                                                echo.
                                            )
                                        ) else (
                                            echo Found %%d
                                            CALL !Uninstall!
                                            echo.
                                    )
                                )
                            )
                        )
                    )
               )
            )
        )
    

    谢谢你,wOxxOm!您的代码更加高效和紧凑。这也是筑巢的一个令人印象深刻的用途。接下来,我将尝试修改代码以创建一个在注册表中没有QuietUninstallString项的TightVNC异常-使用/qn/x msiexec.exe选项。@MattSec,如果您正在谈论替代代码,它更喜欢
    quietInstallString
    ,但在没有前者的情况下将使用
    UninstallString
    。是的,在测试代码时,它也为我这样做了。我希望TightVNC在安静模式下运行,这是使用msiexec.exe选项支持的,但注册表中没有定义QuietInstallString。我编辑了代码以尝试执行此操作,但它不断返回一个错误,说明此时
    else是意外的
    。如果您有兴趣再次帮助我解决问题,我将在原始问题中添加修改后的代码。@MattSec,1)在运行
    之前忘记
    echo
    ,2)不要在
    内的注释中使用未替换的圆括号()
    块:要么用
    ^
    删除它们,要么用
    ^
    删除它们,3)在你发布的代码中没有关闭
    ,希望这只是粘贴时没有选择。我认为缺少括号是粘贴错误。在括号前面加上“^”以转义括号后,代码按预期运行。再次感谢!是否需要使用注册表并调用msiexec?我的意思是,可能更好的方法是使用WMIC命令:即,您可以使用类似于
    WMIC产品的命令,其中“名称类似于“%VNC%”获取名称、版本
    ,以列出名称中包含VNC的已安装软件,然后使用类似于
    WMIC产品的命令,其中“名称类似于“%VNC%”调用uninstall/nointeractive
    卸载应用程序。