From 989c44891d7b60063cc0a169db4f81ea03c6c5b5 Mon Sep 17 00:00:00 2001 From: Zengtudor Date: Fri, 16 Aug 2024 14:29:02 +0800 Subject: [PATCH] update --- src/main.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 17 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6b0d6d3..b90852a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -59,10 +59,18 @@ struct Test{ } }; -struct ProgramRet{ - time_point start; - time_point end; -}; +#ifdef _WIN32 + struct ProgramRet{ + time_point start; + time_point end; + }; + void executeCommandWithRedirect(const std::string &command, const std::string &inputFile, const std::string &outputFile); +#else + struct ProgramRet{ + time_point start; + time_point end; + }; +#endif template T getValueOrPanic(T value); @@ -141,25 +149,35 @@ int main(int argc, char* argv[]) { } printValue(testsPath) const string exePathStr = getProtectPath(exePath); - for(auto i:tests){ - tasks.push([i,&exePathStr,&testsPath]()->ProgramRet{ - string commands; - std::stringstream ss; - ss<>id_str; - path outPath = testsPath/(id_str+".out") ; - commands = commands+exePathStr+" < "+getProtectPath(i.in)+" > "+getProtectPath(outPath); - LOG(commands) + for (auto i : tests) { + tasks.push([i, &exePathStr, &testsPath]() -> ProgramRet { + string id_str = std::to_string(i.id); + path outPath = testsPath / (id_str + ".out"); + + // 构建命令 + string commands = exePathStr + " < " + getProtectPath(i.in) + " > " + getProtectPath(outPath); + + // 输出构建的命令进行调试 + LOG(commands); + + // 执行命令 auto start = high_resolution_clock::now(); - system(commands.c_str()); - auto end=high_resolution_clock::now(); + #ifdef _WIN32 + executeCommandWithRedirect(commands, getProtectPath(i.in), getProtectPath(outPath)); + #else + system(commands.c_str()) + #endif + auto end = high_resolution_clock::now(); + + // AS_EM(result, 0,"error in exec commands") + return ProgramRet{ - .start=start, + .start = start, .end = end }; }); } + while(tasks.size()>0){ auto i = tasks.front(); tasks.pop(); @@ -169,10 +187,60 @@ int main(int argc, char* argv[]) { } } +#ifdef _WIN32 + +void executeCommandWithRedirect(const std::string &command, const std::string &inputFile, const std::string &outputFile) { + // 创建输入输出文件的句柄 + HANDLE hInput = CreateFile(inputFile.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hInput == INVALID_HANDLE_VALUE) { + throw std::runtime_error("Failed to open input file: " + inputFile); + } + + HANDLE hOutput = CreateFile(outputFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hOutput == INVALID_HANDLE_VALUE) { + CloseHandle(hInput); + throw std::runtime_error("Failed to open output file: " + outputFile); + } + + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags |= STARTF_USESTDHANDLES; // 使用标准句柄 + si.hStdInput = hInput; + si.hStdOutput = hOutput; + si.hStdError = GetStdHandle(STD_ERROR_HANDLE); // 重定向错误输出 + + ZeroMemory(&pi, sizeof(pi)); + + // 将命令转换为 LPSTR 类型 + LPSTR cmd = const_cast(command.c_str()); + + // 创建进程 + if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { + CloseHandle(hInput); + CloseHandle(hOutput); + throw std::runtime_error("CreateProcess failed with error: " + std::to_string(GetLastError())); + } + + // 等待子进程结束 + WaitForSingleObject(pi.hProcess, INFINITE); + + // 关闭句柄 + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + CloseHandle(hInput); + CloseHandle(hOutput); +} + +#endif + + string getProtectPath(const std::filesystem::path &p){ return "\""+p.string()+"\""; } + template T getValueOrPanic(T value){ AS_NE(value, Json::nullValue)