singleapplication.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. {
  53. User = 1 << 0,
  54. System = 1 << 1,
  55. SecondaryNotification = 1 << 2,
  56. ExcludeAppVersion = 1 << 3,
  57. ExcludeAppPath = 1 << 4
  58. };
  59. Q_DECLARE_FLAGS(Options, Mode)
  60. /**
  61. * @brief Intitializes a SingleApplication instance with argc command line
  62. * arguments in argv
  63. * @arg {int &} argc - Number of arguments in argv
  64. * @arg {const char *[]} argv - Supplied command line arguments
  65. * @arg {bool} allowSecondary - Whether to start the instance as secondary
  66. * if there is already a primary instance.
  67. * @arg {Mode} mode - Whether for the SingleApplication block to be applied
  68. * User wide or System wide.
  69. * @arg {int} timeout - Timeout to wait in milliseconds.
  70. * @note argc and argv may be changed as Qt removes arguments that it
  71. * recognizes
  72. * @note Mode::SecondaryNotification only works if set on both the primary
  73. * instance and the secondary instance.
  74. * @note The timeout is just a hint for the maximum time of blocking
  75. * operations. It does not guarantee that the SingleApplication
  76. * initialisation will be completed in given time, though is a good hint.
  77. * Usually 4*timeout would be the worst case (fail) scenario.
  78. * @see See the corresponding QAPPLICATION_CLASS constructor for reference
  79. */
  80. explicit SingleApplication(int& argc,
  81. char* argv[],
  82. bool allowSecondary = false,
  83. Options options = Mode::User,
  84. int timeout = 1000);
  85. ~SingleApplication() override;
  86. /**
  87. * @brief Returns if the instance is the primary instance
  88. * @returns {bool}
  89. */
  90. bool isPrimary();
  91. /**
  92. * @brief Returns if the instance is a secondary instance
  93. * @returns {bool}
  94. */
  95. bool isSecondary();
  96. /**
  97. * @brief Returns a unique identifier for the current instance
  98. * @returns {qint32}
  99. */
  100. quint32 instanceId();
  101. /**
  102. * @brief Returns the process ID (PID) of the primary instance
  103. * @returns {qint64}
  104. */
  105. qint64 primaryPid();
  106. /**
  107. * @brief Returns the username of the user running the primary instance
  108. * @returns {QString}
  109. */
  110. QString primaryUser();
  111. /**
  112. * @brief Returns the username of the current user
  113. * @returns {QString}
  114. */
  115. QString currentUser();
  116. /**
  117. * @brief Sends a message to the primary instance. Returns true on success.
  118. * @param {int} timeout - Timeout for connecting
  119. * @returns {bool}
  120. * @note sendMessage() will return false if invoked from the primary
  121. * instance.
  122. */
  123. bool sendMessage(const QByteArray& message, int timeout = 100);
  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