我已经能够为我的软件创建安装。但是,我不知道如何创建另一个可以更新以前安装的安装程序。
我已经更新了组件版本、软件版本和发布日期,但是每当我在预装软件的文件夹上运行第二次安装时 - 我得到The folder you selected already exists and contains an installation. Chose different target for installation.
非常欢迎任何有关如何使用 Qt 安装程序框架更新现有安装的提示!
我已经能够为我的软件创建安装。但是,我不知道如何创建另一个可以更新以前安装的安装程序。
我已经更新了组件版本、软件版本和发布日期,但是每当我在预装软件的文件夹上运行第二次安装时 - 我得到The folder you selected already exists and contains an installation. Chose different target for installation.
非常欢迎任何有关如何使用 Qt 安装程序框架更新现有安装的提示!
我也面临同样的问题。所以我下载了最新的快照并研究了样本。一个特别有用:dynamicpage
当用户选择现有位置时,我没有成功向用户显示弹出警告,因此我找到了解决方法:相反,在所选目录下显示了一个红色标签。
这并不是逐个组件更新组件的真正解决方案,但您将能够继续安装过程。
首先,我们需要替换默认页面“TargetDirectory”。
installerscript.qs
中,这是您需要添加的内容:// Constructor
function Component()
{
component.loaded.connect(this, Component.prototype.installerLoaded);
installer.setDefaultPageVisible(QInstaller.TargetDirectory, false);
}
// Utility function like QString QDir::toNativeSeparators(const QString & pathName) [static]
var Dir = new function () {
this.toNativeSparator = function (path) {
if (installer.value("os") == "win")
return path.replace(/\//g, '\\');
return path;
}
};
// Called as soon as the component was loaded
Component.prototype.installerLoaded = function()
{
if (installer.addWizardPage(component, "TargetWidget", QInstaller.TargetDirectory)) {
var widget = gui.pageWidgetByObjectName("DynamicTargetWidget");
if (widget != null) {
widget.targetDirectory.textChanged.connect(this, Component.prototype.targetChanged);
widget.targetChooser.clicked.connect(this, Component.prototype.chooseTarget);
widget.windowTitle = "Installation Folder";
widget.targetDirectory.text = Dir.toNativeSparator(installer.value("TargetDir"));
}
}
}
// Callback when one is clicking on the button to select where to install your application
Component.prototype.chooseTarget = function () {
var widget = gui.pageWidgetByObjectName("DynamicTargetWidget");
if (widget != null) {
var newTarget = QFileDialog.getExistingDirectory("Choose your target directory.", widget.targetDirectory.text);
if (newTarget != "") {
widget.targetDirectory.text = Dir.toNativeSparator(newTarget);
}
}
}
Component.prototype.targetChanged = function (text) {
var widget = gui.pageWidgetByObjectName("DynamicTargetWidget");
if (widget != null) {
if (text != "") {
widget.complete = true;
installer.setValue("TargetDir", text);
if (installer.fileExists(text + "/components.xml")) {
var warning = "<font color='red'>" + qsTr("A previous installation exists in this folder. If you wish to continue, everything will be overwritten.") + "</font>";
widget.labelOverwrite.text = warning;
} else {
widget.labelOverwrite.text = "";
}
return;
}
widget.complete = false;
}
}
这实际上不是真正的 .ui 文件,仅用于说明目的。在这个文件的末尾,我添加了一个名为labelOverwrite
. targetChanged
文本在回调中填充了红色消息。
<widget class="QWidget" name="TargetWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Please specify the folder where Miam-Player will be installed.</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="targetDirectory"/>
</item>
<item>
<widget class="QToolButton" name="targetChooser"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="labelOverwrite"/>
</item>
</layout>
</widget>
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>Miam-Player</DisplayName>
<Description>Miam-Player is the main program. It is required and cannot be unselected.</Description>
<Name>org.miamplayer.core</Name>
<Script>installscript.qs</Script>
...
<UserInterfaces>
<UserInterface>targetwidget.ui</UserInterface>
</UserInterfaces>
</Package>
Matthieu 的回答是正确的,此外,如果您想要一个问题对话框,请在installerscript.qs中使用此功能:
Component.prototype.targetChanged = function (text)
{
var widget = gui.currentPageWidget(); // get the current wizard page
var install = false;
if (widget != null)
{
if (text != "")
{
if (installer.fileExists(text + "/components.xml"))
{
var result = QMessageBox.question("quit.question", "Installer", "Do you want to overwrite previous installation?",
QMessageBox.Yes | QMessageBox.No);
if (result == QMessageBox.Yes)
{
install = true;
}
}
else
install = true;
}
else
install = false;
}
widget.complete = install;
if(install)
installer.setValue("TargetDir", text);
}
Controller.prototype.TargetDirectoryPageCallback = function()
{
var widget = gui.currentPageWidget();
widget.TargetDirectoryLineEdit.textChanged.connect(this, Controller.prototype.targetChanged);
Controller.prototype.targetChanged(widget.TargetDirectoryLineEdit.text);
}
Controller.prototype.targetChanged = function (text) {
installer.setValue("RemoveTargetDir", true);
if (text != "" && installer.fileExists(text + "/components.xml")) {
if(QMessageBox.question("OverwriteTargetDirectory", "Overwrite target directory", "Do you want to overwrite previous installation?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes) {
installer.setValue("RemoveTargetDir", false);
}
}
这很简单。您应该执行以下操作:
如果您没有安装程序文件夹,请查看Qt/Tools/QtInstallerFramework/3.0/examples/
. 对于这个例子,我制作了一个online
文件夹的副本,我将调用它my_installer_example
。
更新存储库以从packages_update
.
从my_installer_example
运行:
./../bin/repogen --update -p packages_update/repoForUpload
该标志--updade
允许将现有存储库 ( repoForUpload
) 作为输入,并且仅更改指定为附加参数的组件。
上传repoForUpload
到服务器,由config/config.xml
.
运行maintenancetool
位于文件夹安装。