使用 C# 静默卸载 InstallShield Installscript MSI 程序
Uninstalling an InstallShield Installscript MSI program using C# silently
这将非常特定于 InstallShield,因此我怀疑之前是否有人处理过此问题,但我编写了一个批处理文件来卸载我们产品的先前版本,但它不起作用。 (我们总是在 install/upgrade 之前卸载以前的版本,因为 InstallShield 中的升级似乎不起作用)。卸载 Installscript MSI 项目与典型的卸载有很大不同,因为您需要 "record" 卸载并将结果存储在文件中,即:
setup.exe /x /r /f1"C:\temp\UNINST.ISS"
这会将卸载映像存储在 c:\temp\UNINST.ISS 中,然后您需要将其传递给卸载程序以获取要卸载的产品:
setup.exe /s /f1"UNINST.ISS"
所以我对我们产品的所有先前版本都这样做了,然后编写了一个批处理脚本(产品代码为 {7F2A0A82-BB08-4062-85F8-F21BFC3F3708} 来执行如下所示的卸载:
echo Uninstalling 5.3.0
pause
if exist "C:\Program Files (x86)\InstallShield Installation Information\ {7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup.exe" (
del /q "C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe"
copy /y "C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup.exe" "C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe"
cls
echo Uninstalling 5.3.0
"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe" /s /f1".\Uninstall response files.3.0\UNINST-5.3.0.ISS"
:wait1
timeout /t 3 /NOBREAK > nul
tasklist | find /i "Setup-5.3.0.exe" >nul 2>nul
if not errorlevel 1 goto wait1
)
echo Uninstalling 5.3.1...
问题是它不起作用。如果我从提升的 CMD window 执行卸载,它工作正常:
"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe" /s /f1".\Uninstall response files.3.0\UNINST-5.3.0.ISS"
但是当我执行批处理脚本时,它似乎只是通过卸载而没有做任何事情。所以我想我会尝试编写一个简单的 C# 程序来执行此操作,但这也不起作用:
Console.Clear();
Console.WriteLine("Uninstalling 5.3.0");
if (File.Exists(@"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup.exe"))
{
File.Copy(@"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup.exe", @"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe", true);
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = @"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe";
Directory.SetCurrentDirectory(@"..\..\..\");
startInfo.Arguments = "/s / f1\".\Uninstall response files\5.3.0\UNINST-5.3.0.ISS\"";
startInfo.UseShellExecute = false;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
using (Process process = new Process())
{
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
}
}
我试过调试它并确认当前目录是正确的(使用 Directory.GetCurrentDirectory()
),但我得到这个错误:
process.StandardError' threw an exception of type 'System.InvalidOperationException' System.IO.StreamReader {System.InvalidOperationException}
此 PDF 底部还有一些进一步的说明:https://resources.flexera.com/web/pdf/archive/silent_installs.pdf
setup.exe /s /f1"C:\sample\uninstall.iss" /f2"C:\sample\uninstall.log"
您是否手动尝试过 /f1
和 /f2
参数的完整路径?
我正在积极尝试忘记如何编写批处理文件,但我认为您可以通过以下方式获取批处理文件 运行 所在的文件夹:
set here=%~dp0
cd %here%
更改 setup.exe 文件名会导致问题吗?也许您可以尝试不更改 setup.exe 的名称,看看是否完成?
可以通过 /c 参数将命令传递给 cmd.exe
吗? ("执行字符串指定的命令然后终止"):
cmd.exe /c "%here%\setup.exe /s /f1"C:\sample\uninstall.iss" /f2"C:\sample\uninstall.log""
也许可以尝试添加 /SMS switch 以确保 setup.exe 不会在实际卸载完成之前过早退出。正如谣言所说,这个 /SMS 开关对于后期的 Installshield setup.exe 是不需要的,但它是旧版本所需要的。
正如 Gravity 指出的那样,问题是 / 和 f1 之间的 space。它是在剪切和粘贴过程中以某种方式添加的。
这将非常特定于 InstallShield,因此我怀疑之前是否有人处理过此问题,但我编写了一个批处理文件来卸载我们产品的先前版本,但它不起作用。 (我们总是在 install/upgrade 之前卸载以前的版本,因为 InstallShield 中的升级似乎不起作用)。卸载 Installscript MSI 项目与典型的卸载有很大不同,因为您需要 "record" 卸载并将结果存储在文件中,即:
setup.exe /x /r /f1"C:\temp\UNINST.ISS"
这会将卸载映像存储在 c:\temp\UNINST.ISS 中,然后您需要将其传递给卸载程序以获取要卸载的产品:
setup.exe /s /f1"UNINST.ISS"
所以我对我们产品的所有先前版本都这样做了,然后编写了一个批处理脚本(产品代码为 {7F2A0A82-BB08-4062-85F8-F21BFC3F3708} 来执行如下所示的卸载:
echo Uninstalling 5.3.0
pause
if exist "C:\Program Files (x86)\InstallShield Installation Information\ {7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup.exe" (
del /q "C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe"
copy /y "C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup.exe" "C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe"
cls
echo Uninstalling 5.3.0
"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe" /s /f1".\Uninstall response files.3.0\UNINST-5.3.0.ISS"
:wait1
timeout /t 3 /NOBREAK > nul
tasklist | find /i "Setup-5.3.0.exe" >nul 2>nul
if not errorlevel 1 goto wait1
)
echo Uninstalling 5.3.1...
问题是它不起作用。如果我从提升的 CMD window 执行卸载,它工作正常:
"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe" /s /f1".\Uninstall response files.3.0\UNINST-5.3.0.ISS"
但是当我执行批处理脚本时,它似乎只是通过卸载而没有做任何事情。所以我想我会尝试编写一个简单的 C# 程序来执行此操作,但这也不起作用:
Console.Clear();
Console.WriteLine("Uninstalling 5.3.0");
if (File.Exists(@"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup.exe"))
{
File.Copy(@"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup.exe", @"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe", true);
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = @"C:\Program Files (x86)\InstallShield Installation Information\{7F2A0A82-BB08-4062-85F8-F21BFC3F3708}\setup-5.3.0.exe";
Directory.SetCurrentDirectory(@"..\..\..\");
startInfo.Arguments = "/s / f1\".\Uninstall response files\5.3.0\UNINST-5.3.0.ISS\"";
startInfo.UseShellExecute = false;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
using (Process process = new Process())
{
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
}
}
我试过调试它并确认当前目录是正确的(使用 Directory.GetCurrentDirectory()
),但我得到这个错误:
process.StandardError' threw an exception of type 'System.InvalidOperationException' System.IO.StreamReader {System.InvalidOperationException}
此 PDF 底部还有一些进一步的说明:https://resources.flexera.com/web/pdf/archive/silent_installs.pdf
setup.exe /s /f1"C:\sample\uninstall.iss" /f2"C:\sample\uninstall.log"
您是否手动尝试过 /f1
和 /f2
参数的完整路径?
我正在积极尝试忘记如何编写批处理文件,但我认为您可以通过以下方式获取批处理文件 运行 所在的文件夹:
set here=%~dp0
cd %here%
更改 setup.exe 文件名会导致问题吗?也许您可以尝试不更改 setup.exe 的名称,看看是否完成?
可以通过 /c 参数将命令传递给 cmd.exe
吗? ("执行字符串指定的命令然后终止"):
cmd.exe /c "%here%\setup.exe /s /f1"C:\sample\uninstall.iss" /f2"C:\sample\uninstall.log""
也许可以尝试添加 /SMS switch 以确保 setup.exe 不会在实际卸载完成之前过早退出。正如谣言所说,这个 /SMS 开关对于后期的 Installshield setup.exe 是不需要的,但它是旧版本所需要的。
正如 Gravity 指出的那样,问题是 / 和 f1 之间的 space。它是在剪切和粘贴过程中以某种方式添加的。