linux打开桌面软件(wps)、获取已打开的文件名(wps)

程序测试环境是:slackware系统,属于linux系统,有桌面。系统镜像是:slackware64-15.0-install-dvd.iso。c++代码实现。

编译命令是:

bash 复制代码
gcc -o main main.cpp -lstdc++ 

如下是测试代码demo,您可根据注释摘取自己需要的代码:

cpp 复制代码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <dirent.h>
#include <string>
#include <sys/wait.h>
#include <ranges>

// 打开默认软件
void open_wps(){
    pid_t pid = fork();
    if(pid == 0){
        const char* wpsCommand[] = {"vlc", nullptr};//wps(word)、et(excel)、wpspdf(pdf)、wpp(ppt)
        if(execvp(wpsCommand[0], (char* const*)wpsCommand) == -1){
            perror("failed to exec WPS");
            exit(EXIT_FAILURE);
        }else if(pid > 0){
            std::cout << "in main process" << std::endl;
        }else{
            perror("fork failed");
            exit(EXIT_FAILURE);
        }
    }
}

// 根据文件打开软件
void open_wps(const char* wpsType, const std::string& filePath) {
    // Check if the file exists
    if (access(filePath.c_str(), F_OK) == -1) {
        std::cerr << "Error: File does not exist." << std::endl;
        return;
    }

    // Fork a child process
    pid_t pid = fork();
    if (pid == -1) {
        std::cerr << "Error: Failed to fork." << std::endl;
        return;
    }

    if (pid == 0) {
        // Child process
        char *argv[] = {(char *)wpsType, (char *)filePath.c_str(), nullptr};
        if (execvp(argv[0], argv) == -1) {
            std::cerr << "Error: Failed to execute command." << std::endl;
            _exit(EXIT_FAILURE);
        }
    } else {
        // Parent process
    }
}

// 查找wps进程id
std::vector<int> find_wps_processes(){
    std::vector<int> wpsPids;
    DIR* dir{nullptr};
    struct dirent* ent;
    if((dir = opendir("/proc")) != nullptr){
        while((ent = readdir(dir)) != nullptr){
            if(isdigit(ent->d_name[0])){                
                std::string pidDir = "/proc/" + std::string(ent->d_name) + "/cmdline";                
                std::ifstream cmdlineFile(pidDir);
                std::string cmdline;
                std::getline(cmdlineFile, cmdline, '\0');
                std::cout << "pid info: " << pidDir << std::endl;
                std::cout << "cmdline: " << cmdline << std::endl;
                if(cmdline.find("wps") != std::string::npos || cmdline.find("wpp") != std::string::npos){
                    wpsPids.push_back(std::stoi(ent->d_name));
                }
            }
        }
        closedir(dir);
    }else{
        perror("could not open /proc directory");
    }
    return wpsPids;
}

std::string trim(const std::string& str) {
    size_t first = str.find_first_not_of(" \t\n\r\f\v"); // 查找第一个非空白字符的位置
    if (std::string::npos == first) {
        return ""; // 如果字符串全是空白字符,返回空字符串
    }
    size_t last = str.find_last_not_of(" \t\n\r\f\v"); // 查找最后一个非空白字符的位置
    return str.substr(first, (last - first + 1)); // 截取子串
}

// 打印已打开的文件信息
void print_opened_files(std::string type, int pid){
    std::string fdDir = "/proc/" + std::to_string(pid) + "/fd";
    DIR* dir;
    struct dirent* ent;
    if((dir =opendir(fdDir.c_str())) != nullptr){
        while ((ent = readdir(dir)) != nullptr)
        {
            if(ent->d_name[0] != '.'){
                std::string linkTarget = fdDir + "/" + ent->d_name;
                char filePath[PATH_MAX] = {0};
                ssize_t len = readlink(linkTarget.c_str(), filePath, sizeof(filePath) - 1);
                if(len != 1 && std::string(filePath).find(".~") == std::string::npos){
                    if((type == "wps" && std::string(filePath).find(".docx") != std::string::npos) ||
                    (type == "et" && std::string(filePath).find(".xlsx") != std::string::npos) ||
                    (type == "wpspdf" && std::string(filePath).find(".pdf") != std::string::npos) || 
                    (type == "wpp" && std::string(filePath).find(".ppt") != std::string::npos)){
                        size_t pos = std::string(filePath).find_last_of("/");
                        std::string fileName = std::string(filePath).substr(pos+1);
                        std::cout << "pid: " << pid << " " << fileName << std::endl;
                    }
                }
            }
        }
        closedir(dir);
    }else{
        perror("could not open directory");
    }
}

// 打印wps进程信息
void print_wps_print(){
    std::vector<int> wpsPids = find_wps_processes();
    for(int pid:wpsPids){
        std::cout << "wps process id:" << pid << std::endl;
        std::string statusPath = "/proc/" + std::to_string(pid) + "/status";
        std::ifstream statusFile(statusPath);
        std::string line;
        while(std::getline(statusFile, line)){
            int pos = line.find("Name");
            if(pos != std::string::npos){
                std::string name = trim(line.substr(pos+5));
                std::cout << pid << ": " << name << std::endl;
                print_opened_files(name, pid);
                break;
            }            
        }
    }
}


int main(){
    open_wps();
    sleep(2);

    std::string wordFilePath = "/home/gaowb/Documents/开发记录.docx";
    std::string wordFilePath2 = "/home/gaowb/Documents/开发记录2.docx";
    std::string excelFilePath = "/home/gaowb/Documents/C++西安计划安排-2.xlsx";
    std::string pdfFilePath = "/home/gaowb/Documents/slackware中文手册.pdf";

    // Open Word document
    open_wps("wps", wordFilePath);
    open_wps("wps", wordFilePath2);
    sleep(2);

    // Open Excel spreadsheet
    open_wps("et", excelFilePath);
    sleep(2);

    // Open PDF document
    open_wps("wpspdf", pdfFilePath);
    sleep(2);

    print_wps_print();
    return 0;
}

代码需要说明的有如下几点:

1、wps在slackware 中安装好后,可以打开word、pdf、execl、ppt,他们分别对应的可执行文件是wps、wpspdf、et、wpp。

2、打开多个相同类型的文件,比如word,一般只有一个进程,以及一个软件界面,用多个tab页来显示多个文件。

3、代码逻辑有些随意,主要是用于测试。

相关推荐
正在努力的小河1 小时前
Linux设备树简介
linux·运维·服务器
荣光波比1 小时前
Linux(十一)——LVM磁盘配额整理
linux·运维·云计算
LLLLYYYRRRRRTT1 小时前
WordPress (LNMP 架构) 一键部署 Playbook
linux·架构·ansible·mariadb
轻松Ai享生活2 小时前
crash 进程分析流程图
linux
大路谈数字化3 小时前
Centos中内存CPU硬盘的查询
linux·运维·centos
luoqice4 小时前
linux下查看 UDP Server 端口的启用情况
linux
倔强的石头_5 小时前
【Linux指南】动静态库与链接机制:从原理到实践
linux
赏点剩饭7785 小时前
linux中的hostpath卷、nfs卷以及静态持久卷的区别
linux·运维·服务器
神鸟云6 小时前
DELL服务器 R系列 IPMI的配置
linux·运维·服务器·网络·边缘计算·pcdn
herderl6 小时前
**僵尸进程(Zombie Process)** 和**孤儿进程(Orphan Process)**
linux·运维·服务器·网络·网络协议