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、代码逻辑有些随意,主要是用于测试。

相关推荐
大龄Python青年1 小时前
C#快入教程:Linux安装.NET
linux·c#·.net
抠脚学代码1 小时前
Linux开发-->驱动开发-->字符设备驱动框架
linux·数据结构·驱动开发
Elias不吃糖2 小时前
第四天学习总结:C++ 文件系统 × Linux 自动化 × Makefile 工程化
linux·c++·学习
噜啦噜啦嘞好2 小时前
Linux进程信号
linux·运维·服务器
REDcker2 小时前
Linux 进程资源占用分析指南
linux·运维·chrome
samroom2 小时前
Linux系统管理与常用命令详解
linux·运维·服务器
一叶之秋14123 小时前
Linux基本指令
linux·运维·服务器
码割机3 小时前
Linux服务器安装jdk和maven详解
java·linux·maven
亚林瓜子3 小时前
在amazon linux 2023上面源码手动安装tesseract5.5.1
linux·运维·服务器·ocr·aws·ec2
爱学习的大牛1233 小时前
Ubuntu 24.04 安装 FreeSWITCH 完整教程
linux·freeswitch