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

news/2024/9/28 12:59:54 标签: linux, wps, c/c++, slackware

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

编译命令是:

gcc -o main main.cpp -lstdc++ 

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

#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、wpsslackware 中安装好后,可以打开word、pdf、execl、ppt,他们分别对应的可执行文件是wpswpspdf、et、wpp。

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

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


http://www.niftyadmin.cn/n/5681152.html

相关文章

双端之Nginx+Php结合PostgreSQL搭建Wordpress

第一台虚拟机:安装 Nginx 更新系统包列表: sudo apt update安装 Nginx及php扩展: sudo apt install nginx php-fpm php-pgsql php-mysqli -y启动 Nginx 服务: sudo systemctl start nginx检查 Nginx 是否正常运行: xdg-open http://localhost注意:终端命令打开网址 …

深度解析 HTTP

我的主页&#xff1a;2的n次方_ 1. HTTP 的简单介绍 HTTP &#xff1a;超文本传输协议&#xff0c;不仅能传输文本&#xff0c;还能传输图片&#xff0c;音频文件&#xff0c;视频 目前基本上都用的是 1.1 版本 https 可以认为是 http 的升级版&#xff0c;区别就是引入了…

MySQL—表优化

分区表 基本介绍 分区表是将大表的数据按分区字段分成许多小的子集&#xff0c;每个子集称为一个分区。通过分区&#xff0c;用户可以提高查询性能、简化数据管理并提高可维护性。分区表可以使数据更容易管理&#xff0c;尤其是当表中的数据量非常大时。 分区的优点 性能提…

[Linux] Linux操作系统 进程的优先级 环境变量

标题&#xff1a;[Linux] Linux操作系统 进程的优先级 个人主页水墨不写bug &#xff08;图片来源于网络&#xff09; 目录 一、进程优先级 1.PRI and NI 2.PRI vs NI 的补充理解 二、命令行参数和环境变量 1. 命令行参数 2.环境变量 I&#xff0c;环境变量是内…

深度学习:迁移学习

目录 一、迁移学习 1.什么是迁移学习 2.迁移学习的步骤 1、选择预训练的模型和适当的层 2、冻结预训练模型的参数 3、在新数据集上训练新增加的层 4、微调预训练模型的层 5、评估和测试 二、迁移学习实例 1.导入模型 2.冻结模型参数 3.修改参数 4.创建类&#xff…

[element-ui]记录对el-table表头样式的一些处理

1、表头换行 & 列表项换行 可用element-table组件自带的方法实现列标题换行的效果 2、小圆点样式

MySQL 8.0.34 从C盘迁移到D盘

因为开始C盘够用&#xff0c;没注意mysql安装位置&#xff0c;如今C盘爆满&#xff0c;只能把mysql转移到D盘&#xff0c;以腾出更多的空间让我折腾。 一、关闭mysql服务 二、找到C盘MySQL安装文件和Data文件 1.找到C盘mysql bin文件目录安装文件路径&#xff1a; C:\Progra…

使用scroll-behavior属性实现页面平滑滚动的几个问题

在较长的页面中&#xff0c;为了便于用户浏览&#xff0c;开发人员经常会使用锚点链接&#xff0c;锚点链接默认的效果是瞬间跳转&#xff0c;为了让用户体验更好&#xff0c;往往会添加滚动效果。我记得要实现滚动效果&#xff0c;以前一般是结合一段JavaScript代码来实现。 后…