Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Installation and Deployment
  4. "AllUsers" not working if set programmatically in QtIFW
Forum Updated to NodeBB v4.3 + New Features

"AllUsers" not working if set programmatically in QtIFW

Scheduled Pinned Locked Moved Unsolved Installation and Deployment
6 Posts 2 Posters 51 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • FlincoF Offline
    FlincoF Offline
    Flinco
    wrote last edited by Flinco
    #1

    I manage the installation of a small application of mine on Windows using QtIFW.

    The following snippet of XML in the package.xml of one of the installed components sets a link to the application on the Desktop:

    <Operations>
      ...
      <Operation name="CreateShortcut">
        <Argument>@TargetDir@\LBChronoRace.exe</Argument>
        <Argument>@DesktopDir@\LBChronoRace.lnk</Argument>
        <Argument>workingDirectory=@TargetDir@</Argument>
        <Argument>iconPath=@TargetDir@\LBChronoRace.exe</Argument>
        <Argument>iconId=0</Argument>
        <!--<Argument>description="Start LBChronoRace"</Argument>-->
      </Operation>
      ...
    </Operations>
    

    The link is installed on the Desktop folder of the user that is installing the application.

    I would like the link to be installed in the Desktop directory common to all users. To achieve this I tried running the installer by adding AllUsers=true to its command line. And it worked.

    Since this is not feasible for those who will download and install the application (they will not be developers and will install with a simple double click), I tried setting AllUsers=true programmatically in the IFW control script:

    function Controller() {
        installer.setValue("AllUsers", "true");
    }
    

    But it doesn't work and the link keeps being created in the user's Desktop folder instead of the common folder.

    I have evidence that the variable is set. Infact in the last page of the installer the value is reported as true by the following snippet:

    Controller.prototype.FinishedPageCallback = function() {
        var allUsers = installer.value("AllUsers");
        var desktopDir = installer.value("DesktopDir");
        var page = gui.pageWidgetByObjectName("FinishedPage");
        if (page) {
            var msg = "AllUsers = " + allUsers + "\nDesktopDir = " + desktopDir;
            page.MessageLabel.setText(msg);
        }
    };
    

    Looking at the addDynamicPredefinedVariables() function of packagemanagercoredata.cpp (in the IFW sources) I notice this:

    QString desktop;
    if (m_variables.value(QLatin1String("AllUsers")) == scTrue) {
        desktop = system.value(QLatin1String("Common Desktop")).toString();
    } else {
        desktop = user.value(QLatin1String("Desktop")).toString();
    }
    addNewVariable(QLatin1String("DesktopDir"), replaceWindowsEnvironmentVariables(desktop));
    

    So I don't understand why there should be a difference between when the variable set in the environment and when it is set programmatically.

    I also tried the same on the component script installscript.qs:

    function Component() {
    }
    
    Component.prototype.createOperations = function() {
        /* Set the variabile BEFORE operations creation */
        installer.setValue("AllUsers", "true");
    
        /* Go on with standard operations */
        component.createOperations();
    };
    

    with both

    <Script>installscript.qs</Script>
    

    and

    <Script postLoad="true">installscript.qs</Script>
    

    but without any change in the installer behaviour.

    JonBJ 1 Reply Last reply
    0
    • FlincoF Flinco

      I manage the installation of a small application of mine on Windows using QtIFW.

      The following snippet of XML in the package.xml of one of the installed components sets a link to the application on the Desktop:

      <Operations>
        ...
        <Operation name="CreateShortcut">
          <Argument>@TargetDir@\LBChronoRace.exe</Argument>
          <Argument>@DesktopDir@\LBChronoRace.lnk</Argument>
          <Argument>workingDirectory=@TargetDir@</Argument>
          <Argument>iconPath=@TargetDir@\LBChronoRace.exe</Argument>
          <Argument>iconId=0</Argument>
          <!--<Argument>description="Start LBChronoRace"</Argument>-->
        </Operation>
        ...
      </Operations>
      

      The link is installed on the Desktop folder of the user that is installing the application.

      I would like the link to be installed in the Desktop directory common to all users. To achieve this I tried running the installer by adding AllUsers=true to its command line. And it worked.

      Since this is not feasible for those who will download and install the application (they will not be developers and will install with a simple double click), I tried setting AllUsers=true programmatically in the IFW control script:

      function Controller() {
          installer.setValue("AllUsers", "true");
      }
      

      But it doesn't work and the link keeps being created in the user's Desktop folder instead of the common folder.

      I have evidence that the variable is set. Infact in the last page of the installer the value is reported as true by the following snippet:

      Controller.prototype.FinishedPageCallback = function() {
          var allUsers = installer.value("AllUsers");
          var desktopDir = installer.value("DesktopDir");
          var page = gui.pageWidgetByObjectName("FinishedPage");
          if (page) {
              var msg = "AllUsers = " + allUsers + "\nDesktopDir = " + desktopDir;
              page.MessageLabel.setText(msg);
          }
      };
      

      Looking at the addDynamicPredefinedVariables() function of packagemanagercoredata.cpp (in the IFW sources) I notice this:

      QString desktop;
      if (m_variables.value(QLatin1String("AllUsers")) == scTrue) {
          desktop = system.value(QLatin1String("Common Desktop")).toString();
      } else {
          desktop = user.value(QLatin1String("Desktop")).toString();
      }
      addNewVariable(QLatin1String("DesktopDir"), replaceWindowsEnvironmentVariables(desktop));
      

      So I don't understand why there should be a difference between when the variable set in the environment and when it is set programmatically.

      I also tried the same on the component script installscript.qs:

      function Component() {
      }
      
      Component.prototype.createOperations = function() {
          /* Set the variabile BEFORE operations creation */
          installer.setValue("AllUsers", "true");
      
          /* Go on with standard operations */
          component.createOperations();
      };
      

      with both

      <Script>installscript.qs</Script>
      

      and

      <Script postLoad="true">installscript.qs</Script>
      

      but without any change in the installer behaviour.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote last edited by JonB
      #2

      @Flinco
      I have never used installer and know nothing about it, but doesn't stop me trying to help :)

      One obvious way your findings could occur would be if the addDynamicPredefinedVariables() were called only before your installer.setValue("AllUsers", "true"). IF the only important bit is the addNewVariable(QLatin1String("DesktopDir"), ...) maybe try setting installer.setValue("DesktopDir", desiredPath) instead and see if that has any effect? And can you ensure your function Controller() is indeed called?

      1 Reply Last reply
      0
      • FlincoF Offline
        FlincoF Offline
        Flinco
        wrote last edited by Flinco
        #3

        @JonB, I replaced installer.setValue("AllUsers", "true"); with installer.setValue("DesktopDir", installer.toNativeSeparators("C:/Users/Public/Desktop")); in the body of function Controller().

        This ensured that function Controller() is called (I don't know when...), but it certainly gets called since this time the link was created in C:\Users\Public\Desktop (that is exactly where I expect).

        Now, I think this may just be a workaround, since IMHO relying on the fact that the "Common Desktop" directory is always and will always be C:\Users\Public\Desktop is wrong.

        JonBJ 1 Reply Last reply
        0
        • FlincoF Flinco

          @JonB, I replaced installer.setValue("AllUsers", "true"); with installer.setValue("DesktopDir", installer.toNativeSeparators("C:/Users/Public/Desktop")); in the body of function Controller().

          This ensured that function Controller() is called (I don't know when...), but it certainly gets called since this time the link was created in C:\Users\Public\Desktop (that is exactly where I expect).

          Now, I think this may just be a workaround, since IMHO relying on the fact that the "Common Desktop" directory is always and will always be C:\Users\Public\Desktop is wrong.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote last edited by
          #4

          @Flinco
          This was supposed to be a test to see if you can get something working. Obviously you should not pass a literal string but something based on system.value(QLatin1String("Common Desktop")) and replaceWindowsEnvironmentVariables(desktop), per the code you showed.

          1 Reply Last reply
          1
          • FlincoF Offline
            FlincoF Offline
            Flinco
            wrote last edited by
            #5

            @JonB, thank you for your valuable suggestions.
            I found out that this piece of code is working and can be an acceptable workaround:

            function Controller() {
                var commonDesktopPath = system.value(QLatin1String("Common Desktop"));
                installer.setValue("DesktopDir", installer.toNativeSeparators(commonDesktopPath))
            }
            
            JonBJ 1 Reply Last reply
            0
            • FlincoF Flinco

              @JonB, thank you for your valuable suggestions.
              I found out that this piece of code is working and can be an acceptable workaround:

              function Controller() {
                  var commonDesktopPath = system.value(QLatin1String("Common Desktop"));
                  installer.setValue("DesktopDir", installer.toNativeSeparators(commonDesktopPath))
              }
              
              JonBJ Offline
              JonBJ Offline
              JonB
              wrote last edited by
              #6

              @Flinco
              That was indeed the kind of thing I was suggesting. For unknown reason it appears that the if in

              if (m_variables.value(QLatin1String("AllUsers")) == scTrue) {
                  desktop = system.value(QLatin1String("Common Desktop")).toString();
              } else {
                  desktop = user.value(QLatin1String("Desktop")).toString();
              }
              

              reacts as desired when you pass AllUsers=true on command line but not when

              function Controller() {
                  installer.setValue("AllUsers", "true");
              }
              

              Perhaps this is "too late" (or even "too early") for the call to addDynamicPredefinedVariables(). Your new code/this "workaround" does the code for the choice of system.value(QLatin1String("Common Desktop")) unconditionally without relying on m_variables.value(QLatin1String("AllUsers")) == scTrue (btw, I do not know whether setValue("AllUsers", "true") actually sets a value which equals scTrue).

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved