Community Forums
Page 1 of 6 123 ... LastLast
Results 1 to 5 of 29

Thread: Local cached MSI does not get deleted when uninstalling

  1. #1
    Join Date
    Jan 2008
    Posts
    92

    Local cached MSI does not get deleted when uninstalling

    I have an InstallScript MSI Project. I activated the "Cache MSI locally" and indicated the "Cache Path" to "[LocalAppDataFolder]Downloaded Installations".

    I had a look today into this cache path folder and was really surprised to find a list of folder, not only from the actual installed versions, but also uninstalled versions.

    Does IS2008 not delete the cached MSI files when uninstalling a version?

    How do I get IS2008 to delete the cached MSI files during uninstall?

  2. #2
    Join Date
    Mar 2004
    Location
    Lincoln, NE
    Posts
    128

    Cached MSI

    It has always been true that cached msi's are left on the target machine. Years ago, we added script to all of our product deployments to clean up msi cache. The script looks at the cache and removes all but the latest one. Recently, when the path for cached msi's changed to [LocalAppDataPath], we adjusted our scirpt to compensate. If you have questions about how to do this, let me know and I will be glad to help.
    Randy Dugger

  3. #3
    Join Date
    Jul 2003
    Location
    Austin, TX
    Posts
    4,438
    Would you be willing to share that code? I started writing such a script last night but I'm interested to see how others are doing it to see if there are any aspects that I'm missing.
    Christopher Painter
    ISWIX, LLC.
    Visit iswix.com for contact information

  4. #4
    Join Date
    Jan 2008
    Posts
    92
    Quote Originally Posted by ITI_Randy View Post
    It has always been true that cached msi's are left on the target machine. Years ago, we added script to all of our product deployments to clean up msi cache. The script looks at the cache and removes all but the latest one. Recently, when the path for cached msi's changed to [LocalAppDataPath], we adjusted our scirpt to compensate. If you have questions about how to do this, let me know and I will be glad to help.
    Yes, I would be interested in that script. Are you willing to share this code with us?

  5. #5
    Join Date
    Mar 2004
    Location
    Lincoln, NE
    Posts
    128

    Cleaning Msi Cache

    For those who have requested this, I am more than happy to share this code to clean the msi cache on target machines. The example below is for basic msi setups, but can easily be adapted for other project types.

    The process involves the following basic steps:

    1. Rename the Release cache location:

    Since msi's are cached under a GUID-named folder, typically in "Downloaded Installations", it is necessary to rename the release cache folder so that it can be easily located. So for instance, my setup by default may cache to a folder named "C:\Documents and Settings\MyLoginID\Local Settings\Application Data\Downloaded Installations\{2BCC2647-316E-4230-89DF-187395E8EEC5}". My problem will be that the cache for all installations will fall under "Downloaded Installations" in an ambiguous GUID-named folder.

    To remedy this, go to Media > Releases in the InstallShield IDE and reset the "Cache path" under setup.exe properties to be more specific. Instead of just "[LocalAppDataFolder]Downloaded Installations", set the path to be "[LocalAppDataFolder]Downloaded Installations\APS1724\MyProgramName". "MyProgramName" is typically the title of your setup that you have in the General Information section of your InstallShield IDE.

    Now the GUID-named folders for each particular installation will all fall under the folder for "MyProgramName". This simplifies the process much as you now only have to worry about deleting all but the newest one found in the folder.

    2. Write the script to clean up the msi cache. Here is a simple example that pulls the title of the package, assuming that the cache folder name was the package title as mentioned above, and loops through the folder to remove all but the newest GUID-named cache folder found.

    export prototype CleanMsiCache(HWND);

    function CleanMsiCache(hMSI)
    HWND hStream;
    STRING sParent, sTitle[39];
    NUMBER nDataType, nData, nValueBuf;
    POINTER ptrFile;
    begin
    try
    //get the title of this package
    MsiGetSummaryInformation (hMSI, "", 0, hStream);
    nValueBuf = SizeOf(sTitle);
    MsiSummaryInfoGetProperty (hStream, 2, nDataType, nData, ptrFile, sTitle, nValueBuf);
    MsiCloseHandle(hStream);

    //cleaning can only be done if setup name is found
    if (StrLength(sTitle) > 0) then
    //purge all but the newest folder in the current cache
    sParent = LocalAppDataFolder ^ "Downloaded Installations" ^ sTitle;

    if (Is(PATH_EXISTS, sParent) = 1) then
    CleanExtraReleaseFolders(hMSI, sParent);
    endif;
    endif;
    catch
    endcatch;
    end;

    prototype CleanExtraReleaseFolders(HWND, STRING);

    function CleanExtraReleaseFolders(hMSI, sTargetFolder)
    LIST lstDirs;
    STRING sValue, sFileName, sCheck, sNewest, sNewestFolder;
    STRING sSearchPath, sErrMsg;
    NUMBER nResult, nResult2, nDataType, nData, nValueBuf;
    VARIANT vErrNum;
    begin
    try
    //check for any residual cache and clean up all but the newest one
    lstDirs = ListCreate (STRINGLIST);

    //Get all sub folders in the target folder (these will have a GUID name)
    nResult = FindAllDirs (sTargetFolder, EXCLUDE_SUBDIR, lstDirs);
    if (nResult = 0) then
    nResult = ListGetFirstString (lstDirs, sValue);
    while (nResult != END_OF_LIST)
    //get the file name in the folder
    nResult2 = FindAllFiles (sValue, "*.*", sFileName, RESET);
    // Get the time the file was last updated
    if (nResult2 = 0) then
    //file was found in the folder for comparrison
    if (sNewest = "") then
    sNewest = sFileName; //save the filename
    sNewestFolder = sValue; //save the folder name
    else
    nResult = FileCompare (sFileName, sNewest, COMPARE_DATE);
    if nResult = GREATER_THAN then
    sNewest = sFileName; //save the filename

    sNewestFolder = sValue; //save the folder name
    endif;
    endif;
    else
    //no files in the folder, so delete it
    DeleteDir(sValue, ROOT);
    endif;
    nResult = ListGetNextString (lstDirs, sValue);
    endwhile;
    endif;

    /*Loop back through and deleate all but the Newest file.
    If a newer file was not located, then cleanup is invalid
    because there is nothing to base a comparrision on for cleaning.*/
    if (StrLength(sNewestFolder) > 0) then
    nResult = ListGetFirstString (lstDirs, sValue);
    while (nResult != END_OF_LIST)
    if (StrCompare(sValue, sNewestFolder) != 0) then
    StrRemoveLastSlash(sValue);
    //verify it is a msi cache GUID directory
    StrSub(sCheck, sValue, StrLength(sValue) - 1, 1);
    if (StrCompare(sCheck, "}") = 0) then
    DeleteDir(sValue, ALLCONTENTS);
    DeleteDir(sValue, ROOT);
    endif;
    endif;
    nResult = ListGetNextString (lstDirs, sValue);
    endwhile;
    endif;
    catch
    endcatch;
    end;


    3. Schedule the custom action to do the cleaning.

    Place the custom action in the Execute Sequence after Install Finalize. This will allow the current installation to complete and cache before cleaning is done. Set the condition on the CA to be "REMOVE <> "ALL"".

    --------------------------------

    You can generically add this script to all install packages and it will always clean all but the latest msi cache. Remember, it is important to leave the latest one cached on the target machine.

    An important consideration here is that the location of the msi cache changed with the introduction of Vista/Server 2008. It used to be in the [WindowsFolder]\Downloaded Installations. It is now, as I mentioned above, by default, in the [LocalAppDataPath]Downloaded Installations folder. This was done to follow the new security protocol by Microsoft, where messing with the WindowsFolder is becoming considered a "no-no". This affected our considerations for cache cleanup, as we used to have a script that cleaned the [WindowsFolder] location. I therefore wrote a somewhat more involved script which check to see where the msi was last cached (as it could have been at [WindowsFolder]) and also check the current cache, still removing all but the newest one. For those who are concerned about cleaning the past cache location that may be out there one the target machine, I would be happy to give you that extended script.
    Randy Dugger

Page 1 of 6 123 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •