1
0
forked from BRT/arc

Fix for windows

This commit is contained in:
slava 2026-04-06 19:09:39 +07:00
parent 013a00c972
commit d7c296ba42
4 changed files with 139 additions and 17 deletions

View File

@ -93,10 +93,26 @@ add_executable(ARC WIN32
${ANDROID_SOURCES}
views/bank/BankSettingsWindow.cpp
views/bank/BankSettingsWindow.h
views/bank/BankSetupWizard.cpp
views/bank/BankSetupWizard.h
views/log/FileLogWindow.cpp
views/log/FileLogWindow.h
views/log/LogDetailWindow.cpp
views/log/LogDetailWindow.h
database/dao/GeneralLogDAO.cpp
database/dao/GeneralLogDAO.h
android/dushanbe/CommonScript.cpp
android/dushanbe/CommonScript.h
android/dushanbe/GetCardInfoScript.cpp
android/dushanbe/GetCardInfoScript.h
android/dushanbe/GetLastTransactionsScript.cpp
android/dushanbe/GetLastTransactionsScript.h
android/dushanbe/GetProfileInfoScript.cpp
android/dushanbe/GetProfileInfoScript.h
android/dushanbe/LoginAndCheckAccountsScript.cpp
android/dushanbe/LoginAndCheckAccountsScript.h
android/dushanbe/ScreenXmlParser.cpp
android/dushanbe/ScreenXmlParser.h
)
elseif (APPLE)
add_executable(ARC
@ -108,10 +124,26 @@ elseif (APPLE)
${ANDROID_SOURCES}
views/bank/BankSettingsWindow.cpp
views/bank/BankSettingsWindow.h
views/bank/BankSetupWizard.cpp
views/bank/BankSetupWizard.h
views/log/FileLogWindow.cpp
views/log/FileLogWindow.h
views/log/LogDetailWindow.cpp
views/log/LogDetailWindow.h
database/dao/GeneralLogDAO.cpp
database/dao/GeneralLogDAO.h
android/dushanbe/CommonScript.cpp
android/dushanbe/CommonScript.h
android/dushanbe/GetCardInfoScript.cpp
android/dushanbe/GetCardInfoScript.h
android/dushanbe/GetLastTransactionsScript.cpp
android/dushanbe/GetLastTransactionsScript.h
android/dushanbe/GetProfileInfoScript.cpp
android/dushanbe/GetProfileInfoScript.h
android/dushanbe/LoginAndCheckAccountsScript.cpp
android/dushanbe/LoginAndCheckAccountsScript.h
android/dushanbe/ScreenXmlParser.cpp
android/dushanbe/ScreenXmlParser.h
)
endif ()
@ -132,7 +164,15 @@ if (WIN32)
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/eng.traineddata" DESTINATION "${CMAKE_BINARY_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/config.ini" DESTINATION "${CMAKE_BINARY_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/no_devices.png" DESTINATION "${CMAKE_BINARY_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tools/adb/windows" DESTINATION "${CMAKE_BINARY_DIR}/tools/adb")
# adb копируется в post-build чтобы не падать при configure если adb.exe занят
file(GLOB _adb_files "${CMAKE_CURRENT_SOURCE_DIR}/tools/adb/windows/*")
foreach(_adb_file ${_adb_files})
get_filename_component(_adb_fname "${_adb_file}" NAME)
add_custom_command(TARGET ARC POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:ARC>/tools/adb/windows"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_adb_file}" "$<TARGET_FILE_DIR:ARC>/tools/adb/windows/${_adb_fname}"
)
endforeach()
add_custom_command(TARGET ARC POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
@ -161,12 +201,17 @@ if (WIN32)
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_SOURCE_DIR}/no_devices.png"
"$<TARGET_FILE_DIR:ARC>/no_devices.png"
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_CURRENT_SOURCE_DIR}/tools/adb/windows"
"$<TARGET_FILE_DIR:ARC>/tools/adb/windows"
)
# Copy OpenSSL DLLs required for HTTPS (Qt SSL backend)
file(GLOB _openssl_dlls "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libssl*.dll"
"${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libcrypto*.dll")
foreach(_dll ${_openssl_dlls})
add_custom_command(TARGET ARC POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_dll}" "$<TARGET_FILE_DIR:ARC>"
)
endforeach()
elseif (APPLE)
target_link_libraries(ARC
Qt6::Widgets

View File

@ -1,4 +1,5 @@
#include <QApplication>
#include <QSslSocket>
#include <QThread>
#include "dao/MaterialDAO.h"
@ -11,6 +12,35 @@
#include <atomic>
#include <iostream>
#ifdef Q_OS_WIN
#include <windows.h>
#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib")
static LONG WINAPI crashHandler(EXCEPTION_POINTERS *ep) {
fprintf(stderr, "\n=== CRASH ===\n");
fprintf(stderr, "Exception code: 0x%08lX\n", ep->ExceptionRecord->ExceptionCode);
fprintf(stderr, "Exception addr: 0x%p\n", ep->ExceptionRecord->ExceptionAddress);
fprintf(stderr, "Thread ID: %lu\n", GetCurrentThreadId());
HANDLE process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
void *stack[64];
USHORT frames = CaptureStackBackTrace(0, 64, stack, NULL);
SYMBOL_INFO *symbol = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + 256, 1);
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
for (USHORT i = 0; i < frames; i++) {
SymFromAddr(process, (DWORD64)stack[i], 0, symbol);
fprintf(stderr, " [%2u] %s (0x%0llX)\n", i, symbol->Name, symbol->Address);
}
free(symbol);
SymCleanup(process);
fflush(stderr);
return EXCEPTION_EXECUTE_HANDLER;
}
#endif
#include <QPalette>
#include <QStyleFactory>
#include <thread>
@ -206,8 +236,9 @@ void messageHandler(
const QString source = context.function ? QString("%1:%2").arg(context.function).arg(context.line) : QString();
const char *func = context.function ? context.function : "unknown";
const QString line = QString("%1 [%2] [%3:%4] %5\n")
.arg(timestamp, level, context.function, QString::number(context.line), msg);
.arg(timestamp, level, func, QString::number(context.line), msg);
// Записываем в файл (потокобезопасно)
{
QMutexLocker locker(&logMutex);
@ -237,10 +268,21 @@ void messageHandler(
}
int main(int argc, char *argv[]) {
#ifdef Q_OS_WIN
SetUnhandledExceptionFilter(crashHandler);
#endif
QApplication app(argc, argv);
app.setApplicationName("ARC");
app.setWindowIcon(QIcon("arc.png"));
// Используем Schannel (нативный Windows TLS) — не требует OpenSSL DLL
if (QSslSocket::availableBackends().contains("schannel")) {
QSslSocket::setActiveBackend("schannel");
qDebug() << "[main] TLS backend set to schannel";
} else {
qDebug() << "[main] Available TLS backends:" << QSslSocket::availableBackends();
}
// Выбрать стиль Fusion + принудительная светлая тема
QApplication::setStyle(QStyleFactory::create("Fusion"));

View File

@ -9,6 +9,7 @@
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSslSocket>
#include <QProcess>
#include <QTemporaryFile>
#include <QPixmap>
@ -163,6 +164,7 @@ void FileLogWindow::updatePagination() {
}
void FileLogWindow::sendLogToTelegram() {
qDebug() << "[sendLogToTelegram] step 1: checking log file";
const QString logPath = QCoreApplication::applicationDirPath() + "/application.log";
if (!QFile::exists(logPath)) {
QMessageBox::warning(this, "Ошибка", "Файл application.log не найден");
@ -172,6 +174,7 @@ void FileLogWindow::sendLogToTelegram() {
m_sendBtn->setEnabled(false);
m_sendBtn->setText("Подготовка...");
qDebug() << "[sendLogToTelegram] step 2: creating tmp dir";
// Собираем временную папку для архива
const QString tmpDir = QDir::tempPath() + "/arc_logs_export";
QDir().mkpath(tmpDir);
@ -180,6 +183,7 @@ void FileLogWindow::sendLogToTelegram() {
QFile::remove(tmpDir + "/application.log");
QFile::copy(logPath, tmpDir + "/application.log");
qDebug() << "[sendLogToTelegram] step 3: exporting errors";
// 2. Экспортируем events с ошибками в errors.txt
const QList<EventInfo> errors = EventDAO::getAllEvents(EventStatus::Error);
if (!errors.isEmpty()) {
@ -201,6 +205,7 @@ void FileLogWindow::sendLogToTelegram() {
}
}
qDebug() << "[sendLogToTelegram] step 4: exporting event screenshots";
// 3. Экспортируем скриншоты ошибок из events
QDir().mkpath(tmpDir + "/screenshots");
int screenshotCount = 0;
@ -219,6 +224,7 @@ void FileLogWindow::sendLogToTelegram() {
}
}
qDebug() << "[sendLogToTelegram] step 5: exporting log screenshots";
// 3.5. Экспортируем скриншоты из general_logs (ошибки скриптов)
const QList<GeneralLogEntry> logErrors = GeneralLogDAO::getLogs(0, 100, {"WARNING", "CRITICAL", "FATAL"});
for (const GeneralLogEntry &gl : logErrors) {
@ -234,6 +240,7 @@ void FileLogWindow::sendLogToTelegram() {
}
}
qDebug() << "[sendLogToTelegram] step 6: creating archive with powershell";
// 4. Создаём архив
#ifdef Q_OS_WIN
const QString archivePath = QDir::tempPath() + "/arc_logs.zip";
@ -243,7 +250,12 @@ void FileLogWindow::sendLogToTelegram() {
archiver.start("powershell", QStringList()
<< "-NoProfile" << "-Command"
<< QString("Compress-Archive -Path '%1/*' -DestinationPath '%2' -Force").arg(tmpDir, archivePath));
archiver.waitForFinished(30000);
if (!archiver.waitForFinished(30000)) {
qWarning() << "[sendLogToTelegram] powershell archiver timeout/error:" << archiver.errorString();
}
qDebug() << "[sendLogToTelegram] step 6.1: archiver exit code:" << archiver.exitCode()
<< "stdout:" << archiver.readAllStandardOutput()
<< "stderr:" << archiver.readAllStandardError();
#else
const QString archivePath = QDir::tempPath() + "/arc_logs.zip";
QFile::remove(archivePath);
@ -256,6 +268,9 @@ void FileLogWindow::sendLogToTelegram() {
// Чистим временную папку
QDir(tmpDir).removeRecursively();
qDebug() << "[sendLogToTelegram] step 7: archive exists:" << QFile::exists(archivePath)
<< "path:" << archivePath;
if (!QFile::exists(archivePath)) {
QMessageBox::warning(this, "Ошибка", "Не удалось создать архив");
m_sendBtn->setEnabled(true);
@ -274,6 +289,19 @@ void FileLogWindow::sendLogToTelegram() {
return;
}
// Проверяем поддержку SSL
if (!QSslSocket::supportsSsl()) {
qWarning() << "[sendLogToTelegram] SSL not supported! Build:" << QSslSocket::sslLibraryBuildVersionString()
<< "Runtime:" << QSslSocket::sslLibraryVersionString();
QMessageBox::warning(this, "Ошибка", "SSL не поддерживается.\nНевозможно отправить логи через HTTPS.");
delete zipFile;
m_sendBtn->setEnabled(true);
m_sendBtn->setText("Отправить");
return;
}
qDebug() << "[sendLogToTelegram] SSL OK, sending...";
// Telegram Bot API
const QString botToken = "8256716069:AAFgZRB_0Y6KTpqFQmCxIlZiWdY5m2dR2D8";
const QString chatId = "-5177086220";
@ -304,8 +332,19 @@ void FileLogWindow::sendLogToTelegram() {
zipFile->setParent(multiPart);
multiPart->append(filePart);
qDebug() << "[sendLogToTelegram] step 8: creating network request";
auto *manager = new QNetworkAccessManager(this);
QNetworkReply *reply = manager->post(QNetworkRequest(url), multiPart);
// Принудительно используем Schannel (нативный Windows TLS) вместо OpenSSL
QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
sslConfig.setBackendConfigurationOption("SslProtocol", "TlsV1_2OrLater");
QNetworkRequest req(url);
req.setSslConfiguration(sslConfig);
qDebug() << "[sendLogToTelegram] step 9: posting to telegram..."
<< "SSL backend:" << QSslSocket::activeBackend();
QNetworkReply *reply = manager->post(req, multiPart);
qDebug() << "[sendLogToTelegram] step 10: post sent, waiting for reply";
multiPart->setParent(reply);
connect(reply, &QNetworkReply::finished, this, [this, reply, manager, archivePath]() {

View File

@ -31,21 +31,17 @@ LoaderWindow::LoaderWindow(QWidget *parent) : QWidget(parent) {
connect(networkService, &NetworkService::finished, networkService, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
connect(networkService, &NetworkService::finishedWithResult, [&](const int result) {
connect(networkService, &NetworkService::finishedWithResult, this, [this](const int result) {
m_checkResult = result;
if (m_checkResult == -1) {
if (timer) {
QMetaObject::invokeMethod(timer, "stop", Qt::QueuedConnection);
timer->stop();
}
QMetaObject::invokeMethod(this, [=]() {
emit loadingFinished(m_checkResult);
}, Qt::QueuedConnection);
emit loadingFinished(m_checkResult);
} else if (progressBar->value() >= 100) {
QMetaObject::invokeMethod(this, [=]() {
emit loadingFinished(m_checkResult);
}, Qt::QueuedConnection);
emit loadingFinished(m_checkResult);
}
});
}, Qt::QueuedConnection);
thread->start();
}