Important: Please read the Qt Code of Conduct -

Associating a file type to my program?

  • I have a multi tab text editor program and I want to associate a file type to it, so when we double click on the file, my program will open it in a new tab.

    From my understanding, I'll need to first register the file type and shell command in registry to:

    HKEY_CURRENT_USER\SOFTWARE\Classes\.myextension\Shell\Open\Command = "C:\my_program.exe" "%1".

    And then I can retrieve the file path in main(int argc, char *argv[]) in my c++ file with argv[0].

    But how do I keep my program at only one instance? Right now if I double click the file type, it will open a new instance of my program.

  • Lifetime Qt Champion

    @lansing said in Associating a file type to my program?:

    But how do I keep my program at only one instance?

    See this thread:

  • @jsulm

    Is there another alternative with less hassle? That's a lot of files to add for this feature.

  • Lifetime Qt Champion

    @lansing I don't know about any simpler solution

  • Moderators

    clone into your project source [] and include the .pri file in your .pro file

  • I have implemented the SingleApplication from here, and now double clicking on the text file will not open a second instance of the program. But it wouldn't open my file in a new tab.

  • @lansing
    Glancing through that link, you will have to implement what is in the Secondary Instances sub-section. Have you done so?

    Here is an example of how you would start a Secondary Instance send a message with the command line arguments to the primary instance and then shut down.

    That is what you want, isn't it?

  • @JonB

    Yes, so I got the secondary instance sending message to the first instance now. But it was sending a joined QByteArray and I don't know how to split it back in the slot.

        if( app.isSecondary() ) {
            app.sendMessage( app.arguments().join(' ').toUtf8() );        
            return 0;
        } else {

    The QByteArray I received is "my_program.exe D:\myfile.txt", how do I get the myfile.txt string?

  • Lifetime Qt Champion


    You can split your string however why to just send the relevant arguments rather than just all of them ?

  • @lansing
    Well QString::split() will be the simplest to handle "my_program.exe D:\myfile.txt". Though you might want to test with a space in the filename passed in, that might be more tricky, don't know if you can use the QString::split(const QRegularExpression &re) overload for that.

  • @SGaist said in Associating a file type to my program?:


    You can split your string however why to just send the relevant arguments rather than just all of them ?

    Oh yes you're right, I can just send app.sendMessage( argv[1] ). A new problem I see is that my file path that was sent will get shrink if it's too long. Like this
    C:\Users\Me\Desktop\MYFILE~1.TXT. Is this normal?

  • @lansing
    That's just a short (8.3) filename. Nothing you can do about it if that's what you receive. Should work.

  • @JonB

    How do I get the original name back? I tried QFileInfo(filePath).absoluteFilePath() but it still couldn't convert it.

  • @lansing
    I believe this will need a Windows-specific function call, and will not be available as a native Qt call. See GetLongPathNameA function (fileapi.h).

  • @JonB

    I've been trying for 2 days but I couldn't get it to work:


    int main(int argc, char *argv[])
        SingleApplication application( argc, argv, true);
        mainWindow = new MainWindow();
        if (application.isSecondary()) {
            if (application.arguments().count() == 2) {
                application.sendMessage( argv[1] );
            return 0;
        } else { 
            QObject::connect(&application, &SingleApplication::receivedMessage,
                        mainWindow , &MainWindow::slotReceivedMessage);


    namespace Win32 {
    #include "Windows.h"
    #define BUFSIZE 4096
    void MainWindow::slotReceivedMessage(int instanceId, QByteArray message)
        Win32::DWORD  retval=0;
        Win32::BOOL   success;
        Win32::TCHAR  buffer[BUFSIZE];
        Win32::TCHAR  buf[BUFSIZE];
        Win32::TCHAR** lppPart={NULL};
        // convert char * to wchar_t *
        const size_t WCHARBUF = 100;
        wchar_t message_t[WCHARBUF];
        Win32::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, message, -1, message_t, WCHARBUF);
        // get full filename from short filename
        retval = Win32::GetFullPathName(message_t, BUFSIZE, buffer, lppPart);
        QString filePath = QString::fromWCharArray(buffer);
        qDebug() << message;
        qDebug() << filePath;    

    Since GetFullPathName needs a wchar_t as input, I have to first convert the char to wchar_t, then convert it to full path name.

    But when printing out with debug, both the input(message) and output(filePath) are still the same. The GetFullPathName wasn't doing anything. What am I doing wrong?

Log in to reply