C++启动和关闭外部exe

1.WinExec(
  lpCmdLine: LPCSTR; {文件名和参数; 如没指定路径会按以下顺序查找: 程序目录/当前目录/System32/Windows/PATH环境变量}
  uCmdShow: UINT     {启动选项}
): UINT;

WinExec("D:\\Program Files\\Test\\Test.exe", SW_SHOWMAXIMIZED);

2.ShellExecute函数原型及参数含义如下:

  ShellExecute(

  HWND hwnd,           //父窗口句柄 (如:NULL,Handle等)

  LPCSTR lpOperation, //操作类型 (如:"open")*要加英文双引号

  LPCSTR lpFile,           //要进行操作的文件或路径

  LPCSTR lpParameters, //当lpOperation为“explore”时指定要传递的参数,通常设为NULL

  LPCSTR lpDirectory,    //指定默认目录,通常设为NULL

  INT nShowCmd          //文件打开的方式,以通常方式还是最大化或最小化显示,一般为SW_SHOWNORMAL

  ) 
参数说明:
  ●hWnd:用于指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。例如,可以将其设置为应用程序主窗口句柄,即Application.Handle,也可以将其设置为桌面窗口句柄(用GetDesktopWindow函数获得)。

  ●Operation:用于指定要进行的操作。其中“open”操作表示执行由FileName参数指定的程序,或打开由FileName参数指定的文件或文件夹;“print”操作表示打印由FileName参数指定的文件;“explore”操作表示浏览由FileName参数指定的文件夹。当参数设为nil时,表示执行默认操作“open”。

  ●FileName:用于指定要打开的文件名、要执行的程序文件名或要浏览的文件夹名。

  ●Parameters:若FileName参数是一个可执行程序,则此参数指定命令行参数,否则此参数应为nil或PChar(0)。

  ●Directory:用于指定默认目录。

  ●ShowCmd:若FileName参数是一个可执行程序,则此参数指定程序窗口的初始显示方式,否则此参数应设置为0。

  若ShellExecute函数调用成功,则返回值为被执行程序的实例句柄。若返回值小于32,则表示出现错误。

ShellExecute(NULL,NULL,"E:/udpserver.exe", NULL, NULL, SW_SHOWNORMAL);

3.ShellExecuteEx:

SHELLEXECUTEINFO  ShExecInfo;
    ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    ShExecInfo.fMask = NULL;
    ShExecInfo.hwnd = NULL;
    ShExecInfo.lpVerb = NULL;
    ShExecInfo.lpFile = ("E:/udpserver.exe");        // 执行的程序名 
    ShExecInfo.lpParameters = NULL;
    ShExecInfo.lpDirectory = NULL;
    ShExecInfo.nShow = SW_MAXIMIZE;                // 全屏显示这个程序 
    ShExecInfo.hInstApp = NULL;
    ShellExecuteEx(&ShExecInfo);

4.函数原型:BOOL CreateProcess

  (
  LPCTSTR lpApplicationName, 
  LPTSTR lpCommandLine, 
  LPSECURITY_ATTRIBUTES lpProcessAttributes。
  LPSECURITY_ATTRIBUTES lpThreadAttributes, 
  BOOL bInheritHandles, 
  DWORD dwCreationFlags,
  LPVOID lpEnvironment, 
  LPCTSTR lpCurrentDirectory, 
  LPSTARTUPINFO lpStartupInfo, 
  LPPROCESS_INFORMATION lpProcessInformation 
  );

STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
    if (!CreateProcess(NULL,   // No module name (use command line)
        "notepad.exe",        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi)           // Pointer to PROCESS_INFORMATION structure
        )
    {
        printf("CreateProcess failed (%d).\n", GetLastError());
        cout << "ertror" << endl;
    }

结束进程:

std::string temp = std::string("TASKKILL /F /IM ") +exe_name;
    system(temp.c_str());

 

转载于:https://www.cnblogs.com/Sketch-liu/p/7277130.html

<think>我们正在讨论如何在C++启动关闭外部服务器。根据之前的引用,我们知道服务器通常是一个独立的进程,因此我们可以通过C++程序来启动终止这个进程。 在C++中,启动外部服务器通常意味着启动一个外部程序(例如,一个可执行文件或脚本),而关闭则意味着终止该进程。 ### 启动外部服务器 在C++中,启动外部程序可以使用标准库中的`system`函数(位于`<cstdlib>`中),或者使用更底层的API如`CreateProcess`(Windows)或`fork``exec`系列(Linux)。 #### 使用`system`函数(跨平台,但有限制) `system`函数会调用操作系统的命令行解释器(如Windows的cmd或Linux的shell)来执行命令。例如: ```cpp #include <cstdlib> int main() { // 启动服务器,假设服务器程序名为"server.exe"(Windows)或"./server"(Linux) system("server.exe"); // Windows // 或者 system("./server"); // Linux return 0; } ``` 但是,`system`会阻塞直到被调用的程序结束,这通常不是我们想要的,因为服务器需要长时间运行。因此,我们需要让服务器在后台运行(在Linux中,可以在命令后加`&`),或者在Windows中,使用`start`命令来启动新窗口。 #### Windows下使用`CreateProcess` 在Windows中,我们可以使用`CreateProcess`函数来启动一个进程,并且不阻塞当前程序。 ```cpp #include <windows.h> int main() { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); // 启动服务器进程 if (!CreateProcess( NULL, // 应用程序名(如果为NULL,则使用命令行) "server.exe", // 命令行 NULL, // 进程句柄不可继承 NULL, // 线程句柄不可继承 FALSE, // 不继承句柄 0, // 无创建标志 NULL, // 使用父进程环境 NULL, // 使用父进程工作目录 &si, // 指向STARTUPINFO的指针 &pi // 指向PROCESS_INFORMATION的指针 )) { // 处理错误 return 1; } // 可以在这里做其他事情,服务器在后台运行 // 关闭进程线程句柄(此时进程仍在运行) CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; } ``` #### Linux下使用`fork``exec` 在Linux中,我们可以使用`fork`创建子进程,然后在子进程中调用`exec`来执行服务器程序。 ```cpp #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid == 0) { // 子进程 execl("./server", "./server", NULL); // 替换为服务器程序 // 如果execl返回,说明出错了 exit(1); } else if (pid > 0) { // 父进程,可以继续执行其他任务 // 注意:这里我们不想等待子进程,所以可以忽略SIGCHLD信号或者使用非阻塞等待 } else { // fork失败 } return 0; } ``` ### 关闭外部服务器 关闭服务器意味着终止之前启动的进程。在Windows中,我们可以使用`TerminateProcess`函数;在Linux中,我们可以使用`kill`函数。 #### Windows下关闭进程 如果我们使用`CreateProcess`启动了进程,那么我们可以使用`TerminateProcess`来终止它。 ```cpp // 假设我们保存了pi.hProcess TerminateProcess(pi.hProcess, 0); CloseHandle(pi.hProcess); // 终止后关闭句柄 ``` 但是,如果我们没有保存进程句柄,那么我们需要先找到该进程的句柄。可以通过进程名或ID来查找。 #### Linux下关闭进程 在Linux中,我们可以使用`kill`函数发送信号(如`SIGTERM`)来终止进程。 ```cpp #include <signal.h> // 假设我们保存了子进程的pid kill(pid, SIGTERM); // 发送终止信号 ``` 如果我们没有保存pid,我们可以通过进程名来查找进程ID(例如使用`system("pkill server")`,但这样不太安全,因为可能杀死同名的其他进程)。 ### 注意事项 1. **跨平台**:如果需要跨平台,可以使用条件编译(`#ifdef _WIN32`)来区分不同平台的代码。 2. **安全关闭**:`TerminateProcess``kill`都是强制终止进程,可能导致资源未释放。更好的方式是让服务器程序提供一种关闭机制(例如通过发送关闭命令或信号),让服务器自己优雅关闭。 3. **进程管理**:如果服务器程序是控制台程序,在Windows中使用`CreateProcess`启动时,它可能会在后台运行(没有窗口)。在Linux中,使用`fork``exec`启动的进程默认在后台运行。 ### 优雅关闭 理想情况下,我们应该通过某种进程间通信(IPC)通知服务器关闭。例如: - 在服务器程序中监听一个特定的信号(如Linux的`SIGINT`或`SIGTERM`),然后在信号处理函数中清理资源并退出。 - 使用套接字、命名管道等向服务器发送关闭命令。 例如,在Linux中,我们可以使用`kill`发送`SIGTERM`信号,并在服务器程序中捕获该信号: ```cpp // 服务器程序中的信号处理 #include <signal.h> #include <cstdlib> volatile sig_atomic_t stop = 0; void handle_signal(int signum) { stop = 1; } int main() { signal(SIGTERM, handle_signal); while (!stop) { // 服务器主循环 } // 清理资源 return 0; } ``` 在Windows中,我们可以使用事件(Event)或控制台控制事件(如`CTRL_C_EVENT`)来通知服务器关闭。 ### 总结 在C++启动关闭外部服务器,主要涉及进程的创建终止。我们可以使用平台特定的API(如Windows的`CreateProcess``TerminateProcess`,Linux的`fork/exec``kill`)来实现。为了更优雅地关闭,建议通过进程间通信机制通知服务器自行关闭。 §§相关问题§§ 1. 如何在C++中实现跨平台的进程管理? 2. 如何优雅地关闭服务器进程? 3. C++中如何实现进程间通信(IPC)?</think>在C++启动关闭外部服务器主要涉及进程管理技术。以下是具体实现方法: ### 一、启动外部服务器 #### 方法1:使用 `system()` 函数(简单但有限制) ```cpp #include <cstdlib> int main() { // 启动服务器(Windows/Linux通用) int result = system("path/to/server_executable &"); // Linux需加 & 表示后台运行 if (result != 0) { // 错误处理 } return 0; } ``` * 优点:跨平台简单调用 * 缺点:依赖系统shell,安全性低,无法精细控制进程[^4] #### 方法2:使用平台API(推荐) **Windows(`CreateProcess`):** ```cpp #include <windows.h> STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; if (CreateProcess( "C:\\server.exe", // 服务器路径 NULL, // 命令行参数 NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { // 成功启动 CloseHandle(pi.hThread); // pi.hProcess 用于后续关闭 } else { // 错误处理 } ``` **Linux(`fork` + `exec`):** ```cpp #include <unistd.h> #include <sys/types.h> pid_t pid = fork(); if (pid == 0) { // 子进程 execl("/path/to/server", "server", (char*)NULL); exit(EXIT_FAILURE); // 若exec失败 } else if (pid > 0) { // 父进程继续执行,pid为服务器进程ID } else { // fork失败 } ``` ### 二、关闭外部服务器 #### 方法1:终止进程 **Windows:** ```cpp TerminateProcess(pi.hProcess, 0); // 强制终止 CloseHandle(pi.hProcess); ``` **Linux:** ```cpp kill(pid, SIGTERM); // 发送终止信号 // 或 kill(pid, SIGKILL); // 强制终止 ``` #### 方法2:优雅关闭(需服务器支持) 通过进程间通信(IPC)发送关闭指令: ```cpp // 示例:通过命名管道发送关闭命令 HANDLE pipe = CreateFile("\\\\.\\pipe\\ServerControl", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (pipe != INVALID_HANDLE_VALUE) { const char* cmd = "SHUTDOWN"; DWORD written; WriteFile(pipe, cmd, strlen(cmd), &written, NULL); CloseHandle(pipe); } ``` ### 三、关键注意事项 1. **权限问题**:需确保程序有权限启动/终止目标进程 2. **路径安全**:使用绝对路径避免路径解析错误 3. **防火墙配置**:云服务器需配置安全组规则[^2] 4. **服务器状态监控**:建议使用 `WaitForSingleObject`(Win) 或 `waitpid`(Linux) 监控进程状态 5. **优雅关闭**:优先使用IPC通知服务器自行清理资源,避免强制终止导致数据损坏 ### 四、完整示例(Windows) ```cpp #include <windows.h> int main() { // 启动服务器 PROCESS_INFORMATION pi; STARTUPINFO si = { sizeof(si) }; CreateProcess("myserver.exe", NULL, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi); // ... 其他操作 ... // 优雅关闭(假设服务器监听控制命令) TerminateProcess(pi.hProcess, 0); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; } ``` > **重要提示**:生产环境建议使用进程管理框架(如Boost.Process)或实现守护进程监控机制,确保服务器异常退出后能自动重启[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值