Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt installer script execute
Forum Updated to NodeBB v4.3 + New Features

Qt installer script execute

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 6 Posters 17.1k Views 2 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.
  • M MartinD

    Hi Paul,
    unfortunately, I still have no luck in running external program. I tried e.g.:

    component.addOperation("Execute", "pnputil", "-i", "-a", "D:/usbserial.inf");
    component.addOperation("Execute", "C:/Windows/System32/pnputil.exe", "-i", "-a", "D:/usbserial.inf");
    component.addOperation("Execute", "C:/Windows/System32/PnPutil.exe");
    component.addOperation("Execute", installer.environmentVariable("SystemRoot") + "\\System32\\PnPutil.exe");
    component.addOperation("Execute", "cmd.exe"); // even cmd is not possible
    

    The last three commands produce "No program defined" error.

    RatzzR Offline
    RatzzR Offline
    Ratzz
    wrote on last edited by Ratzz
    #4

    @MartinD
    These might helpful
    https://forum.qt.io/topic/35272/qt-installer-framework-and-administrator-privileges-solved/27
    http://doc.qt.io/qtinstallerframework/scripting.html

    For .txt is shown here http://doc.qt.io/qtinstallerframework/operations.html

    component.addOperation("Execute", "touch", "test.txt", "UNDOEXECUTE", "rm", "test.txt")

    --Alles ist gut.

    1 Reply Last reply
    1
    • M Offline
      M Offline
      MartinD
      wrote on last edited by
      #5

      I have partial success in executing command.

      component.addOperation("Execute", "cmd", "/C", "PnPutil.exe", "-i", "-a", "@TargetDir@\\driver.inf");
      

      It produces:

      Execution failed(Unexpected exit code: 1): "cmd /C PnpUtil.exe -i -a D:\MyApp\driver.inf"
      

      However, cmd /C PnpUtil.exe -i -a D:\MyApp\driver.inf run directly in command prompt produces exit code 0. Does somebody know why the exit codes differs?

      I think I read the documentation and forum but command execution in Qt installer framework seems to be uncomprehensible to me. I don't have a clue why command execution mentioned here produces the errors, why I have to run pnputil.exe via cmd, etc.

      1 Reply Last reply
      0
      • Paul ColbyP Offline
        Paul ColbyP Offline
        Paul Colby
        wrote on last edited by
        #6

        Maybe try addElevatedOperation?

        M 1 Reply Last reply
        1
        • Paul ColbyP Paul Colby

          Maybe try addElevatedOperation?

          M Offline
          M Offline
          MartinD
          wrote on last edited by
          #7

          @Paul-Colby Thanks. I added

          <RequiresAdminRights>true</RequiresAdminRights>
          

          to my package.xml

          and added elevated operation:

          component.addElevatedOperation("Execute", "cmd", "/C", "PnPutil.exe", "-i", "-a", "@TargetDir@\\driver.inf");
          

          Still the same - error code 1.

          RatzzR 1 Reply Last reply
          0
          • M MartinD

            @Paul-Colby Thanks. I added

            <RequiresAdminRights>true</RequiresAdminRights>
            

            to my package.xml

            and added elevated operation:

            component.addElevatedOperation("Execute", "cmd", "/C", "PnPutil.exe", "-i", "-a", "@TargetDir@\\driver.inf");
            

            Still the same - error code 1.

            RatzzR Offline
            RatzzR Offline
            Ratzz
            wrote on last edited by
            #8

            @MartinD
            Did you try full path for PnPutil.exe ?
            Also should it

            @TargetDir@\\driver.inf
            

            be

            @TargetDir@/driver.inf
            

            ?

            --Alles ist gut.

            M 1 Reply Last reply
            0
            • RatzzR Ratzz

              @MartinD
              Did you try full path for PnPutil.exe ?
              Also should it

              @TargetDir@\\driver.inf
              

              be

              @TargetDir@/driver.inf
              

              ?

              M Offline
              M Offline
              MartinD
              wrote on last edited by
              #9

              @Ratzz Still exit code 1.

              I discovered that operation with nonexistent .exe

              component.addElevatedOperation("Execute", "cmd", "/C", "blabla", "-i", "-a", "@TargetDir@/dfdu.inf");
              

              still produces exit code 1 error in my installer.

              1 Reply Last reply
              0
              • M Offline
                M Offline
                MartinD
                wrote on last edited by MartinD
                #10

                I discoved this works:

                // launching python script in installer works
                component.addOperation("Execute", "C:/Python27/python.exe", "@TargetDir@/script.py", "workingdirectory=@TargetDir@");
                

                This doesn't work:

                // launching e.g. pnputil.exe or qmake.exe produces "no program defined" error
                component.addOperation("Execute", "C:/Windows/System32/pnputil.exe", "workingdirectory=@TargetDir@");
                component.addOperation("Execute", "C:/Qt/5.6/mingw49_32/bin/qmake.exe", "workingdirectory=@TargetDir@");
                

                Any idea why? (launching them in command line works of course)

                EDIT: I found that "No program defined" defined error is defined in qprocess.cpp:

                void QProcess::start(const QString &program, const QStringList &arguments, OpenMode mode)
                {
                    Q_D(QProcess);
                    if (d->processState != NotRunning) {
                        qWarning("QProcess::start: Process is already running");
                        return;
                    }
                    if (program.isEmpty()) {
                        Q_D(QProcess);
                        d->processError = QProcess::FailedToStart;
                        setErrorString(tr("No program defined"));
                        emit error(d->processError);
                        return;
                    }
                
                    d->program = program;
                    d->arguments = arguments;
                
                    d->start(mode);
                }
                
                1 Reply Last reply
                0
                • Paul ColbyP Offline
                  Paul ColbyP Offline
                  Paul Colby
                  wrote on last edited by
                  #11

                  @MartinD said:

                  I discoved this works:

                  // launching python script in installer works
                  component.addOperation("Execute", "C:/Python27/python.exe", "@TargetDir@/script.py", "workingdirectory=@TargetDir@");
                  

                  This doesn't work:

                  // launching e.g. pnputil.exe or qmake.exe produces "no program defined" error
                  component.addOperation("Execute", "C:/Windows/System32/pnputil.exe", "workingdirectory=@TargetDir@");
                  component.addOperation("Execute", "C:/Qt/5.6/mingw49_32/bin/qmake.exe", "workingdirectory=@TargetDir@");
                  

                  Any idea why?

                  I suspect the reason is that the Python example has an argument (ignoring the workerdirectory bit) while the other two do not.

                  The reason I suspect this, is that it looks (from trawling the code), that there's a bug in the Qt Installer Framework code specific to Q_OS_WIN and args.count() == 1.

                  Let me explain...

                  I found that "No program defined" defined error is defined in qprocess.cpp:

                  That code / error indicates that QProcess::start is being called with an empty program name; ie the following check is being triggered.

                  if (program.isEmpty()) {
                  

                  So, where is that coming from...

                  Looking into the QIF's code, we see that ElevatedExecuteOperation (which seems to handle all Execute commands, not just the elevated one) uses QIF's QProcessWrapper class, which lightly wraps Qt's QProcess.

                  That brings us to this bit of code, found in ElevatedExecuteOperation::Private::run:

                  #ifdef Q_OS_WIN
                      if (args.count() == 1) {
                          process->setNativeArguments(args.front());
                          qDebug() << "ElevatedExecuteOperation setNativeArguments to start:" << args.front();
                          process->start(QString(), QStringList());
                      } else
                  #endif
                      {
                          process->start(args.front(), args.mid(1));
                      }
                  

                  See that on Q_OS_WIN, if the args count is 1, then:

                  1. the code uses QProcess::setNativeArguments (so, presumably, forward-to-back slash conversion is no longer in effect, etc) - this part is okay; then
                  2. invokes QProcess::start with a null string!

                  It's that second step which will always fail, as I read the code, since QProcess::start pays no attention to anything set via QProcess::setNativeArguments, so far as I can see, before checking the program name.

                  The QProcess::setNativeArguments documentation is unclear, but numerous examples on github suggest that even when using it, the first argument to QProcess::start should still be the executable.

                  So I'd:

                  1. try adding another argument to your latest example (to fail the args.count() == 1 test);
                  2. report this as a (potential) bug on bugreports.qt.io to see what the QIF's devs think.

                  Cheers.

                  1 Reply Last reply
                  4
                  • X Offline
                    X Offline
                    xl0x
                    wrote on last edited by
                    #12

                    Hey,

                    old topic, but I've spent hours today on the same issue, and this is the only place I could google. And as someone new to Windows, it was not obvious at all.

                    The problem is with the Windows filesystem redirection:
                    https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187.aspx

                    Since the installer is 32-bit, Windows redirects calls to system32 into sysWOW64, which does not have pnputil. You need to use the sysnative directory instead, see the msdn article.

                    That's how I do it in my installer:

                        windir = installer.environmentVariable("windir");
                        console.log("WINDIR: " + windir);
                    
                        if (windir == "") {
                            //Just in case.
                            console.log("Undefined WINDIR? Assuming c:\\windows\\");
                            windir = "c:\\windows";
                        }
                    
                        pnputil = windir + "\\sysnative\\pnputil.exe";
                    
                        console.log("pnputil = " + pnputil);
                        component.addElevatedOperation("Execute", pnputil, "-i", "-a", "@TargetDir@\\driver.inf");
                    

                    Works as expected!

                    1 Reply Last reply
                    4
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #13

                      Hi and welcome to devnet,

                      Thanks for sharing your findings !

                      Did you try to take a look at the bug report system ? If not, please do and if you find a related bug report, please update it too :)

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0
                      • X Offline
                        X Offline
                        xl0x
                        wrote on last edited by
                        #14

                        The bug report is closed already:

                        https://bugreports.qt.io/browse/QTIFW-862

                        It seems that there was some unrelated problem, and it's been fixed in 2.1.0.

                        1 Reply Last reply
                        1
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #15

                          Thanks !

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          0
                          • K Offline
                            K Offline
                            kluszon
                            wrote on last edited by
                            #16

                            @xl0x in my case your solution produce error" "Execution failed(Unexpected exit code: 259): "C:\windows\sysnative\pnputil.exe -i -a C:\Program Files (x86)\My_app\driver\driver.inf"". Any soution for this?

                            I found the partial solution. I created bat file which installs driver:

                            start Pnputil -i -a PX218.inf
                            

                            After that, I convert this bat file to exe using "Bat to Exe Convereter" application. Finally, I added this line to installscript.qs:

                            component.addOperation("Execute", "@TargetDir@/driver/install.exe", "workingdirectory=@TargetDir@/driver/");
                            

                            and it work form me, but it's not convenient....

                            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