Wix 在删除旧包后不安装新的 exe 包

问题描述 投票:0回答:1

我正在尝试卸载 SqlServer 2017 并安装 SqlServer 2022。它正在卸载 SqlServer 2017,但从未安装 2022。请帮忙。

我有一个名为RemoveSql2017.cs的类,如下所示:

 public class RemoveSQL2017
    {
        const string UNINSTALL_SQL_2017 = "/Action=Uninstall /INSTANCENAME=PHARMSPEC /FEATURES=SQL /QS /HIDECONSOLE";
        const string sqlFile = "DetachPharmSpecDB.sql";
        const string DB_INSTANCE = "PHARMSPEC";
        const int COMMAND_LINE_WAIT = 10000;
        private static WixBootstrapper _bootstrapper;
        const string registryKey = @"SOFTWARE\HIAC\PharmSpec\Database";
        const string subKeyValue = "DataPath";

        public RemoveSQL2017(WixBootstrapper bootstrapper)
        {
            _bootstrapper = bootstrapper;
        }

        public void Remove(string bootStrapFolder, string dataFilePath)
        {
            CreateDetachSQLFile();
            CopyFiles(dataFilePath);
            UninstallSQL(bootStrapFolder);
            DeleteDBRegistryPath();
        }
        public static void UninstallSQL(string bootstrapFolder)
        {
            try
            {
                _bootstrapper.Engine.Log(LogLevel.Verbose, "Beginning UninstallSQL; bootstrapFolder=" + bootstrapFolder);
                Process process = new Process();
                ProcessStartInfo startInfo = new ProcessStartInfo(bootstrapFolder + "//SQL2017//setup.exe", UNINSTALL_SQL_2017);
                process.StartInfo = startInfo;
                process.Start();
                process.WaitForExit();
                _bootstrapper.Engine.Log(LogLevel.Verbose, "Completing UninstallSQL; bootstrapFolder=" + bootstrapFolder);
            }
            catch (Exception e)
            {
                _bootstrapper.Engine.Log(LogLevel.Verbose, "Error in UninstallSQL:\n " + e.ToString());
                throw (e);
            }
        }
        public static void CopyFiles(string dataFilePath)
        {
            try
            {
                _bootstrapper.Engine.Log(LogLevel.Verbose, "Beginning CopyFiles; dataFilePath=" + dataFilePath + "  tempDBFilePath=" + Globals.tempDBFilePath);
                File.Copy(Path.Combine(dataFilePath, Globals.MDF_FILE), Path.Combine(Globals.tempDBFilePath, Globals.MDF_FILE));
                File.Copy(Path.Combine(dataFilePath, Globals.LDF_FILE), Path.Combine(Globals.tempDBFilePath, Globals.LDF_FILE));
                _bootstrapper.Engine.Log(LogLevel.Verbose, "Completing CopyFiles; dataFilePath=" + dataFilePath + "  tempDBFilePath=" + Globals.tempDBFilePath);
            }
            catch (Exception e)
            {
                _bootstrapper.Engine.Log(LogLevel.Verbose, "Error in CopyFiles:\n " + e.ToString());
            }
        }
        public static void DetachDB(string sqlFilePath)
        {
            try
            {
                _bootstrapper.Engine.Log(LogLevel.Verbose, "Beginning DetachDB; sqlFilePath=" + sqlFilePath);
                string command = string.Format("-S .\\{0} -E -i \"{1}\"", DB_INSTANCE, sqlFilePath);
                ProcessStartInfo info = new ProcessStartInfo("sqlcmd", command);
                info.UseShellExecute = false;
                info.CreateNoWindow = false;
                info.WindowStyle = ProcessWindowStyle.Hidden;
                Process proc = new Process();
                proc.StartInfo = info;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.Start();
                string outputD = proc.StandardOutput.ReadToEnd();
                if (proc.WaitForExit(COMMAND_LINE_WAIT))
                {
                    _bootstrapper.Engine.Log(LogLevel.Verbose, outputD);
                }
                else
                {
                    _bootstrapper.Engine.Log(LogLevel.Verbose, "Process timeout in DetachDb");
                }
                _bootstrapper.Engine.Log(LogLevel.Verbose, "Completing DetachDB; sqlFilePath=" + sqlFilePath);
            }
            catch (Exception e)
            {
                _bootstrapper.Engine.Log(LogLevel.Verbose, "Error in DetachDB:\n " + e.ToString());
                throw (e);
            }
        }
        public static void CreateDetachSQLFile()
        {
            try
            {
                string sqlFilePath = Path.Combine(Path.GetTempPath(), sqlFile);
                var sqlScript = new StringBuilder();
                sqlScript.AppendLine("GO");
                sqlScript.AppendLine("IF EXISTS (SELECT * FROM sysdatabases WHERE name = N'PharmSpecDB')");
                sqlScript.AppendLine("use PharmSpecDB");
                sqlScript.AppendLine("DROP SCHEMA PharmSpecUsr");
                sqlScript.AppendLine("DROP USER PharmSpecUsr");
                sqlScript.AppendLine("use master");
                sqlScript.AppendLine("EXEC sp_detach_db 'PharmSpecDB'");
                sqlScript.AppendLine("GO");
                sqlScript.AppendLine("IF EXISTS (SELECT * FROM syslogins WHERE name = N'PharmSpecUsr')");
                sqlScript.AppendLine("DROP LOGIN PharmSpecUsr");
                sqlScript.AppendLine("GO");
                using (StreamWriter sw = new StreamWriter(sqlFilePath))
                {
                    sw.Write(sqlScript.ToString());
                }
                DetachDB(sqlFilePath);
            }
            catch (Exception e)
            {
                _bootstrapper.Engine.Log(LogLevel.Verbose, "error in CreateDetachSQLFile:\n " + e.ToString());
                throw (e);
            }
        }

        public static void DeleteDBRegistryPath()
        {
            try
            {
                using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
                {
                    RegistryKey subkey = key.OpenSubKey(registryKey, true);
                    if (subkey != null)
                    {
                        subkey.DeleteValue(subKeyValue);
                    }           
                }
            }
            catch (Exception e)
            {
                _bootstrapper.Engine.Log(LogLevel.Verbose, "error in DeleteDBRegistryPath:\n" + e.ToString());
            }
        }

我按如下方式调用此类:我能够看到 SqlServer 2017 被卸载。

 if (Bootstrapper.Engine.StringVariables["PreviousVersion"].CompareTo("3.5.99") <= 0 &&
               Bootstrapper.Engine.StringVariables["SqlInstanceKeyFound64"] == "1")
                {
                    RemoveSQL2017 removeSQL = new RemoveSQL2017(Bootstrapper);
                    removeSQL.Remove(Bootstrapper.Engine.StringVariables["DB2017SETUP"], Bootstrapper.Engine.StringVariables["2017DBDataPath"]);
                    Bootstrapper.Engine.StringVariables["OLDDBDATAPATH"] = Globals.tempDBFilePath;
                    Bootstrapper.Engine.StringVariables["INSTALLSQL"] = "1";
                }

我有一个SqlServer.wxi,其中注册表项和exe文件如下。在删除 SqlServer2017 之前,这是注册表中的内容,

Registry

SqlServer.wxi

<Variable Name="SqlInstanceKeyFound" Value="0"/>
        <Variable Name="SqlInstanceKeyFound64" Value="0"/>
<util:RegistrySearch
          Id="SqlInstanceKeyFound64"
          Root="HKLM" Key="SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" Value="PHARMSPEC"
          Result="exists" Variable="SqlInstanceKeyFound64" Win64="yes"/>
        <util:RegistrySearch
          Id="SqlInstanceKey64"
          Root="HKLM" Key="SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" Value="PHARMSPEC"
          Variable="SqlInstanceKey64" After="SqlInstanceKeyFound64" Condition="SqlInstanceKeyFound64" Win64="yes" />
        <util:RegistrySearch
          Id="SqlInstanceFound64"
          Root="HKLM" Key="SOFTWARE\Microsoft\Microsoft SQL Server\[SqlInstanceKey64]"
          Result="exists" Variable="SqlInstanceFound64" After="SqlInstanceKey64" Condition="SqlInstanceKeyFound64" Win64="yes" />
        <util:RegistrySearch
          Id="SqlVersion64"
          Root="HKLM" Key="SOFTWARE\Microsoft\Microsoft SQL Server\[SqlInstanceKey64]\Setup" Value="Version"
          Variable="SqlVersion64" After="SqlInstanceKey64" Condition="SqlInstanceFound64" Win64="yes" />

 <PackageGroup Id="SQL2022Express">
      <ExePackage Id="SQL2022Express"
              DisplayName="SQL Server 2022 Express"
              Cache="yes"
              Compressed="no"
              PerMachine="yes"
              Permanent="no"
              Vital="yes"
              DetectCondition="SqlInstanceFound64"
              InstallCondition="INSTALLSQL=1"
              Name="Redist\SQLEXPR_x64_!(loc.LANG).exe"
              SourceFile="$(var.DependencyFolder)\SQLEXPR_x64_!(loc.LANG).exe"
              InstallCommand="/ACTION=Install /IACCEPTSQLSERVERLICENSETERMS [SQLQUIET] /HIDECONSOLE /FEATURES=SQLEngine /UpdateEnabled=0 /INSTANCENAME=PHARMSPEC /SQLSYSADMINACCOUNTS=Builtin\Administrators /SQLSVCACCOUNT=&quot;NT AUTHORITY\NETWORK SERVICE&quot; /SECURITYMODE=SQL /SAPWD=[SAPASSWORD] /NPENABLED=1 /TCPENABLED=1 /SKIPRULES=RebootRequiredCheck"
              UninstallCommand="/Action=Uninstall /INSTANCENAME=PHARMSPEC /FEATURES=SQL /QS /HIDECONSOLE">
        <ExitCode Value ="3010" Behavior="forceReboot" />
      </ExePackage>
    </PackageGroup>

在日志中显示以下内容:

  • [0EE8:0EEC][2024-11-08T14:09:13]i000:设置数字变量 “SqlInstanceFound64”值为 1
  • [0EE8:0EEC][2024-11-08T14:09:13]i052:条件“SqlInstanceFound”的计算结果为 false。
  • [0EE8:0EEC][2024-11-08T14:09:13]i052:条件“SqlInstanceFound64”计算结果为 true。
  • [0EE8:0EEC][2024-11-08T14:09:13]i000:将字符串变量“SqlVersion64”设置为值 ‘14.0.1000.169’
  • [0EE8:0EEC][2024-11-08T14:09:13]i101:检测到的包:SQL2022Express,状态:存在, 缓存:无
  • [0EE8:0EEC][2024-11-08T14:09:29]i052:条件“INSTALLSQL=1”的计算结果为 true。
  • [0EE8:0EEC][2024-11-08T14:09:29]w321:跳过包上的依赖项注册 没有依赖项提供程序:SQL2022Express
  • [0EE8:0EEC][2024-11-08T14:09:29]i052:条件“INSTALLSQL=0”的计算结果为 false。
wix exe upgrade uninstallation bootstrapper
1个回答
0
投票
找到了

SqlInstanceFound64
变量,该变量在您的 DetectCondition 中用于指示 SQL Express 2022 已安装。捆绑包不会安装已经存在的东西。

我认为您需要搜索 SQL Express 2022 特有的注册表项(或其他内容)。您现在看到的内容似乎是由许多版本的 SQL Express 设置的。

© www.soinside.com 2019 - 2024. All rights reserved.