Results 1 to 20 of 21

Thread: Add "Check for updates" feature

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Add "Check for updates" feature

    Hi,
    first of all sorry for this long post. I would like to add to my application the feature of the 3d title: check if there is a new version of the program or of the data files (mainly database) and eventually download and install the updates. I have searched the forum for a similar question but found only a discussion if integrate the "update" feature on the main program or in a separate one; all answers were for the latter. That topic solved one of the my problem. But now I have some other questions and since I don't never coded a internet application it was great if you can drive me to the right direction.

    First of all I have divided the work in steps according to the phases of the "update" progress.

    1) Check if there is an active internet connection: obviously the first step. What is the simplest way? A ping to the server is sufficient? Which qt4 method should I use?

    2) What is the best way for version checking? My project is hosted by sourceforge. The program should check for two packages: the main program (less updated) and the data files (more updates). The program is distributed for linux (only source code, no binary) and windows. The data files are common for the two OSs.

    2a) Should I add new packages to the project? (maybe myapp-update and myapp-data-update).

    2b) Which compression method should I use for packaging the updates. In linux it's not a problem, what about windows? I don't want more dependencies other than qt4. Maybe a self extracting package?

    3) If there is an update the main program calls the updater; this asks the user if download the updates.

    3a) Which qt4 method gives the current OS?

    3b) Which method I have to use for downloading?

    3c) Where I have to download the files? In a tmp folder, obviously; in linux is /tmp but in windows it can change: which qt4 method gives the current system temp folder?

    4) Once download is finished the updater asks if install the new files:

    4a) In linux only the data files should be installed (the binary must be compiled): so they are installed in the application folder in $HOME. Ok.

    4b) In windows: thanks to QApplication::applicationDirPath() I know where the application is installed; and there extract the binary. Where I have to put the data files? In the same directory is ok, or in the user profile subfolder? Which qt4 method gives the current user directory?


    Am I forgetting something else? Any help will be very appreciated.
    Giuseppe CalÃ

  2. #2
    Join Date
    Nov 2007
    Posts
    89
    Qt products
    Qt4
    Platforms
    Windows
    Thanked 21 Times in 18 Posts

    Default Re: Add "Check for updates" feature

    Quote Originally Posted by jiveaxe View Post
    1) Check if there is an active internet connection: obviously the first step. What is the simplest way? A ping to the server is sufficient? Which qt4 method should I use?
    Just try to connect. If it fails, then there is no active connection.

    2b) Which compression method should I use for packaging the updates. In linux it's not a problem, what about windows? I don't want more dependencies other than qt4. Maybe a self extracting package?
    Try looking to QByteArray::qCompress and QByteArray::qUncompress.

    3b) Which method I have to use for downloading?
    You can use QHttp or QFtp.

    3c) Where I have to download the files? In a tmp folder, obviously; in linux is /tmp but in windows it can change: which qt4 method gives the current system temp folder?
    You can use QTemporaryFile.


    4b) In windows: thanks to QApplication::applicationDirPath() I know where the application is installed; and there extract the binary. Where I have to put the data files? In the same directory is ok, or in the user profile subfolder? Which qt4 method gives the current user directory?
    User data should be in AppData directory. You can obtain it with SHGetSpecialFolderPath, or with %APPDATA% env variable.

  3. The following user says thank you to bender86 for this useful post:

    wendelmaques (19th September 2010)

  4. #3
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Add "Check for updates" feature

    Quote Originally Posted by bender86 View Post
    Just try to connect. If it fails, then there is no active connection.
    Sorry, but what this mean? Have I to contact some server and evaluate the response?

    Quote Originally Posted by bender86 View Post
    If I compress the file with zip should QByteArray::qUncompress uncompress it?

    Quote Originally Posted by bender86 View Post
    You can use QTemporaryFile.
    Useful class. Thanks

    Regards
    Giuseppe CalÃ

  5. #4
    Join Date
    Nov 2007
    Posts
    89
    Qt products
    Qt4
    Platforms
    Windows
    Thanked 21 Times in 18 Posts

    Default Re: Add "Check for updates" feature

    Quote Originally Posted by jiveaxe View Post
    Sorry, but what this mean? Have I to contact some server and evaluate the response?
    Something like this:
    Qt Code:
    1. ...
    2.  
    3. QTcpSocket *socket = new QTcpSocket;
    4. connect(socket,SIGNAL(connected()),this,SLOT(slotConnected()));
    5. connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(slotError(QAbstractSocket::SocketError)));
    6. socket->connectToHost("updatehost",1212);
    7.  
    8. ...
    9.  
    10. void ClassName::slotConnected() {
    11. // Connected to server.
    12. // Get update files.
    13. }
    14.  
    15. void ClassName::slotError(QAbstractSocket::SocketError) {
    16. // NOT connected to server.
    17. QMessageBox::critical(0,QString(),tr("Can't connect to updates server!"));
    18. }
    To copy to clipboard, switch view to plain text mode 
    I don't know how to do using QHttp or QFtp, but you should follow this way:
    - Get update
    - If ok, install update
    - If error, tell user "Error!"


    Quote Originally Posted by jiveaxe View Post
    If I compress the file with zip should QByteArray::qUncompress uncompress it?
    I don't think so. I think you should read zip file, find compressed data, then uncompress it.
    Probably it is better to use some library.

  6. The following user says thank you to bender86 for this useful post:

    wendelmaques (19th September 2010)

  7. #5
    Join Date
    Jan 2006
    Posts
    371
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    14
    Thanked 18 Times in 17 Posts

    Default Re: Add "Check for updates" feature

    have in your site an xml file, and parse it. it will contain the latest version available.

  8. #6
    Join Date
    Jan 2006
    Posts
    44
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11
    Thanks
    9

    Default Re: Add "Check for updates" feature

    I would go with the following:

    Have an XML file on your site that the app downloads and parses to get the latest version number (and possibly date) along with a download URL.

    Use QHttp to get it, and QXml to parse it (dom or sax, your choice). use QHttp or QFtp to retrieve it. As far as compression, QByteArray::qUncompresscan deal with zipfiles but it takes extra work:

    Note: If you want to use this function to uncompress external data compressed using zlib, you first need to prepend four bytes to the byte array that contain the expected length of the uncompressed data encoded in big-endian order (most significant byte first).
    If you can not retrieve the download file, you would check for error as noted in a prior response and tell the user something like "Unable to retrieve update data. Please ensure your connection to the Internet is working and try again."

    Using the XML file gives you additional options such as including a description of the update to allow the user to decide if they want to install the update (or data). You would retrieve and parse the XML file and could then display a "Release notes" based on the contents. Personally I don't like apps that have a "blind update"; I like to know what changed and preferably an option ignore that update, install it, or not install it right now. But that's me.
    --
    The Real Bill

  9. #7
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Add "Check for updates" feature

    Thanks to all for the precious suggestions; now I can start working on.

    Regards
    Giuseppe CalÃ

  10. #8
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Add "Check for updates" feature

    I have just started and now the first problem.

    I got a segmentation fault with this code:

    Qt Code:
    1. ...
    2. if(!file.open()) {
    3. ...
    4. }
    5.  
    6. QUrl url("http://localhost/mysite");
    7. http = new QHttp;
    8. http->setHost(url.host(), url.port(80));
    9. http->get("/lastrelease.xml", &file);
    10. http->close();
    To copy to clipboard, switch view to plain text mode 

    If I comment http->get no more error. The temporary file is created with this path: /tmp//qt_temp.xxxx . Is it normal the double '/' ?

    Before somebody asks me, the local server is running and http://localhost/mysite/lastrelease.xml exists.

    If I use QFile instead of QTemporaryFile:
    Qt Code:
    1. QFile file("/tmp/lastrelease.xml");
    2. if(!file.open(QIODevice::ReadWrite)){...}
    To copy to clipboard, switch view to plain text mode 

    I have no segmentation fault at all but the file created in /tmp is empty. In the console I have this line:
    QIODevice::write: ReadOnly device
    Where is the mistake?

    Thanks
    Giuseppe CalÃ

  11. #9
    Join Date
    Nov 2007
    Posts
    89
    Qt products
    Qt4
    Platforms
    Windows
    Thanked 21 Times in 18 Posts

    Default Re: Add "Check for updates" feature

    Qt Code:
    1. ...
    2. if(!file.open()) {
    3. ...
    4. }
    5.  
    6. QUrl url("http://localhost/mysite");
    7. http = new QHttp;
    8. http->setHost(url.host(), url.port(80));
    9. http->get("/lastrelease.xml", &file);
    10. http->close();
    To copy to clipboard, switch view to plain text mode 

    I think it should be:
    Qt Code:
    1. http->setHost("localhost");
    2. http->get("/mysite/lastrelease.xml");
    To copy to clipboard, switch view to plain text mode 


    The temporary file is created with this path: /tmp//qt_temp.xxxx . Is it normal the double '/' ?
    Multiple / are ignored. You can check with ls /usr////src or similar.


    QIODevice::write: ReadOnly device
    Is /tmp writable? Try another directory (like $HOME).

  12. #10
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Add "Check for updates" feature

    Quote Originally Posted by bender86 View Post
    [CODE]...
    I think it should be:
    Qt Code:
    1. http->setHost("localhost");
    2. http->get("/mysite/lastrelease.xml");
    To copy to clipboard, switch view to plain text mode 
    It gives the same problem.

    I have also tried to get some page from the remote site, but nothing changes. Using QTemporaryFile gives the segmentation fault; with QFile an empty output.

    Try this:

    Qt Code:
    1. if(!file.open()) {
    2. QMessageBox::critical(0,QString(),tr("Can't open the file!"));
    3. }
    4.  
    5. QUrl url("http://www.bzip.org");
    6. http = new QHttp;
    7. http->setHost(url.host(), url.port(80));
    8. http->get("/docs.html", &file);
    9. http->close();
    To copy to clipboard, switch view to plain text mode 

    or this:

    Qt Code:
    1. QFile file("/tmp/output.html");
    2. if(!file.open(QIODevice::ReadWrite)) {
    3. QMessageBox::critical(0,QString(),tr("Can't open the file!"));
    4. }
    5.  
    6. QUrl url("http://www.bzip.org");
    7. http = new QHttp;
    8. http->setHost(url.host(), url.port(80));
    9. http->get("/docs.html", &file);
    10. http->close();
    To copy to clipboard, switch view to plain text mode 

    Quote Originally Posted by bender86 View Post
    Is /tmp writable? Try another directory (like $HOME).
    Of course /tmp is writable.

    Regards
    Giuseppe CalÃ

  13. #11
    Join Date
    Nov 2007
    Posts
    89
    Qt products
    Qt4
    Platforms
    Windows
    Thanked 21 Times in 18 Posts

    Default Re: Add "Check for updates" feature

    You have to close the QFile after writing into.
    You can catch QHttp::dataReadProgress(int done, int total). If done == total, then download is complete, and you can close file (you will need an event loop, so call QCoreApplication::exec()).
    Check also QHttp example.

    For QTemporaryFile, keep in mind that if you create it on stack, it will be destroyed when gone out of scope (usually after a }). If you pass his address to http.get("/file",&tempFile), QHttp will try to write to a invalid address.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.