diff --git a/processstarter/src/main/native/linux/main.cpp b/processstarter/src/main/native/linux/main.cpp index 7663292dea..1d2847967e 100644 --- a/processstarter/src/main/native/linux/main.cpp +++ b/processstarter/src/main/native/linux/main.cpp @@ -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 #include #include @@ -11,7 +13,6 @@ #include #include #include -#include #include 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); +} diff --git a/processstarter/src/main/native/linux/main.h b/processstarter/src/main/native/linux/main.h new file mode 100644 index 0000000000..227d666b7f --- /dev/null +++ b/processstarter/src/main/native/linux/main.h @@ -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 + +int StartExeTool(std::filesystem::path& exePath); +int StartJavaTool(std::filesystem::path& exePath); +int main(int argc, char* argv[]); diff --git a/processstarter/src/main/native/osx/main.h b/processstarter/src/main/native/osx/main.h new file mode 100644 index 0000000000..227d666b7f --- /dev/null +++ b/processstarter/src/main/native/osx/main.h @@ -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 + +int StartExeTool(std::filesystem::path& exePath); +int StartJavaTool(std::filesystem::path& exePath); +int main(int argc, char* argv[]); diff --git a/processstarter/src/main/native/osx/main.mm b/processstarter/src/main/native/osx/main.mm index 57b6678464..103603ec03 100644 --- a/processstarter/src/main/native/osx/main.mm +++ b/processstarter/src/main/native/osx/main.mm @@ -3,8 +3,10 @@ // the WPILib BSD license file in the root directory of this project. #import +#include "main.h" + +#include #include -#include 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; +} diff --git a/processstarter/src/main/native/windows/main.cpp b/processstarter/src/main/native/windows/main.cpp index 8b22aef0d8..5bb4c7f136 100644 --- a/processstarter/src/main/native/windows/main.cpp +++ b/processstarter/src/main/native/windows/main.cpp @@ -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 - -#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; +} diff --git a/processstarter/src/main/native/windows/main.h b/processstarter/src/main/native/windows/main.h new file mode 100644 index 0000000000..99877d2de2 --- /dev/null +++ b/processstarter/src/main/native/windows/main.h @@ -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 + +#include +#include + +int StartExeTool(std::filesystem::path& ExePath); +int StartJavaTool(std::filesystem::path& ExePath); +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPTSTR pCmdLine, int nCmdShow);