chore: sync from fn-registry agent
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
#include "chrome_launcher.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#ifdef _WIN32
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace navegator {
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef _WIN32
|
||||
const char* kChromePaths[] = {
|
||||
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
|
||||
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
|
||||
};
|
||||
|
||||
bool file_exists_w(const char* path) {
|
||||
DWORD attrs = GetFileAttributesA(path);
|
||||
return (attrs != INVALID_FILE_ATTRIBUTES) && !(attrs & FILE_ATTRIBUTE_DIRECTORY);
|
||||
}
|
||||
|
||||
std::string find_chrome() {
|
||||
for (const char* p : kChromePaths) {
|
||||
if (file_exists_w(p)) return p;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// Quote para argv en CreateProcess (rules de MSVCR / Chromium):
|
||||
// envolver en " y escapar las " internas con \" y los \ que preceden a " con \\.
|
||||
std::string quote_arg(const std::string& a) {
|
||||
if (a.empty()) return "\"\"";
|
||||
bool needs = a.find_first_of(" \t\"") != std::string::npos;
|
||||
if (!needs) return a;
|
||||
std::string out = "\"";
|
||||
int backslashes = 0;
|
||||
for (char c : a) {
|
||||
if (c == '\\') {
|
||||
++backslashes;
|
||||
out += c;
|
||||
} else if (c == '"') {
|
||||
// Duplicar las \\ acumuladas + escapar la "
|
||||
for (int i = 0; i < backslashes; ++i) out += '\\';
|
||||
backslashes = 0;
|
||||
out += "\\\"";
|
||||
} else {
|
||||
backslashes = 0;
|
||||
out += c;
|
||||
}
|
||||
}
|
||||
// Cerrar: duplicar \\ pendientes.
|
||||
for (int i = 0; i < backslashes; ++i) out += '\\';
|
||||
out += '"';
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
LaunchResult launch_chrome(const LaunchOpts& opts) {
|
||||
LaunchResult r;
|
||||
#ifndef _WIN32
|
||||
(void)opts;
|
||||
r.error = "launch_chrome: solo Windows en v0";
|
||||
return r;
|
||||
#else
|
||||
std::string chrome = opts.chrome_path.empty() ? find_chrome() : opts.chrome_path;
|
||||
if (chrome.empty()) {
|
||||
r.error = "chrome.exe no encontrado en Program Files";
|
||||
return r;
|
||||
}
|
||||
if (opts.user_data_dir.empty()) {
|
||||
r.error = "user_data_dir obligatorio para aislar perfil";
|
||||
return r;
|
||||
}
|
||||
|
||||
// Crear el directorio si no existe (ignoramos errores, Chrome se queja si no puede).
|
||||
CreateDirectoryA(opts.user_data_dir.c_str(), nullptr);
|
||||
|
||||
char port_buf[32];
|
||||
std::snprintf(port_buf, sizeof(port_buf), "--remote-debugging-port=%d", opts.port);
|
||||
|
||||
std::string cmd;
|
||||
cmd = quote_arg(chrome);
|
||||
cmd += " ";
|
||||
cmd += quote_arg(port_buf);
|
||||
cmd += " --remote-allow-origins=*";
|
||||
cmd += " ";
|
||||
cmd += quote_arg(std::string("--user-data-dir=") + opts.user_data_dir);
|
||||
cmd += " --no-first-run --no-default-browser-check";
|
||||
if (opts.headless) {
|
||||
cmd += " --headless=new --disable-gpu";
|
||||
}
|
||||
if (!opts.start_url.empty()) {
|
||||
cmd += " ";
|
||||
cmd += quote_arg(opts.start_url);
|
||||
} else {
|
||||
cmd += " about:blank";
|
||||
}
|
||||
|
||||
STARTUPINFOA si{};
|
||||
si.cb = sizeof(si);
|
||||
PROCESS_INFORMATION pi{};
|
||||
|
||||
// CreateProcess modifica el commandline buffer — copia mutable.
|
||||
std::string mutable_cmd = cmd;
|
||||
BOOL ok = CreateProcessA(
|
||||
nullptr,
|
||||
mutable_cmd.data(),
|
||||
nullptr, nullptr, FALSE,
|
||||
CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
|
||||
nullptr, nullptr, &si, &pi);
|
||||
if (!ok) {
|
||||
DWORD err = GetLastError();
|
||||
char buf[64];
|
||||
std::snprintf(buf, sizeof(buf), "CreateProcess failed (err=%lu)", (unsigned long)err);
|
||||
r.error = buf;
|
||||
return r;
|
||||
}
|
||||
r.ok = true;
|
||||
r.pid = (uint32_t)pi.dwProcessId;
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace navegator
|
||||
Reference in New Issue
Block a user