windowsqtclucene

Using a Qt Help file in an installed app


I develop a Qt application for windows, and the help file was generated in qch format with the qhc collection file. The help was embedded in the application using QHelpEngine. The help files are put in the same folder as the application executable, and this works well for dev builds.

But when we deploy the application in "Program Files" using a WiX installer, the documentation works but the search function fails, and I get a warning:

virtual void fulltextsearch::clucene::QHelpSearchIndexWriter::run(): Failed because of CLucene exception.

On the dev build, it seems that CLucene create some index files in the help file folder. Here it cannot, since the help file is in the installation folder, and the standard user cannot write there.

Is the error related to missing index file creation rights? How can I make CLucene write to the User folder instead?

Thanks


Solution

  • I found the solution by looking into assistant source code.

    CLucene always writes its cache to the same folder as the .qhc

    Qt Assistant handles this by not opening the main qhc directly. It copies it to the user profile (Under windows, in C:\User\Username\appdata\Local\assistant) updating the .qch paths accordingly, and then open this user specific file.

    I implemented the same approach and it works like a charm. You don't even have to deploy a qhc in the installer, you can directly create one by calling QHelpEngine with a path which does not exists, and register the qch files using registerDocumentation

    So the best way I have found is:

    1. Create a QHelpEngine with the path of a .qhc file which may not exist, but in a folder which exists and is writable. I use QStandardPaths::CacheLocation for this. Qt will create a .qhc file if required, or open it again.
    2. Iterate over all your .qch files and check if they are registered using engine->registeredDocumentations()
    3. For the documentations which are not registered, register them with engine->registerDocumentation
    4. Your engine is ready to use

    Here is my code with a single qch file:

    QString collPath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
    QDir().mkpath(collPath);
    collPath.append("/myapp.qhc");
    
    engine = new QHelpEngine(collPath, this);
    engine->setupData();
    
    QString docPath = QApplication::applicationDirPath()+"/myapp.qch";
    
    docNS = QHelpEngineCore::namespaceName(docPath);
    
    if(docNS.isEmpty() || !engine->registeredDocumentations().contains(docNS))
    {
        if(engine->registerDocumentation(docPath))
        {
            qInfo("Registered documentation %s", qPrintable(docPath));
        }
        else
        {
            qWarning("Could not register documentation file %s", qPrintable(docPath));
            qWarning("Help engine error : %s", qPrintable(engine->error()));
        }
    }
    
    //Now you can use "engine" in a text browser