2017-09-27 4 views
1

Cette question concerne la version 2.0 de Qt Installer Framework. À ce stade, il est de notoriété publique que les personnes utilisant Qt Installer Framework ne peuvent pas, sans personnalisation, remplacer une installation existante par l'intermédiaire de votre programme d'installation. Cela a apparemment été fait pour résoudre certains problèmes qui se sont produits lorsque cela a été fait avec le cadre Qt. Cependant, pour les projets plus petits et relativement simples, l'écrasement est parfaitement bien et beaucoup plus pratique que d'avoir à exécuter manuellement l'outil de maintenance au préalable.Solution de contournement pour Qt Installer Framework ne pas remplacer l'installation existante

Je cherche une solution impliquant une interface utilisateur personnalisée + script composant qui ajoute un bouton à la page du répertoire cible qui permet à l'utilisateur d'

  1. Supprimez le répertoire spécifié si elle existe, ou
  2. Exécutez l'outil de maintenance dans ce répertoire.

Il serait préférable de pouvoir exécuter l'outil de maintenance dans le répertoire cible, l'avoir supprimer automatiquement un paquet donné, mais je me rends compte que cela se demande un peu trop.

J'ai lu les réponses à d'autres questions sur ce site concernant la résolution du même problème, mais aucune des solutions ne fonctionne correctement. Je voudrais également mentionner que j'ai un script de composant en cours d'exécution, mais pas d'interface utilisateur personnalisée.

Répondre

1

J'ai finalement trouvé une solution viable.

Vous avez besoin de trois choses à retirer ceci:

  1. Un script de composant,
  2. Une interface utilisateur personnalisée pour la page de répertoire cible et
  3. Un script de contrôleur qui clique sur le programme de désinstallation automatique.

Je vais maintenant énumérer textuellement ce qui fonctionne pour moi (avec mes trucs spécifiques au projet). Mon composant est appelé Atlas4500 Tuner

config.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<Installer> 
    <Name>Atlas4500 Tuner</Name> 
    <Version>1.0.0</Version> 
    <Title>Atlas4500 Tuner Installer</Title> 
    <Publisher>EF Johnson Technologies</Publisher> 
    <StartMenuDir>EF Johnson</StartMenuDir> 
    <TargetDir>C:\Program Files (x86)\EF Johnson\Atlas4500 Tuner</TargetDir> 
</Installer> 

paquets/Atlas4500 Tuner/méta/package.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<Package> 
    <DisplayName>Atlas4500Tuner</DisplayName> 
    <Description>Install the Atlas4500 Tuner</Description> 
    <Version>1.0.0</Version> 
    <ReleaseDate></ReleaseDate> 
    <Default>true</Default> 
    <Required>true</Required> 
    <Script>installscript.qs</Script> 
    <UserInterfaces> 
     <UserInterface>targetwidget.ui</UserInterface> 
    </UserInterfaces> 
</Package> 

script personnalisé composant paquets/Atlas4500 Tuner/meta/installscript.qs:

var targetDirectoryPage = null; 

function Component() 
{ 
    installer.gainAdminRights(); 
    component.loaded.connect(this, this.installerLoaded); 
} 

Component.prototype.createOperations = function() 
{ 
    // Add the desktop and start menu shortcuts. 
    component.createOperations(); 
    component.addOperation("CreateShortcut", 
          "@[email protected]/Atlas4500Tuner.exe", 
          "@[email protected]/Atlas4500 Tuner.lnk", 
          "[email protected]@"); 

    component.addOperation("CreateShortcut", 
          "@[email protected]/Atlas4500Tuner.exe", 
          "@[email protected]/Atlas4500 Tuner.lnk", 
          "[email protected]@"); 
} 

Component.prototype.installerLoaded = function() 
{ 
    installer.setDefaultPageVisible(QInstaller.TargetDirectory, false); 
    installer.addWizardPage(component, "TargetWidget", QInstaller.TargetDirectory); 

    targetDirectoryPage = gui.pageWidgetByObjectName("DynamicTargetWidget"); 
    targetDirectoryPage.windowTitle = "Choose Installation Directory"; 
    targetDirectoryPage.description.setText("Please select where the Atlas4500 Tuner will be installed:"); 
    targetDirectoryPage.targetDirectory.textChanged.connect(this, this.targetDirectoryChanged); 
    targetDirectoryPage.targetDirectory.setText(installer.value("TargetDir")); 
    targetDirectoryPage.targetChooser.released.connect(this, this.targetChooserClicked); 

    gui.pageById(QInstaller.ComponentSelection).entered.connect(this, this.componentSelectionPageEntered); 
} 

Component.prototype.targetChooserClicked = function() 
{ 
    var dir = QFileDialog.getExistingDirectory("", targetDirectoryPage.targetDirectory.text); 
    targetDirectoryPage.targetDirectory.setText(dir); 
} 

Component.prototype.targetDirectoryChanged = function() 
{ 
    var dir = targetDirectoryPage.targetDirectory.text; 
    if (installer.fileExists(dir) && installer.fileExists(dir + "/maintenancetool.exe")) { 
     targetDirectoryPage.warning.setText("<p style=\"color: red\">Existing installation detected and will be overwritten.</p>"); 
    } 
    else if (installer.fileExists(dir)) { 
      targetDirectoryPage.warning.setText("<p style=\"color: red\">Installing in existing directory. It will be wiped on uninstallation.</p>"); 
    } 
    else { 
     targetDirectoryPage.warning.setText(""); 
    } 
    installer.setValue("TargetDir", dir); 
} 

Component.prototype.componentSelectionPageEntered = function() 
{ 
    var dir = installer.value("TargetDir"); 
    if (installer.fileExists(dir) && installer.fileExists(dir + "/maintenancetool.exe")) { 
     installer.execute(dir + "/maintenancetool.exe", "--script=" + dir + "/scripts/auto_uninstall.qs"); 
    } 
} 

répertoire cible personnalisée widget packages/Atlas4500 Tuner/meta/targetwidget.ui:

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>TargetWidget</class> 
<widget class="QWidget" name="TargetWidget"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>491</width> 
    <height>190</height> 
    </rect> 
    </property> 
    <property name="sizePolicy"> 
    <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> 
    <horstretch>0</horstretch> 
    <verstretch>0</verstretch> 
    </sizepolicy> 
    </property> 
    <property name="minimumSize"> 
    <size> 
    <width>491</width> 
    <height>190</height> 
    </size> 
    </property> 
    <property name="windowTitle"> 
    <string>Form</string> 
    </property> 
    <layout class="QVBoxLayout" name="verticalLayout"> 
    <item> 
    <widget class="QLabel" name="description"> 
    <property name="text"> 
     <string/> 
    </property> 
    </widget> 
    </item> 
    <item> 
    <layout class="QHBoxLayout" name="horizontalLayout"> 
    <item> 
     <widget class="QLineEdit" name="targetDirectory"> 
     <property name="readOnly"> 
     <bool>true</bool> 
     </property> 
     </widget> 
    </item> 
    <item> 
     <widget class="QToolButton" name="targetChooser"> 
     <property name="sizePolicy"> 
     <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> 
     <horstretch>0</horstretch> 
     <verstretch>0</verstretch> 
     </sizepolicy> 
     </property> 
     <property name="minimumSize"> 
     <size> 
     <width>0</width> 
     <height>0</height> 
     </size> 
     </property> 
     <property name="text"> 
     <string>...</string> 
     </property> 
     </widget> 
    </item> 
    </layout> 
    </item> 
    <item> 
    <layout class="QHBoxLayout" name="horizontalLayout_2"> 
    <property name="topMargin"> 
     <number>0</number> 
    </property> 
    <item> 
     <widget class="QLabel" name="warning"> 
     <property name="enabled"> 
     <bool>true</bool> 
     </property> 
     <property name="text"> 
     <string>TextLabel</string> 
     </property> 
     </widget> 
    </item> 
    <item> 
     <spacer name="horizontalSpacer"> 
     <property name="orientation"> 
     <enum>Qt::Horizontal</enum> 
     </property> 
     <property name="sizeHint" stdset="0"> 
     <size> 
     <width>40</width> 
     <height>20</height> 
     </size> 
     </property> 
     </spacer> 
    </item> 
    </layout> 
    </item> 
    <item> 
    <spacer name="verticalSpacer"> 
    <property name="orientation"> 
     <enum>Qt::Vertical</enum> 
    </property> 
    <property name="sizeHint" stdset="0"> 
     <size> 
     <width>20</width> 
     <height>122</height> 
     </size> 
    </property> 
    </spacer> 
    </item> 
    </layout> 
</widget> 
<resources/> 
<connections/> 
</ui> 

forfaits/Atlas4500 Tuner/données/scripts/auto_uninstall.qs:

// Controller script to pass to the uninstaller to get it to run automatically. 
// It's passed to the maintenance tool during installation if there is already an 
// installation present with: <target dir>/maintenancetool.exe --script=<target dir>/scripts/auto_uninstall.qs. 
// This is required so that the user doesn't have to see/deal with the uninstaller in the middle of 
// an installation. 

function Controller() 
{ 
    gui.clickButton(buttons.NextButton); 
    gui.clickButton(buttons.NextButton); 

    installer.uninstallationFinished.connect(this, this.uninstallationFinished); 
} 

Controller.prototype.uninstallationFinished = function() 
{ 
    gui.clickButton(buttons.NextButton); 
} 

Controller.prototype.FinishedPageCallback = function() 
{ 
    gui.clickButton(buttons.FinishButton); 
} 

L'idée ici est de détecter si le répertoire courant a une installation ou non, et, si elle le fait, exécutez l'outil de maintenance dans ce répertoire avec un contrôleur script qui clique juste à travers.

Notez que je place le script du contrôleur dans un répertoire de scripts qui fait partie des données de composant réelles. Vous pourriez probablement faire quelque chose de plus propre si vous avez plusieurs composants, mais c'est ce que j'utilise.

Vous devriez être en mesure de copier ces fichiers pour vous-même et juste modifier les chaînes pour le faire fonctionner.

0

Il y a peu de choses que vous devez faire:

  • Pour passer de TargetDirectoryPage que vous pouvez obtenir en ajoutant ce code installer.setValue("RemoveTargetDir", false)

  • interface utilisateur personnalisée (ou boîte de message) qui vous permettent pour exécuter ce code. Cette interface utilisateur doit être insérée après la TargetDirectoryPage. // you need to append .exe on the maintenance for windows installation installer.execute(installer.findPath(installer.value("MaintenanceToolName"), installer.value("TargetDir")));

+0

Cela me met sur la bonne voie, car l'exécution de l'outil de maintenance fonctionne comme ça. Cependant, le "RemoveTargerDir" ne fait rien. Voir ma réponse pour la solution que j'ai trouvée. – rationalcoder