processthread.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #include "processthread.h"
  2. #include "appevent.h"
  3. #include "processmodel.h"
  4. #include "qjsonarray.h"
  5. #include "qjsonobject.h"
  6. #include <cwf/sqldatabasestorage.h>
  7. #include "api/processapi.h"
  8. #include "qjsonvalue.h"
  9. CWF::SqlDatabaseStorage storage("QSQLITE", "localhost", "postgres", "postgres", "1234", 5432);
  10. // 将 FILETIME 转换为 Unix 时间戳
  11. static qint64 fileTimeToUnixTimestamp(FILETIME ft)
  12. {
  13. // FILETIME 是自 1601 年以来的 100 毫微秒数
  14. ULARGE_INTEGER ull;
  15. ull.LowPart = ft.dwLowDateTime;
  16. ull.HighPart = ft.dwHighDateTime;
  17. // FILETIME 和 时间戳的 基础时间不一样
  18. // 转换为秒,并减去 1601 到 1970 年之间的秒数
  19. if (ull.QuadPart / 10000000LL > 11644473600LL) {
  20. qint64 timestamp = ull.QuadPart / 10000000LL - 11644473600LL;
  21. return timestamp;
  22. }
  23. return ull.QuadPart / 10000000LL;
  24. }
  25. void sendExitTime(qint64 updataTime)
  26. {
  27. ProcessModel processModel{storage};
  28. // 在数据库 获取 不是这个更新日期的数据
  29. CWF::SqlQueryManager qry(storage);
  30. qry.select("*", processModel.getTableName())
  31. .where(QString("updataTime != '%1' OR updataTime IS NULL").arg(updataTime));
  32. qry.prepare();
  33. QJsonObject jsonObject = qry.exec();
  34. QJsonArray jsonArray = qry.toJson();
  35. QJsonArray sendJsonArray;
  36. if (jsonArray.size() > 0) {
  37. for (const auto &json : jsonArray) {
  38. const QJsonObject object = json.toObject();
  39. QJsonObject sendObject;
  40. sendObject.insert("pid", object["pid"]);
  41. sendObject.insert("pid_name", object["processName"]);
  42. sendObject.insert("begin_time", object["creationTime"]);
  43. sendObject.insert("end_time", object["exitTime"]);
  44. sendObject.insert("last_check_time", object["updataTime"]);
  45. sendObject.insert("status", 1);
  46. sendObject.insert("notes", "");
  47. sendJsonArray.append(sendObject);
  48. }
  49. }
  50. // 上传 后 删除
  51. if (sendJsonArray.size() > 0) {
  52. TC::ProcessApi processApi(sendJsonArray);
  53. bool isSendok = processApi.post();
  54. if (isSendok) {
  55. // 移除发送到服务器的本地数据
  56. CWF::SqlQueryManager qry(storage);
  57. qry.remove(processModel.getTableName(),
  58. QString("updataTime != '%1' OR updataTime IS NULL").arg(updataTime));
  59. qry.prepare();
  60. QJsonObject jsonObject = qry.exec();
  61. QJsonArray jsonArray = qry.toJson();
  62. }
  63. }
  64. bool isok = false;
  65. QVariant timeVariant = AppEvent::instance()->configReadValue("ProcessOutTime", &isok);
  66. int time = 0;
  67. if (isok) {
  68. time = timeVariant.toLongLong();
  69. } else {
  70. // 服务器时间
  71. }
  72. if (time > 0) {
  73. CWF::SqlQueryManager qry(storage);
  74. qry.select("*", processModel.getTableName())
  75. .where(QString("(updataTime - lastAlertTime) > %1").arg(time));
  76. qry.prepare();
  77. QJsonObject jsonObject = qry.exec();
  78. QJsonArray jsonArray = qry.toJson();
  79. }
  80. // 提示
  81. // SELECT * FROM ProcessTime WHERE (updataTime - lastAlertTime) > 1565;
  82. }
  83. bool ProcessThread::upDataProcessSql()
  84. {
  85. std::vector<std::shared_ptr<ProcessMonitor::ProcessInfo>> timeProcessVector
  86. = processMonitor.checkProcesses();
  87. // 退出时间默认当前时间 然后更新
  88. auto exitTimestamp = QDateTime::currentSecsSinceEpoch();
  89. auto updataTimestamp = QDateTime::currentSecsSinceEpoch();
  90. QStringList sqlValues;
  91. for (auto timeProcess : timeProcessVector) {
  92. qint64 timestamp = fileTimeToUnixTimestamp(timeProcess->creationTime);
  93. ProcessModel processModel{storage};
  94. CWF::SqlQueryManager qry(storage);
  95. qry.select("*", processModel.getTableName())
  96. .where(QString("pid == '%1' AND processName == '%2'")
  97. .arg(timeProcess->pid)
  98. .arg(timeProcess->processName.c_str()));
  99. qry.prepare();
  100. QJsonObject jsonObject = qry.exec();
  101. if (jsonObject["success"].toBool()) {
  102. // 查询或者替换 ?
  103. QJsonArray array = qry.toJson();
  104. if (array.size() > 0) {
  105. // 替换
  106. for (const QJsonValue &info : array) {
  107. const QJsonObject object = info.toObject();
  108. //数据还原到 结构体
  109. processModel.buildFromJson(object);
  110. // 更新 结束时间
  111. processModel.setExitTime(exitTimestamp);
  112. processModel.setUpdataTime(updataTimestamp);
  113. processModel.save();
  114. }
  115. } else {
  116. // 插入数据
  117. processModel.setProcessName(timeProcess->processName.c_str());
  118. processModel.setPid(timeProcess->pid);
  119. processModel.setCreationTime(timestamp);
  120. processModel.setExitTime(exitTimestamp);
  121. processModel.setUpdataTime(updataTimestamp);
  122. processModel.setLastAlertTime(updataTimestamp);
  123. processModel.save();
  124. }
  125. }
  126. qDebug().noquote().nospace() << jsonObject << qry.toJson();
  127. // jsonObject.insert("begin_time", object["creationTime"]);
  128. // jsonObject.insert("end_time", object["exitTime"]);
  129. // jsonObject.insert("last_check_time", object["updataTime"]);
  130. // jsonObject.insert("status", 1);
  131. // jsonObject.insert("notes", "");
  132. // FILETIME ft = timeProcess->creationTime;
  133. // FILETIME currentTime;
  134. // GetSystemTimeAsFileTime(&currentTime);
  135. // ULARGE_INTEGER creation, current;
  136. // creation.LowPart = ft.dwLowDateTime;
  137. // creation.HighPart = ft.dwHighDateTime;
  138. // current.LowPart = currentTime.dwLowDateTime;
  139. // current.HighPart = currentTime.dwHighDateTime;
  140. // ULONGLONG elapsedSeconds = (current.QuadPart - creation.QuadPart) / 10000000;
  141. // // 计算天、小时、分钟和秒
  142. // ULONGLONG days = elapsedSeconds / 86400; // 1天 = 86400秒
  143. // ULONGLONG hours = (elapsedSeconds % 86400) / 3600; // 1小时 = 3600秒
  144. // ULONGLONG minutes = (elapsedSeconds % 3600) / 60; // 1分钟 = 60秒
  145. // ULONGLONG seconds = elapsedSeconds % 60; // 剩余秒数
  146. // // 打印进程的运行时间
  147. // qDebug() << QString::fromStdString(timeProcess->processName) //
  148. // << days << hours << minutes << seconds << timestamp;
  149. /*
  150. INSERT OR REPLACE INTO ProcessTime (pid, processName, creationTime, exitTime)
  151. VALUES
  152. (123, 'process1', strftime('%s', 'now'), strftime('%s', 'now')),
  153. (124, 'process2', strftime('%s', 'now'), strftime('%s', 'now')),
  154. (125, 'process3', strftime('%s', 'now'), strftime('%s', 'now'));
  155. */
  156. // sqlValues.append(QString("(%1,'%2',%3,%4,%5)")
  157. // .arg(timeProcess->pid) // pid
  158. // .arg(timeProcess->processName.c_str()) // 进程名
  159. // .arg(timestamp) // 开始时间戳
  160. // .arg(exitTimestamp) // 结束时间戳
  161. // .arg(updataTimestamp)); // 数据更新时间
  162. }
  163. // const QString query = QString(
  164. // R"(INSERT OR REPLACE INTO ProcessTime
  165. // (pid, processName, creationTime, exitTime, updataTime)
  166. // VALUES
  167. // %1)")
  168. // .arg(sqlValues.join(","));
  169. // // 使用上述插入或者替换
  170. // // 首先查找
  171. // QString where;
  172. // CWF::SqlQueryManager qry(storage);
  173. // QJsonObject jsonObject = qry.exec(query);
  174. // 发送更新后的数据
  175. sendExitTime(updataTimestamp);
  176. // if (jsonObject.contains("success")) {
  177. // if (jsonObject["success"].toBool()) {
  178. // return true;
  179. // }
  180. // }
  181. return false;
  182. }
  183. ProcessThread::ProcessThread(
  184. QObject *parent)
  185. : QThread{parent}
  186. {}
  187. void ProcessThread::run()
  188. {
  189. ProcessModel processModel{storage};
  190. processModel.updateDB();
  191. {
  192. const QString query = QString("CREATE UNIQUE INDEX %2_%3_unique ON %1 (%2, %3);")
  193. .arg(processModel.getTableName())
  194. .arg("pid")
  195. .arg("processName");
  196. CWF::SqlQuery qry(storage);
  197. qry.exec(query);
  198. }
  199. QElapsedTimer timer; // 创建高精度计时器
  200. timer.start(); // 启动计时器
  201. upDataProcessSql();
  202. while (true) {
  203. // 校验网络
  204. if (timer.elapsed() >= 30 * 1000) { // 检查是否经过1分钟
  205. timer.restart(); // 重新启动计时器
  206. upDataProcessSql();
  207. }
  208. msleep(1000); // 休息1秒
  209. }
  210. }