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