6

我想中止 Qt Installer Framework 进程,这可以通过多种方式完成(按照 Qt 为此提供的示例,或者抛出未捕获的异常,或者只是注入无效命令以导致硬崩溃......)。但无论如何,退出代码似乎是0(即“成功”)!有什么方法可以使它成为 1 (或其他东西)?

我可以想到一些丑陋的、笨拙的替代方案来以编程方式评估这个过程的成功,但我真的希望这不是必需的......

4

1 回答 1

3

没有找到真正的解决方案,所以我这样做了......

基本上,我的解决方法是抛出未捕获的异常,并在“失败时退出”条件下写入错误日志文件。日志的存在表明发生了问题。如果没有这样的日志,那么安装成功。如果您只关心通过/失败,只需检查文件是否存在。否则,请阅读文件以获取详细信息。

在我的解决方案中,我允许客户端将参数传递给安装程序,为错误日志指定特定的路径/名称。如果未提供,它将写入临时目录上的默认路径。

请注意,除非我错了,否则我看不到在 QtIFW 脚本中直接写入文件、删除文件或解析临时路径的方法。所以,我只使用 shell 操作。我使用它们的方式是从 shell 返回路径分辨率,从而隐式允许在文件路径中使用环境变量。

  • 将以下内容粘贴到您的 QtIFW QScript 中:

这是完整的Windows特定解决方案:

function clearErrorLog() {
    var path = installer.value( "errlog", "%temp%\\installer.err" );
    var deleteCmd = "echo off && del \"" + path + "\" /q\necho " + path + "\n";
    var result = installer.execute( "cmd.exe", ["/k"], deleteCmd );
    if( result[1] != 0 ) 
        throw new Error("Clear error log failed.");
    try{
        var cmdOutLns = result[0].split("\n");
        path = cmdOutLns[cmdOutLns.length-2].trim();
    }
    catch(e){ path = ""; }
    if( path=="" || installer.fileExists( path ) ) 
        throw new Error("Clear error log failed. (file exists)");
    console.log("Cleared error log: " + path);
}

function writeErrorLog( msg ) {
    var path = installer.value( "errlog", "%temp%\\installer.err" );
    var writeCmd = "echo off && echo " + msg + " > \"" + path + "\"\necho " + path + "\n";
    var result = installer.execute( "cmd.exe", ["/k"], writeCmd );
    if( result[1] != 0 ) 
        throw new Error("Write error log failed.");
    try{
        var cmdOutLns = result[0].split("\n");
        path = cmdOutLns[cmdOutLns.length-2].trim();
    }
    catch(e){ path = ""; }
    if( path=="" || !installer.fileExists( path ) ) 
        throw new Error("Write error log failed. (file does not exists)");
    console.log("Wrote error log to: " + path);
}

function silentAbort( msg ) {
    writeErrorLog( msg );
    throw new Error( msg );
}

在脚本开始时,清除日志。

function Controller() {
    clearErrorLog();
   ...
}
  • 对于macOSLinux(至少大多数发行版应该很高兴):

将第一行替换为clearErrorLog()

var path = installer.value( "errlog", "/tmp/installer.err" );
var deleteCmd = "rm \"" + path + "\";echo " + path;
var result = installer.execute( "sh", ["-c", deleteCmd] );

并将第一行替换为writeErrorLog()

var path = installer.value( "errlog", "/tmp/installer.err" );
var writeCmd = "echo " + msg + " > \"" + path + "\";echo " + path;
var result = installer.execute( "sh", ["-c", writeCmd] );

如果要检查平台,systemInfo.kernelType将返回"winnt""linux""darwin"(对于 macOS)以及其他可能的值。

  • 当您要调用该机制时,请调用 silentAbort( msg ).

在 QtIWF 脚本中,没有主异常处理程序或诸如此类的东西,因此只要您没有将那个 silentAbort 函数嵌套在 try 块中,异常就会立即有效地终止程序。

为了明确说明要使用的路径,请使用“errlog”键作为参数启动安装程序,如下所示myinstaller.exe errlog=mylog.err:如果您不包含完整路径,则将使用当前工作目录。

如果需要,您可以自行删除日志。当然,在临时目录中也留下垃圾是很常见的(并不是说我真的很喜欢那个......)。

于 2019-04-21T17:17:49.730 回答