2017-09-27 445 views
1

这个问题是关于Qt安装程序框架的2.0版本。Qt安装程序框架的解决方法不覆盖现有安装

在这一点上,使用Qt Installer Framework的人们通常都知道,如果没有定制,您无法通过安装程序覆盖现有安装。这显然是为了解决使用Qt框架完成的一些问题。

但是,对于较小的相对简单的项目,覆盖是完美的,并且比预先手动运行维护工具更方便。

我找了涉及自定义UI +组件脚本,增加了一个按钮到目标目录页面,允许用户如果存在任何

  1. 删除指定目录下的解决方案,或
  2. 运行该目录中的维护工具。

这将是最好能够运行在目标目录中的维护工具,让它自动删除一个给定的包,我意识到,这是要求一点也不为过。

我已阅读本网站上关于解决相同问题的其他问题的答案,但没有一个解决方案能正常工作。我还想提一下,我有一个组件脚本启动并运行,但没有自定义用户界面。

回答

1

我终于找到一个可行的解决方案。

您需要三样东西拉这一关:

  1. 的组件脚本,
  2. 目标目录页面自定义用户界面,并
  3. 通过卸载程序自动点击控制器脚本。

我现在要逐字列出对我有用的东西(用我的项目特定的东西)。我的组件被称为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> 

包/ Atlas4500调谐器/元/包。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> 

自定义组件脚本包/ Atlas4500调谐器/元/ 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"); 
    } 
} 

自定义目标目录插件包/ Atlas4500调谐器/元/ 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> 

packages/Atlas4500 Tuner /数据/脚本/ 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); 
} 

这里的想法是,以检测如果当前目录中有一个安装与否,而且,如果这样做,运行在该目录中的维护工具与控制器只需点击它的脚本。

请注意,我将控制器脚本放在作为实际组件数据一部分的脚本目录中。如果你有多个组件,你可以做更干净的事情,但这是我正在使用的。

你应该可以为自己复制这些文件,只需调整字符串使其工作。

0

有你需要做的几件事情:

  • 要获得TargetDirectoryPage的过去,你可以通过添加该代码 installer.setValue("RemoveTargetDir", false)

  • 自定义用户界面(或消息框)实现,让您来运行这段代码。该UI应该插入TargetDirectoryPage之后。 // you need to append .exe on the maintenance for windows installation installer.execute(installer.findPath(installer.value("MaintenanceToolName"), installer.value("TargetDir")));

+0

这让我走上了正确的道路,因为维护工具的运行就像这样。但是,“RemoveTargerDir”不会执行任何操作。看到我的答案为我提出的解决方案。 – rationalcoder