[processstarter] Handle Elastic and AdvantageScope (#8068)

Since they are in different directories, they need to be special cased
This is needed to support wpilibsuite/WPILibInstaller-Avalonia#492,
since those are currently handled by special scripts.
This commit is contained in:
sciencewhiz
2025-07-17 21:18:27 -07:00
committed by GitHub
parent 2875fd7d7c
commit 8799733838
6 changed files with 157 additions and 7 deletions

View File

@@ -2,6 +2,8 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "main.h"
#include <poll.h>
#include <spawn.h>
#include <sys/syscall.h>
@@ -11,7 +13,6 @@
#include <climits>
#include <cstdio>
#include <cstring>
#include <filesystem>
#include <string>
int main(int argc, char* argv[]) {
@@ -42,6 +43,22 @@ int main(int argc, char* argv[]) {
return 1;
}
if (exePath.stem() == (L"AdvantageScope")) {
std::filesystem::path AdvantageScopePath{
exePath.parent_path().parent_path() / L"advantagescope" /
L"advantagescope-wpilib"};
return StartExeTool(AdvantageScopePath);
} else if (exePath.stem() == (L"Elastic")) {
std::filesystem::path ElasticPath{exePath.parent_path().parent_path() /
L"elastic" / L"elastic_dashboard"};
return StartExeTool(ElasticPath);
} else {
return StartJavaTool(exePath);
}
}
int StartJavaTool(std::filesystem::path& exePath) {
pid_t pid = 0;
std::filesystem::path jarPath{exePath};
jarPath.replace_extension("jar");
std::filesystem::path parentPath{exePath.parent_path()};
@@ -53,10 +70,10 @@ int main(int argc, char* argv[]) {
std::filesystem::path Java = toolsFolder / "jdk" / "bin" / "java";
pid = 0;
std::string data = jarPath;
std::string jarArg = "-jar";
char* const arguments[] = {jarArg.data(), data.data(), nullptr};
char* const arguments[] = {Java.generic_string().data(), jarArg.data(),
data.data(), nullptr};
int status =
posix_spawn(&pid, Java.c_str(), nullptr, nullptr, arguments, environ);
@@ -85,3 +102,22 @@ int main(int argc, char* argv[]) {
struct pollfd pfd = {childPid, POLLIN, 0};
return poll(&pfd, 1, 3000);
}
int StartExeTool(std::filesystem::path& exePath) {
char* const arguments[] = {nullptr};
pid_t pid = 0;
int status =
posix_spawn(&pid, exePath.c_str(), nullptr, nullptr, arguments, environ);
if (status != 0) {
return 1;
}
int childPid = syscall(SYS_pidfd_open, pid, 0);
if (childPid <= 0) {
return 1;
}
struct pollfd pfd = {childPid, POLLIN, 0};
return poll(&pfd, 1, 5000);
}

View File

@@ -0,0 +1,11 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <filesystem>
int StartExeTool(std::filesystem::path& exePath);
int StartJavaTool(std::filesystem::path& exePath);
int main(int argc, char* argv[]);

View File

@@ -0,0 +1,11 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <filesystem>
int StartExeTool(std::filesystem::path& exePath);
int StartJavaTool(std::filesystem::path& exePath);
int main(int argc, char* argv[]);

View File

@@ -3,8 +3,10 @@
// the WPILib BSD license file in the root directory of this project.
#import <Foundation/Foundation.h>
#include "main.h"
#include <iostream>
#include <string>
#include <filesystem>
int main(int argc, char* argv[]) {
(void)argc;
@@ -28,6 +30,24 @@ int main(int argc, char* argv[]) {
return 1;
}
if (exePath.stem() == (L"AdvantageScope")) {
std::filesystem::path AdvantageScopePath{
exePath.parent_path().parent_path() / L"advantagescope" /
L"Advantagescope (WPILib).app" / L"Contents" / L"MacOS" /
L"advantagescope"};
return StartExeTool(AdvantageScopePath);
} else if (exePath.stem() == (L"Elastic")) {
std::filesystem::path ElasticPath{exePath.parent_path().parent_path() /
L"elastic" / L"elastic_dashboard.app" /
L"Contents" / L"MacOS" /
L"elastic_dashboard"};
return StartExeTool(ElasticPath);
} else {
return StartJavaTool(exePath);
}
}
int StartJavaTool(std::filesystem::path& exePath) {
std::filesystem::path jarPath{exePath};
jarPath.replace_extension("jar");
std::filesystem::path parentPath{exePath.parent_path()};
@@ -78,3 +98,22 @@ int main(int argc, char* argv[]) {
return task.running ? 0 : 1;
}
int StartExeTool(std::filesystem::path& exePath) {
std::cout << "exePath: " << exePath.c_str() << std::endl;
NSTask* task = [[NSTask alloc] init];
task.launchPath = [NSString stringWithFormat:@"%s", exePath.c_str()];
// task.arguments = Arguments;
task.terminationHandler = ^(NSTask* t) {
(void)t;
CFRunLoopStop(CFRunLoopGetMain());
};
if (![task launchAndReturnError:nil]) {
return 1;
}
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 3, false);
return task.running ? 0 : 1;
}

View File

@@ -2,9 +2,7 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include <filesystem>
#include "Windows.h"
#include "main.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR pCmdLine, int nCmdShow) {
@@ -29,6 +27,24 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
return 1;
}
if (ExePath.stem() == (L"AdvantageScope")) {
std::filesystem::path AdvantageScopePath{
ExePath.parent_path().parent_path() / L"advantagescope" /
L"AdvantageScope (WPILib).exe"};
return StartExeTool(AdvantageScopePath);
} else if (ExePath.stem() == (L"Elastic")) {
std::filesystem::path ElasticPath{ExePath.parent_path().parent_path() /
L"elastic" / L"elastic_dashboard.exe"};
return StartExeTool(ElasticPath);
} else {
return StartJavaTool(ExePath);
}
}
int StartJavaTool(std::filesystem::path& ExePath) {
WCHAR ExePathRaw[1024];
DWORD Status;
std::filesystem::path JarPath{ExePath};
JarPath.replace_extension(L"jar");
std::filesystem::path ParentPath{ExePath.parent_path()};
@@ -83,3 +99,25 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
return Status == WAIT_TIMEOUT ? 0 : 1;
}
int StartExeTool(std::filesystem::path& ExePath) {
STARTUPINFOW StartupInfo;
PROCESS_INFORMATION ProcessInfo;
DWORD Status;
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);
ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
if (!CreateProcessW(ExePath.c_str(), NULL, NULL, NULL, FALSE, 0, NULL, NULL,
&StartupInfo, &ProcessInfo)) {
return 1;
}
Status =
WaitForSingleObject(ProcessInfo.hProcess, 5000); // Wait for 5 seconds
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
return Status == WAIT_TIMEOUT ? 0 : 1;
}

View File

@@ -0,0 +1,15 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <windows.h>
#include <filesystem>
#include <string>
int StartExeTool(std::filesystem::path& ExePath);
int StartJavaTool(std::filesystem::path& ExePath);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR pCmdLine, int nCmdShow);