Search code examples
c#dynamicdllinstallshielddynamic-linking

InstallShield Dynamic File Linking can't overwrite


I'm working on an InstallShield project and want to implement dynamic file linking to some files so that they always replace the older ones when being installed. The "always overwrite" option is not available while dynamic linking, and I can't find it in InstallShield. This still doesn't work even after I tried to integrate it in the setup.rul using a c# dll.

This is the c# dll that creates a dll called "OverwriteProfilesFiles.dll" and this dll is declared as a SetupFile of InstallShield and moved to "supportDirPath" when I'm installing it:

namespace MoveProfilesFilesOverwriting
{
    [ComVisible(true)]
    public class MoveFiles
    {

        [ComVisible(true)]
        public bool MoveProfilesFiles()
        {
            try
            {
                var source = @"..\FilesCommon\Profiles";
                var dest = @"C:\ProgramData\ProgramName\Profiles\PersistentData\Setup\Definitions";
                CopyFilesRecursively(source, dest);

                return true;
            }
            catch
            {
                return false;
            }
        }
        private static void CopyFilesRecursively(string sourcePath, string targetPath)
        {
            //Now Create all of the directories
            foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
            {
                Directory.CreateDirectory(dirPath.Replace(sourcePath, targetPath));
            }

            //Copy all the files & Replaces any files with the same name
            foreach (string newPath in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories))
            {
                File.Copy(newPath, newPath.Replace(sourcePath, targetPath), true);
            }
        }
    }
}

And this is the setup.rul function:

// *****************************************************************
// Move Profiles Files
// *****************************************************************
function MoveProfilesFiles(hMSI)
    STRING sDLL, szClassName, supportDirPath, returnValue, installerFileName;
    STRING subStr;
    BOOL callValue;
    INT nLength;
    OBJECT oInstHelp;
begin
    nLength = 256;
    MsiGetProperty(hMSI, "SUPPORTDIR", supportDirPath, nLength);

        sDLL = supportDirPath ^ "OverwriteProfilesFiles.dll";
        szClassName = "MoveProfilesFilesOverwriting.MoveFiles";
        try
            set oInstHelp = DotNetCoCreateObject(sDLL, szClassName, "");
        catch
            SprintfBox (INFORMATION, "Error","Error while loading OverwriteHCCUFiles.dll: %i\n\n%s\n\n%s", Err.Number, Err.Description, Err.LastDllError);
        endcatch;
        try
            callValue = oInstHelp.MoveProfilesFiles();
        catch
            SprintfBox (INFORMATION, "Error","Error : %i\n\n%s\n\n%s", Err.Number, Err.Description, Err.LastDllError);
        endcatch;
    
end;

There are no errors when I try to install the.exe file, however the files aren't copied to the folder. Any suggestions on how to make this function better or another approach to use dynamic file linking with the always overwrite option are welcome.


Solution

  • This is the limitation when you use dynamic file linking. Refer this - https://docs.revenera.com/installshield21helplib/helplibrary/DFL-Limitations.htm#organizingfiles_2971526177_1186025

    When you use "Always Overwrite" feature for static files, Installshield puts highest version(65535.0.0.0) so that it always replaces files on target system using file versioning rules.

    So, In order to achieve same behavior in dynamic link settings, you need to modify .msi file using vbscript/powershell to update version column in File table externally(Build system or manually). After this, you can digitally sign the .msi file. That's it.

    Handling this through separate copy operations(as per above setup.rul function) will complicate the future upgrades/patching. This should be avoided.