Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt Installer Framework - Admin Rights when uninstalling



  • Hello,

    I currently work with Qt Installer Framework to execute the following commands during the installation:

    //adds firewall rule
    component.addElevatedOperation("Execute", "C:\\Windows\\System32\\netsh.exe", "advfirewall", "firewall", "add", "rule", "name=@ProductName@", "protocol=TCP", "dir=in", "localip=192.168.69.10", "localport=51000", "action=allow", "program=@TargetDir@\\test.exe");
    
    //registers dlls
    component.addElevatedOperation("Execute", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/codebase", "@TargetDir@\\CP_Xcom.dll");
    

    By adding Admin <RequiresAdminRights>true</RequiresAdminRights> in package.xml these commands perfectly work.
    Now I'd like to execute similar commands during uninstallation like the one below but it doesn't work. During uninstallation I get a warning message and I must skip this step.

    //deletes firewall rule
    component.addElevatedOperation("Execute", "C:\\Windows\\System32\\netsh.exe", "advfirewall", "firewall", "delete", "rule", "name=@ProductName@");
    

    I also tried to execute it in the installer script but same result. I think this is because I don't have admin rights during uninstallation.
    I tried many different ways to do it but impossible to make it work.

    Did someone already be able to execute this kind of command during uninstallation?
    Thank you.



  • I'm not sure about this but have you tried that instead of writing two Execute operations in installation and uninstallation, just write one operation using Execute and UNDOEXECUTE

    Component.prototype.createOperations = function()
    {
        // call default implementation
        component.createOperations();
        // ... add custom operations
        component.addElevatedOperation("Execute", "C:\\Windows\\System32\\netsh.exe", "advfirewall", "firewall", "add", "rule", "name=@ProductName@", "protocol=TCP", "dir=in", "localip=192.168.69.10", "localport=51000", "action=allow", "program=@TargetDir@\\test.exe", "UNDOEXECUTE", "C:\\Windows\\System32\\netsh.exe", "advfirewall", "firewall", "delete", "rule", "name=@ProductName@");
    }
    


  • Hi Bonnie,

    Thank you so much it works like a charm for this command.
    I just have another issue, during installation I register .dll files of files present in the application folder:

    component.addElevatedOperation("Execute", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/codebase", "@TargetDir@\\CP_Xcom.dll");
    

    During uninstallation I have to unregister them so I used UNDOEXECUTE :

    component.addElevatedOperation("Execute", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/codebase", "@TargetDir@\\CP_Xcom.dll", "UNDOEXECUTE", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/unregister", "@TargetDir@\\CP_Xcom.dll");
    

    I cannot do this because I need that dll files still exist in my app folder to unregistrer them in the Windows Registry.

    Is there a way to execute this command in Component() before the system starts to delete files?
    I found a solution for Controller() but I can't do this in controller because it needs Admin rights and my commadns don't work.

    Thank you for your help.



  • I also noticed that "UNDOEXECUTE" command is launched during updates.
    Is there a way to only execute it during uninstallation and not updates?

    I tried to add this but it doesn't work:

    if (installer.isInstaller() && !installer.isUpdater()) {}
    

    Thanks.



  • During looking into the first question, I'm curious that where do you put the RegAsm Operation?
    When I tried to Execute something like "dir" in installation , I found that the operation is performed before the files are copied to the TargetDir.
    So I should not be able to do the register thing because there is no such dll in the TargetDir during installation. It confuses me.
    Or do you put the operation in a different component than the dll file?

    As for the second one, how about only using

    if (!installer.isUpdater()) {}
    


  • Hi Bonnie, I firstly want to thank you for your help.
    Here's my script, I can confirm that these commands are executed once files copied. How do you do to execute commands before?

    Edit: It's weird because if I try to display a QMessageBox it is launched before the copy. I don't understand

    function Component()
    {
    }
    
    Component.prototype.createOperations = function()
    {
        if (systemInfo.productType === "windows") {
    
            try {
    
                // Calls the base create operations function
                component.createOperations();
    
                if (installer.isInstaller()) {
    
                    // Adds firewall rules
                    component.addElevatedOperation("Execute", "C:\\Windows\\System32\\netsh.exe", "advfirewall", "firewall", "add", "rule", "name=@ProductName@", "protocol=TCP", "dir=in", "action=allow", "program=@TargetDir@\\@AppExe@");
                    component.addElevatedOperation("Execute", "C:\\Windows\\System32\\netsh.exe", "advfirewall", "firewall", "add", "rule", "name=@ProductName@", "protocol=UDP", "dir=in", "action=allow", "program=@TargetDir@\\@AppExe@");
                    component.addElevatedOperation("Execute", "C:\\Windows\\System32\\netsh.exe", "advfirewall", "firewall", "add", "rule", "name=@ProductName@", "protocol=TCP", "dir=out", "action=allow", "program=@TargetDir@\\@AppExe@");
                    component.addElevatedOperation("Execute", "C:\\Windows\\System32\\netsh.exe", "advfirewall", "firewall", "add", "rule", "name=@ProductName@", "protocol=UDP", "dir=out", "action=allow", "program=@TargetDir@\\@AppExe@");
    
                    // Registers .dll files
                    component.addElevatedOperation("Execute", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/codebase", "@TargetDir@\\CP_Xcom.dll");
                    component.addElevatedOperation("Execute", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/codebase", "@TargetDir@\\SP_Chacom.dll");
                    component.addElevatedOperation("Execute", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/codebase", "@TargetDir@\\DLL_VisionSystem_SV.dll");
                }
    
            } catch (e) {
                console.log(e);
            }
        }
    }
    

    I'm going to try your solution for my second question.



  • Regarding my second question I tried your solution but unfortunately "UNDOEXECUTE" commands are still executed when I update my application, very strange.

    It seems that the system absolutely wants to undo commands that have been executed during the installation when we're updating. I mean I tried to add a QMessageBox.question in the if (!installer.isUpdater()) {} and this message box is well executed during installation and not executed during updates so normally commands should not be executed and in my case they are...

    Component.prototype.createOperations = function()
    {
        if (systemInfo.productType === "windows") {
    
            try {
    
                if (!installer.isUpdater()) {
    
                        // Registers .dll files
                        component.addElevatedOperation("Execute", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/codebase", "@TargetDir@\\CP_Xcom.dll", "UNDOEXECUTE", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/unregister", "@TargetDir@\\CP_Xcom.dll");
                        component.addElevatedOperation("Execute", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/codebase", "@TargetDir@\\SP_Chacom.dll", "UNDOEXECUTE", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/unregister", "@TargetDir@\\SP_Chacom.dll");
                        component.addElevatedOperation("Execute", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/codebase", "@TargetDir@\\DLL_VisionSystem_SV.dll", "UNDOEXECUTE", "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe", "/unregister", "@TargetDir@\\DLL_VisionSystem_SV.dll");
            }
    
            } catch (e) {
                console.log(e);
            }
        }
    }
    


  • @SebastienB I did some more tests.

    1. The Execute operations seem do run after install files are copied.
      But the UNDOEXECUTE operations also run before the files are deleted.
      I use a SimpleMoveFile operation to test.
      It always successfully moves the specific file out of the install dir before it is deleted by the uninstallation.
      And by running the maintenancetool.exe with -v in CMD console, I can see the "undo of Execute" (UNDOEXECUTE ) is in front of the "undo of Extract" (Delete).
      So I'm not sure why your installer's behavior is different from mine.
      *I'm using the newest version 3.2.

    2. After checking the source code of ifw, I found that createOperations is only called in installation.
      In uninstaller / updater, it reads its performed operation from the .dat file.
      So I think there is probably no way to disable any operation in the updater.


Log in to reply