1
0
forked from BRT/arc

Fix for windows

This commit is contained in:
slava 2026-03-16 18:31:45 +07:00
parent 8ed25698e8
commit 10897164e9
5 changed files with 151 additions and 13 deletions

View File

@ -16,18 +16,27 @@ set(CMAKE_AUTOUIC ON)
add_compile_definitions(QT_MESSAGELOGCONTEXT)
if (WIN32)
# Определяем архитектуру: проверяем VCPKG triplet, CMAKE переменные и env
if (VCPKG_TARGET_TRIPLET MATCHES "arm64"
# Определяем целевую архитектуру.
# CMAKE_GENERATOR_PLATFORM (-A flag) самый надёжный способ определения при кросс-компиляции.
# На ARM64 хосте CMAKE_SYSTEM_PROCESSOR может быть "ARM64" даже при сборке под x64,
# поэтому сначала проверяем явные x64-признаки.
if (CMAKE_GENERATOR_PLATFORM STREQUAL "x64"
OR CMAKE_GENERATOR_PLATFORM STREQUAL "Win64"
OR VCPKG_TARGET_TRIPLET MATCHES "x64")
message(STATUS "Detected x64 target architecture")
set(CMAKE_PREFIX_PATH "C:/Qt/6.9.0/msvc2022_64")
list(APPEND CMAKE_PREFIX_PATH "C:/Users/User/.vcpkg-clion/vcpkg/installed/x64-windows")
set(Tesseract_DIR "C:/Users/User/.vcpkg-clion/vcpkg/installed/x64-windows/share/tesseract")
elseif (VCPKG_TARGET_TRIPLET MATCHES "arm64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64"
OR CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64"
OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "ARM64"
OR CMAKE_CXX_COMPILER MATCHES "arm64")
message(STATUS "Detected ARM64 target architecture")
set(CMAKE_PREFIX_PATH "C:/Qt/6.9.0/msvc2022_arm64")
list(APPEND CMAKE_PREFIX_PATH "C:/Users/User/.vcpkg-clion/vcpkg/installed/arm64-windows")
set(Tesseract_DIR "C:/Users/User/.vcpkg-clion/vcpkg/installed/arm64-windows/share/tesseract")
else ()
message(STATUS "Detected x64 target architecture")
message(STATUS "Detected x64 target architecture (default)")
set(CMAKE_PREFIX_PATH "C:/Qt/6.9.0/msvc2022_64")
list(APPEND CMAKE_PREFIX_PATH "C:/Users/User/.vcpkg-clion/vcpkg/installed/x64-windows")
set(Tesseract_DIR "C:/Users/User/.vcpkg-clion/vcpkg/installed/x64-windows/share/tesseract")

View File

@ -3,29 +3,60 @@
#include <qDebug>
#include <QString>
#include <QCoreApplication>
#include <QFileInfo>
AdbUtils::AdbUtils(QObject *parent) : QObject(parent) {
}
QString AdbUtils::adbPath() {
#ifdef Q_OS_WIN
return QCoreApplication::applicationDirPath() + "/tools/adb/windows/adb.exe";
QString path = QCoreApplication::applicationDirPath() + "/tools/adb/windows/adb.exe";
#else
return QCoreApplication::applicationDirPath() + "/tools/adb/macos/adb";
QString path = QCoreApplication::applicationDirPath() + "/tools/adb/macos/adb";
#endif
static bool checked = false;
if (!checked) {
checked = true;
QFileInfo fi(path);
if (!fi.exists()) {
qWarning() << "[AdbUtils] adb not found at:" << path;
} else if (!fi.isExecutable()) {
qWarning() << "[AdbUtils] adb is not executable:" << path;
} else {
qDebug() << "[AdbUtils] adb path:" << path;
}
}
return path;
}
QString AdbUtils::adbDir() {
return QFileInfo(adbPath()).absolutePath();
}
bool AdbUtils::startProcess(const QString &program, const QStringList &args,
QString *stdOut, QString *stdErr) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(program, args);
if (!process.waitForFinished() ||
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start process:" << program << args
<< "error:" << process.errorString();
if (stdErr) {
*stdErr = process.errorString();
}
return false;
}
if (!process.waitForFinished(30000) ||
process.exitStatus() != QProcess::NormalExit ||
process.exitCode() != 0) {
if (stdErr) {
*stdErr = QString::fromUtf8(process.readAllStandardError());
}
qWarning() << "[AdbUtils] Process failed:" << program << args
<< "exitCode:" << process.exitCode()
<< "stderr:" << (stdErr ? *stdErr : QString::fromUtf8(process.readAllStandardError()));
return false;
}
@ -45,9 +76,36 @@ bool AdbUtils::startProcess(const QString &program, const QStringList &args,
* @return [(id, status), ...]
*/
QList<QPair<QString, QString> > AdbUtils::getListDevices() {
const QString adb = adbPath();
const QString dir = adbDir();
// Убиваем чужой adb-сервер (возможно другой версии) и запускаем свой,
// чтобы избежать конфликта версий (например, scrcpy adb 35 vs bundled adb 36)
static bool serverRestarted = false;
if (!serverRestarted) {
serverRestarted = true;
QProcess kill;
kill.setWorkingDirectory(dir);
kill.start(adb, {"kill-server"});
kill.waitForFinished(5000);
qDebug() << "[AdbUtils] Killed existing adb server";
QProcess start;
start.setWorkingDirectory(dir);
start.start(adb, {"start-server"});
start.waitForFinished(10000);
qDebug() << "[AdbUtils] Started own adb server";
}
QProcess process;
process.start(adbPath(), {"devices"});
process.waitForFinished();
process.setWorkingDirectory(dir);
process.start(adb, {"devices"});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb devices:" << process.errorString();
return {};
}
process.waitForFinished(10000);
const QString output = process.readAllStandardOutput();
QList<QPair<QString, QString> > devices;
@ -76,10 +134,15 @@ QList<QPair<QString, QString> > AdbUtils::getListDevices() {
QString AdbUtils::tryToGetRunningAppPid(const QString &deviceId, const QString &packageName) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {
"-s", deviceId,
"shell", "pidof", packageName
});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb pidof:" << process.errorString();
return {};
}
process.waitForFinished();
QString pid = process.readAllStandardOutput();
return pid.replace("\n", "");
@ -87,6 +150,7 @@ QString AdbUtils::tryToGetRunningAppPid(const QString &deviceId, const QString &
bool AdbUtils::tryToStartApplication(const QString &deviceId, const QString &packageName) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {
"-s", deviceId,
"shell", "monkey",
@ -94,6 +158,10 @@ bool AdbUtils::tryToStartApplication(const QString &deviceId, const QString &pac
"-c", "android.intent.category.LAUNCHER",
"1"
});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb monkey:" << process.errorString();
return false;
}
process.waitForFinished();
const QString output = process.readAllStandardOutput();
@ -110,11 +178,16 @@ bool AdbUtils::tryToStartApplication(const QString &deviceId, const QString &pac
bool AdbUtils::tryToKillApplication(const QString &deviceId, const QString &packageName) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {
"-s", deviceId,
"shell", "am",
"force-stop", packageName
});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb force-stop:" << process.errorString();
return false;
}
process.waitForFinished();
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
}
@ -186,7 +259,13 @@ bool AdbUtils::takeScreenshot(const QString &deviceId, const QString &name) {
QByteArray AdbUtils::captureScreenshotBytes(const QString &deviceId) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {"-s", deviceId, "exec-out", "screencap", "-p"});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] captureScreenshotBytes failed to start for" << deviceId
<< "error:" << process.errorString();
return {};
}
if (!process.waitForFinished(10000) || process.exitCode() != 0) {
qWarning() << "[AdbUtils] captureScreenshotBytes failed for" << deviceId;
return {};
@ -217,11 +296,16 @@ bool AdbUtils::takeXmlDump(const QString &deviceId, const QString &name) {
bool AdbUtils::makeTap(const QString &deviceId, const int x, const int y) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {
"-s", deviceId,
"shell", "input",
"tap", QString::number(x), QString::number(y)
});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb tap:" << process.errorString();
return false;
}
process.waitForFinished();
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
}
@ -247,12 +331,17 @@ bool AdbUtils::enableAdbIMEKeyboard(const QString &deviceId) {
bool AdbUtils::inputAdbIMEText(const QString &deviceId, const QString &text) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {
"-s", deviceId,
"shell", "am", "broadcast",
"-a", "ADB_INPUT_TEXT",
"--es", "msg", text
});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb broadcast:" << process.errorString();
return false;
}
process.waitForFinished();
qDebug() << "[AdbUtils] inputAdbIMEText result:" << process.exitCode()
<< "output:" << process.readAllStandardOutput().trimmed()
@ -262,14 +351,20 @@ bool AdbUtils::inputAdbIMEText(const QString &deviceId, const QString &text) {
bool AdbUtils::disableAdbIMEKeyboard(const QString &deviceId) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {"-s", deviceId, "shell", "ime", "disable",
"com.android.adbkeyboard/.AdbIME"});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb ime disable:" << process.errorString();
return false;
}
process.waitForFinished();
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
}
bool AdbUtils::makeSwipe(const QString &deviceId, const int x1, const int y1, const int x2, const int y2) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(
adbPath(),
{
@ -280,50 +375,74 @@ bool AdbUtils::makeSwipe(const QString &deviceId, const int x1, const int y1, co
QString::number(x2), QString::number(y2)
}
);
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb swipe:" << process.errorString();
return false;
}
process.waitForFinished();
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
}
bool AdbUtils::inputText(const QString &deviceId, const QString &text) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {
"-s", deviceId,
"shell", "input",
"text", text
});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb input text:" << process.errorString();
return false;
}
process.waitForFinished();
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
}
bool AdbUtils::hideKeyboard(const QString &deviceId) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {
"-s", deviceId,
"shell", "input",
"keyevent", "111"
});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb keyevent:" << process.errorString();
return false;
}
process.waitForFinished();
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
}
bool AdbUtils::goBack(const QString &deviceId) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {
"-s", deviceId,
"shell", "input",
"keyevent", "4"
});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb keyevent:" << process.errorString();
return false;
}
process.waitForFinished();
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
}
QSet<QString> AdbUtils::getListApps(const QString &deviceId) {
QProcess process;
process.setWorkingDirectory(adbDir());
process.start(adbPath(), {
"-s", deviceId,
"shell", "pm list",
"packages", "-3"
});
if (!process.waitForStarted(5000)) {
qWarning() << "[AdbUtils] Failed to start adb pm list:" << process.errorString();
return {};
}
process.waitForFinished();
const QString output = process.readAllStandardOutput();

View File

@ -47,6 +47,7 @@ public:
static QSet<QString> getListApps(const QString &deviceId);
private:
static QString adbDir();
static bool startProcess(const QString &program, const QStringList &args,
QString *stdOut = nullptr, QString *stdErr = nullptr);
};

Binary file not shown.

View File

@ -3,6 +3,7 @@
#include <QSettings>
#include <QProcess>
#include <QFile>
#include <QFileInfo>
#include <QBuffer>
#include <qeventloop.h>
#include <QThread>
@ -350,10 +351,11 @@ QByteArray convertPngToJpeg(const QByteArray &pngData, const int quality = 90) {
QByteArray DeviceScreener::takeScreenshot(const QString &deviceId) {
QProcess process;
process.setWorkingDirectory(QFileInfo(AdbUtils::adbPath()).absolutePath());
QStringList arguments;
arguments << "-s" << deviceId << "exec-out" << "screencap" << "-p";
process.start("adb", arguments);
process.start(AdbUtils::adbPath(), arguments);
if (!process.waitForFinished(5000)) {
qWarning() << "ADB скриншот не завершился для" << deviceId;
@ -372,8 +374,14 @@ QByteArray DeviceScreener::takeScreenshot(const QString &deviceId) {
QList<QPair<QString, QString> > DeviceScreener::readAdbDevices() {
QProcess process;
process.start("adb", QStringList() << "devices");
process.waitForFinished();
process.setWorkingDirectory(QFileInfo(AdbUtils::adbPath()).absolutePath());
process.start(AdbUtils::adbPath(), QStringList() << "devices");
if (!process.waitForStarted(5000)) {
qWarning() << "[DeviceScreener] Failed to start adb devices:" << process.errorString();
return {};
}
process.waitForFinished(10000);
const QString output = process.readAllStandardOutput();
QList<QPair<QString, QString> > devices;
@ -412,7 +420,8 @@ DeviceInfo DeviceScreener::readDeviceInfo(const QString &deviceId, const bool is
auto runAdbCommand = [&](const QStringList &args) -> QString {
QProcess process;
process.start("adb", QStringList{"-s", deviceId} + args);
process.setWorkingDirectory(QFileInfo(AdbUtils::adbPath()).absolutePath());
process.start(AdbUtils::adbPath(), QStringList{"-s", deviceId} + args);
process.waitForFinished();
return QString::fromUtf8(process.readAllStandardOutput()).trimmed();
};