Search code examples
upgradewixsharp

Wixsharp upgrade is not retaining previous settings like DB data and other configurations


I'm using wixsharp to build my installer. Everytime I give a new build I want to update all my exe, dlls and other binaries but I want to retain manually changed settings like we have an option to store some keys in database that will create some folders inside application folder in program files. I want to retain this data and to replace binaries but when I upgrade it is deleting this data as well.

I'm using below wixsharp code to implement upgrade.

project.UpgradeCode= new Guid("some GUID here, keeping it same in all builds");
project.ProductId = new Guid("GUID here, changing it in all incremental build");
project.Version = new Version(6, 1, 1, 1); // upgrading it in incremental builds
            project.MajorUpgrade = new MajorUpgrade
            {
                Schedule = UpgradeSchedule.afterInstallValidate,
                AllowSameVersionUpgrades = true,
                MigrateFeatures =true,
                IgnoreRemoveFailure=true,
                DowngradeErrorMessage="A new version of this product is already installed."
            };

One more issue with this I'm facing is when we are installing 2nd build it is not showing the upgrade option but showing install option only (like fresh installation) and at last it is asking user's permission to uninstall the product, that is uninstalling old product it seems but it doesn't look user friendly as user might feel why he/she is uninstalling the product. I just want an upgrade option that can do the upgrade without showing user what is going in backend.


Solution

  • Question 1:

    If you want to have some static files which ones adds if not exist but not update them with new one installation. You need to mark them with Permanent="yes" NeverOverwrite="yes" attributes.

    For more information link here: Wix Component Element

    How to make it with WixSharp?

    Here is my code how to make index.html and web.config immutable:

            var immutableFiles = 
            {
                @"index.html",
                @"web.config"
            };
    // ....
            var wixObjects = new WixObject[]
            {
                new Dir(
                    @"%ProgramFiles%\YourProductFolderName\",
                    WixFilesBuilderUtils.BuildDirectoryInfo(BinariesRoot, immutableFiles)),
                // Properties etc...
            }.ToArray();
    
            var project = new ManagedProject("name",  wixObjects);
    

    Builder code:

     public class WixFilesBuilderUtils
    {
        public static WixEntity[] BuildDirectoryInfo(string currentRoot, IEnumerable<string> immutableFiles)
        {
            var result = new List<WixEntity>();
            var currentRootDictionaryInfo = new DirectoryInfo(currentRoot);
            var localImmutableFiles = immutableFiles.Select(fileName => fileName.ToLower()).ToArray();
    
            var currentRootDirList = currentRootDictionaryInfo
                .GetDirectories()
                .Select(dirInfoSub => dirInfoSub.FullName).ToArray();
    
            result.AddRange(
                Directory.GetFiles(currentRootDictionaryInfo.FullName)
                    .Select(
                        filePath => new WixSharp.File(filePath)
                        {
                            Attributes = MarkFileAsPersonal(filePath, localImmutableFiles)
                        })
                    .Cast<WixEntity>());
    
            if (currentRootDirList.Any())
            {
                var subDirs = currentRootDirList
                    .Select(dirPath => new DirectoryInfo(dirPath))
                    .Select(
                        rootSubDirInfo =>
                            new Dir(rootSubDirInfo.Name,
                                BuildDirectoryInfo(rootSubDirInfo.FullName, localImmutableFiles)))
                    .Cast<WixEntity>();
    
                result.AddRange(subDirs);
            }
    
            return result.ToArray();
        }
    
        private static Dictionary<string, string> MarkFileAsPersonal(string path, IEnumerable<string> immutableFiles)
        {
            return immutableFiles.Any(path.ToLower().EndsWith)
                       ? new Dictionary<string, string>
                           {
                               { "Component:Permanent", "yes" },
                               { "Component:NeverOverwrite", "yes" }
                           }
                       : new Dictionary<string, string>();
        }
    }
    

    Question 2:

    Please try to have same UpdateCode and ProductCode GUIDs each one build and this one strategy:

    MajorUpgradeStrategy = new MajorUpgradeStrategy
                {
                    RemoveExistingProductAfter = Step.InstallInitialize,
                    UpgradeVersions = VersionRange.OlderThanThis,
                    PreventDowngradingVersions = VersionRange.NewerThanThis,
                    NewerProductInstalledErrorMessage = "."
                };