Announcement

Collapse
No announcement yet.

Uninstall Needing Reboot

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Ulrich
    replied
    Is the option to suppress the "in use" notice checked for the controls, or the folder reference, if you use one to add these controls to the installer? If it is not, please use this and rebuild the installer, then try again.

    Click image for larger version

Name:	SCRN-2021-03-02-01.png
Views:	60
Size:	21.5 KB
ID:	306270

    Ulrich

    Leave a comment:


  • ScottWirt
    replied
    Can we expect this to be fixed in a Setup Factory update so it is clear that files were marked for delete on reboot without having to review this registry key?

    Leave a comment:


  • Ulrich
    replied
    Assuming that the number of controls is not too big and the file names are known, you can modify this code with the String.Find() and check just for the files known to give you issues.

    Ulrich

    Leave a comment:


  • ScottWirt
    replied
    Thank you. I'm not sure this will help though, because the files causing the issue are all shared third-party components that are in the windows system32 folder. I thought of maybe grabbing the contents of that pending operations registry key before and after the uninstaller is run and see if there has been any change to it, but to be accurate, it would have to pick out just the new entries and see if any of them are file (not folder) operations. It seems to always add a few folder removals too, but they don't actually hurt anything because those folders are not empty.

    Leave a comment:


  • Ulrich
    replied
    Okay, so this does not work. But here is something what could help. Once you have the target folder defined (here I assume that it is stored in %AppFolder%), you can check if there is a pending file rename/delete operation for this location. If there is something, you could stop the setup before the new files are deployed. Here is some code I put together:

    Code:
    -- Some helper functions
    
    function Registry.DoesValueExist(MainKey, SubKey, Value)
       local bFound = false;
       if Registry.DoesKeyExist(MainKey, SubKey) then
          local tblValues = Registry.GetValueNames(MainKey, SubKey);
          if (tblValues ~= nil) then
             for index, sValueName in pairs(tblValues) do
                if (String.Compare(sValueName, Value) == 0) then
                   bFound = true;
                   break;
                end
             end
          end
       end
       return bFound;
    end
    
    function DelimitedStringToTable(DelimitedString, Delimiter)
       tbReturn = {};
       local strWorking;
       local nPos = nil;
       local strData;
       local nTableIndex = 1;
       local nDelimiterLength = String.Length(Delimiter);
    
       if (nDelimiterLength < 1) then
          tbReturn[nTableIndex] = DelimitedString;
          return tbReturn;
       end
    
       strWorking = DelimitedString;
       nPos = String.Find(strWorking,Delimiter);
       while (nPos ~= -1) do
          strData = String.Left(strWorking,nPos-1);
          tbReturn[nTableIndex] = strData;
          nTableIndex = nTableIndex + 1;
          local nLength = String.Length(strWorking);
          strWorking = String.Right(strWorking,nLength - (nPos + (nDelimiterLength-1)));
          nPos = String.Find(strWorking,Delimiter);
       end
    
       if (strWorking ~= "") then
          tbReturn[nTableIndex] = strWorking;
       end
    
       return tbReturn;
    end
    
    -- Check if there is a pending deletion or rename operation
    
    local bPendingFileOperation = false;
    
    if Registry.DoesValueExist(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager", "PendingFileRenameOperations") then
       local sData = Registry.GetValue(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager", "PendingFileRenameOperations", true);
       if (#sData > 0) then
          local tData = DelimitedStringToTable(sData, "|");
          for i = 1, #tData do
             if tData[i] ~= nil then
                if String.Find(tData[i], SessionVar.Expand("%AppFolder%"), 5, false) ~= -1 then
                   bPendingFileOperation = true;
                   break;
                end
             end
          end
       end
    end
    
    if bPendingFileOperation then
       Dialog.Message("Warning", SessionVar.Expand("There is a pending file operation (deletion) scheduled for %AppFolder%.\r\nPlease restart the device before installing this product."), MB_OK, MB_ICONSTOP);
    end
    Ulrich

    Leave a comment:


  • ScottWirt
    replied
    I did check that and it appears to return 0. I also checked the _NeedsReboot flag and added an Info line to show the status of that. This is some of what I see in the log file:

    [03/01/2021 16:02:24] Success Unregister COM file: C:\Windows\system32\ActBar2.ocx
    [03/01/2021 16:02:24] Success Remove file on reboot: C:\Windows\system32\ActBar2.ocx
    [03/01/2021 16:02:27] Success Unregister COM file: C:\Windows\system32\VSFlex7.ocx
    [03/01/2021 16:02:27] Success Remove file on reboot: C:\Windows\system32\VSFlex7.ocx
    [03/01/2021 16:02:30] Info Restart NOT needed
    [03/01/2021 16:02:30] Success Run uninstall event: On Shutdown
    [03/01/2021 16:02:30] Notice Exit uninstall process (Return code: 0)

    Leave a comment:


  • Ulrich
    replied
    Have you checked the exit code of the uninstaller? From the documentation, it could be that it returns 500 - "One or more files could not be removed by the uninstall program". I have not tested this here, but if the exit code of the uninstaller is working as the documentation suggests, you could stop the installer right there, schedule it to run automatically at the restart, and ask the user to confirm the reboot...

    Ulrich

    Leave a comment:


  • ScottWirt
    started a topic Uninstall Needing Reboot

    Uninstall Needing Reboot

    I have my installer set to run the uninstaller in silent mode first, if available, and that works fine. However, I have found a case where a problem can result. If a component is in use when you go to install an update, it seems that uninstaller in silent mode does not set _NeedsReboot or anything that I can identify to indicate that it has set a file for deletion on restart. After the uninstall completes and the installer goes to install new files, it will pop a warning that the file is in use and you can close some other app and click retry and then it works. However, that file has already been marked for deletion on reboot before this point, so after the installation is complete, when you do reboot, it actually deletes a file that is needed and now the application does not run.

    I have been trying to find a way for the silent uninstaller to inform the parent installer that a reboot is needed so it can inform the user and abort, but _NeedsReboot is not set. Should it be? I can see a potential problem here as it seems to always mark a few folders for removal on reboot. They don't get deleted because they are not empty when the system reboots, but if this also set the _NeedsReboot flag, then you would always need to restart.

    Is there some way to intercept the prompt for file in use that you don't see when you are running in silent mode? Is there a way to make a fake silent mode that doesn't pop warnings for every shared file or display anything except file in use warnings?

    Is there some other way to deal with this that I'm just missing entirely?

    Thanks

    Scott
Working...
X