Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

เปิดโปรแกรมภายนอกด้วย C++: คำสั่ง system() และทางเลือกที่ดีกว่า

การเปิดโปรแกรม/แอปพลิเคชันภายนอกจาก C++ สามารถทำได้หลายวิธี ขึ้นอยู่กับ Platform และความต้องการ

1. วิธีง่ายที่สุด: std::system() (Portable แต่มีข้อจำกัด)

#include <cstdlib>
#include <iostream>

int main() {
    std::cout << "Opening Notepad..." << std::endl;
    int result = std::system("notepad.exe"); // Windows
    // int result = std::system("gedit");    // Linux
    // int result = std::system("open -a TextEdit"); // macOS
    
    if (result == -1) {
        std::cerr << "Failed to execute command" << std::endl;
    }
    return 0;
}

ข้อดี/ข้อเสีย

  • ✅ เรียบง่าย, Cross-platform (Command String แตกต่างตาม OS)
  • ❌ สร้าง Process ใหม่ผ่าน Shell (Overhead, Security Risk: Shell Injection)
  • ❌ ไม่ได้ Handle/Process ID กลับมา (ควบคุม Process ยาก)
  • ❌ Blocking: รอจน Process จบ (เว้นแต่ใช้ & ใน Unix)

2. Platform-Specific APIs (ควบคุมได้ดีกว่า)

Windows: CreateProcess() / ShellExecute()

#include <windows.h>
#include <iostream>

int main() {
    // ShellExecute - เปิดไฟล์/URL ด้วย Default App
    HINSTANCE result = ShellExecute(nullptr, "open", "notepad.exe", nullptr, nullptr, SW_SHOWNORMAL);
    if ((intptr_t)result <= 32) {
        std::cerr << "Failed: " << GetLastError() << std::endl;
    }
    return 0;
}

POSIX (Linux/macOS): fork() + exec() / posix_spawn()

#include <unistd.h>
#include <spawn.h>
#include <iostream>

extern char** environ;

int main() {
    pid_t pid;
    const char* args[] = {"gedit", nullptr};
    int status = posix_spawn(&pid, "/usr/bin/gedit", nullptr, nullptr, 
                             const_cast<char* const*>(args), environ);
    if (status == 0) {
        std::cout << "Launched PID: " << pid << std::endl;
    }
    return 0;
}

3. Modern C++: std::process (C++26 / Boost.Process)

C++26 จะมี std::process ส่วนปัจจุบันใช้ Boost.Process ได้:

#include <boost/process.hpp>
#include <iostream>

namespace bp = boost::process;

int main() {
    // Async launch
    bp::child c("notepad.exe");
    std::cout << "Notepad PID: " << c.id() << std::endl;
    
    // Wait หรือ Detach
    c.detach(); // หรือ c.wait();
    return 0;
}

ตารางเปรียบเทียบ

วิธีPortableControlAsyncSecurity
system()✅❌❌⚠️ Shell Injection
Win32 API❌✅✅✅
POSIX spawn❌ (Unix)✅✅✅
Boost.Process✅✅✅✅

สรุป

  • โปรแกรมเล็ก/Script/Prototype: ใช้ system() ได้ (ระวัง Input Sanitization)
  • Production/ต้องควบคุม Process: ใช้ Platform API หรือ Boost.Process
  • C++26 จะมี std::process เป็น Standard