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 16.8k 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 Offline
    M Offline
    MartinD
    wrote on 17 May 2016, 21:00 last edited by
    #1

    Hi,
    what is the correct syntax to run pnputil.exe to install inf driver in Windows in Qt installer framework script?

    I tried:

    //installscript.qs
    function Component()
    {
    }
    
    Component.prototype.createOperations = function()
    {
        component.createOperations();
    
        component.addOperation("Execute", "pnputil", "-i -a driver.inf");
    }
    

    but that ends with "execution failed: could not start proces failed to start: no such file or directory" during installation.

    I'm able to run pnputil -i -a driver.inf in my command line.

    1 Reply Last reply
    0
    • P Offline
      P Offline
      Paul Colby
      wrote on 17 May 2016, 22:17 last edited by
      #2

      Hi @MartinD,

      component.addOperation("Execute", "pnputil", "-i -a driver.inf");
      

      I'm not familiar with Qt Installer Framework (hoping to start using it soon), but I first thing I'd try is:

      • add the .exe extension; and
      • separate out the arguments.

      Something like:

      component.addOperation("Execute", "pnputil.exe", "-i", "-a", "driver.inf");
      

      And if that didn't work, I'd fully-qualify both the .exe and .inf filenames too.

      Hopefully someone with more QIF experience can offer some better suggestions :)

      Cheers.

      1 Reply Last reply
      0
      • M Offline
        M Offline
        MartinD
        wrote on 18 May 2016, 06:31 last edited by MartinD
        #3

        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.

        R 1 Reply Last reply 18 May 2016, 08:09
        0
        • M MartinD
          18 May 2016, 06:31

          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.

          R Offline
          R Offline
          Ratzz
          wrote on 18 May 2016, 08:09 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 18 May 2016, 09:55 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
            • P Offline
              P Offline
              Paul Colby
              wrote on 18 May 2016, 10:00 last edited by
              #6

              Maybe try addElevatedOperation?

              M 1 Reply Last reply 18 May 2016, 10:15
              1
              • P Paul Colby
                18 May 2016, 10:00

                Maybe try addElevatedOperation?

                M Offline
                M Offline
                MartinD
                wrote on 18 May 2016, 10:15 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.

                R 1 Reply Last reply 18 May 2016, 10:37
                0
                • M MartinD
                  18 May 2016, 10:15

                  @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.

                  R Offline
                  R Offline
                  Ratzz
                  wrote on 18 May 2016, 10:37 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 18 May 2016, 10:59
                  0
                  • R Ratzz
                    18 May 2016, 10:37

                    @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 18 May 2016, 10:59 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 18 May 2016, 16:32 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
                      • P Offline
                        P Offline
                        Paul Colby
                        wrote on 18 May 2016, 22:31 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 8 Oct 2017, 13:02 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 8 Oct 2017, 18:25 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 9 Oct 2017, 06:06 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 9 Oct 2017, 06:11 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 28 Jun 2018, 09:57 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