singleapplication.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // The MIT License (MIT)
  2. //
  3. // Copyright (c) Itay Grudev 2015 - 2018
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. #ifndef SINGLE_APPLICATION_H
  23. #define SINGLE_APPLICATION_H
  24. #include <QtCore/QtGlobal>
  25. #include <QtNetwork/QLocalSocket>
  26. #ifndef QAPPLICATION_CLASS
  27. #define QAPPLICATION_CLASS QCoreApplication
  28. #endif
  29. #include QT_STRINGIFY(QAPPLICATION_CLASS)
  30. class SingleApplicationPrivate;
  31. /**
  32. * @brief The SingleApplication class handles multiple instances of the same
  33. * Application
  34. * @see QCoreApplication
  35. */
  36. class SingleApplication : public QAPPLICATION_CLASS
  37. {
  38. Q_OBJECT
  39. using app_t = QAPPLICATION_CLASS;
  40. public:
  41. /**
  42. * @brief Mode of operation of SingleApplication.
  43. * Whether the block should be user-wide or system-wide and whether the
  44. * primary instance should be notified when a secondary instance had been
  45. * started.
  46. * @note Operating system can restrict the shared memory blocks to the same
  47. * user, in which case the User/System modes will have no effect and the
  48. * block will be user wide.
  49. * @enum
  50. */
  51. enum Mode {
  52. User = 1 << 0,
  53. System = 1 << 1,
  54. SecondaryNotification = 1 << 2,
  55. ExcludeAppVersion = 1 << 3,
  56. ExcludeAppPath = 1 << 4
  57. };
  58. Q_DECLARE_FLAGS(Options, Mode)
  59. /**
  60. * @brief Intitializes a SingleApplication instance with argc command line
  61. * arguments in argv
  62. * @arg {int &} argc - Number of arguments in argv
  63. * @arg {const char *[]} argv - Supplied command line arguments
  64. * @arg {bool} allowSecondary - Whether to start the instance as secondary
  65. * if there is already a primary instance.
  66. * @arg {Mode} mode - Whether for the SingleApplication block to be applied
  67. * User wide or System wide.
  68. * @arg {int} timeout - Timeout to wait in milliseconds.
  69. * @note argc and argv may be changed as Qt removes arguments that it
  70. * recognizes
  71. * @note Mode::SecondaryNotification only works if set on both the primary
  72. * instance and the secondary instance.
  73. * @note The timeout is just a hint for the maximum time of blocking
  74. * operations. It does not guarantee that the SingleApplication
  75. * initialisation will be completed in given time, though is a good hint.
  76. * Usually 4*timeout would be the worst case (fail) scenario.
  77. * @see See the corresponding QAPPLICATION_CLASS constructor for reference
  78. */
  79. explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000, const QString &userData = {} );
  80. ~SingleApplication() override;
  81. /**
  82. * @brief Returns if the instance is the primary instance
  83. * @returns {bool}
  84. */
  85. bool isPrimary() const;
  86. /**
  87. * @brief Returns if the instance is a secondary instance
  88. * @returns {bool}
  89. */
  90. bool isSecondary() const;
  91. /**
  92. * @brief Returns a unique identifier for the current instance
  93. * @returns {qint32}
  94. */
  95. quint32 instanceId() const;
  96. /**
  97. * @brief Returns the process ID (PID) of the primary instance
  98. * @returns {qint64}
  99. */
  100. qint64 primaryPid() const;
  101. /**
  102. * @brief Returns the username of the user running the primary instance
  103. * @returns {QString}
  104. */
  105. QString primaryUser() const;
  106. /**
  107. * @brief Returns the username of the current user
  108. * @returns {QString}
  109. */
  110. QString currentUser() const;
  111. /**
  112. * @brief Sends a message to the primary instance. Returns true on success.
  113. * @param {int} timeout - Timeout for connecting
  114. * @returns {bool}
  115. * @note sendMessage() will return false if invoked from the primary
  116. * instance.
  117. */
  118. bool sendMessage( const QByteArray &message, int timeout = 100 );
  119. /**
  120. * @brief Get the set user data.
  121. * @returns {QStringList}
  122. */
  123. QStringList userData() const;
  124. Q_SIGNALS:
  125. void instanceStarted();
  126. void receivedMessage( quint32 instanceId, QByteArray message );
  127. private:
  128. SingleApplicationPrivate *d_ptr;
  129. Q_DECLARE_PRIVATE(SingleApplication)
  130. void abortSafely();
  131. };
  132. Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options)
  133. #endif // SINGLE_APPLICATION_H