windows/Linux c++ 获取CMD指令执行的返回结果

2023-10-27

 无论是在windows还是linux下我们都可以借助popen执行终端指令并获取到返回值。

/// 执行cmd指令并返回结果
string getCmdResult(const string &strCmd)  
{
    char buf[10240] = {0};
    FILE *pf = NULL;

    if( (pf = popen(strCmd.c_str(), "r")) == NULL )
    {
        return "";
    }

    string strResult;
    while(fgets(buf, sizeof buf, pf))
    {
        strResult += buf;
    }

    pclose(pf);

    unsigned int iSize =  strResult.size();
    if(iSize > 0 && strResult[iSize - 1] == '\n')  // linux
    {
        strResult = strResult.substr(0, iSize - 1);
    }

    return strResult;
}

但是值得注意的是,windows下诸多的指令需要管理员的权限才能执行,这是很令人头疼的。

除了上述方法外,我们先大致罗列下windows下可以执行命令行指令的方法:

1、WinExec() ==》无法直接使用管理员权限,无法获取返回信息,只能判断是否执行

 QString cmdstr = QString("cmd /c taskkill /im iphelper.exe /t /f");
 WinExec(cmdstr.toLatin1().data(), SW_HIDE);

2、ShellExecute()==》可使用管理员权限,无法获取返回信息

ShellExecute(0,"runas", LPCSTR("cmd.exe"),LPCSTR("/c net user administrator /active:yes"),"",SW_HIDE);

3、CreateProcessAsUser()==》可使用管理员权限,无法获取返回信息,可判断是否执行成功

 BOOL CreateProcessAsUser(
  HANDLE hToken,         // handle to a token representing the logged-on user
  LPCTSTR lpApplicationName,  // pointer to name of executable module
  LPTSTR lpCommandLine,       // pointer to command line string
  LPSECURITY_ATTRIBUTES lpProcessAttributes, // process security attributes
  LPSECURITY_ATTRIBUTES lpThreadAttributes,  // thread security attributes
  BOOL bInheritHandles,         // whether new process inherits handles
  DWORD dwCreationFlags,        // creation flags
  LPVOID lpEnvironment,         // pointer to new environment block
  LPCTSTR lpCurrentDirectory,   // pointer to current directory name
  LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO
  LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION
);

4、CreateProcessW()  ==》 可使用管理员权限,无法直接获取返回信息,可判断是否执行成功。

附一个封装的基于CreateProcessW 的方法,支持阻塞模式。

bool RunProgram(QString exePath, QString args, bool bWaitFor)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    exePath = exePath + " " + args;
    if (!CreateProcessW(nullptr,   // No module name (use command line)
                        const_cast<LPWSTR>(exePath.toStdWString().c_str()),        // Command line
                        NULL,           // Process handle not inheritable
                        NULL,           // Thread handle not inheritable
                        FALSE,          // Set handle inheritance to FALSE
                        CREATE_NO_WINDOW,              // No creation flags
                        NULL,           // Use parent's environment block
                        NULL,           // Use parent's starting directory
                        &si,            // Pointer to STARTUPINFO structure
                        &pi)            // Pointer to PROCESS_INFORMATION structure
            )
    {
        printf("CreateProcess failed (%d).\n", GetLastError());
        return false;
    }

    if (bWaitFor)
    {
        WaitForSingleObject(pi.hProcess, INFINITE);
        //Close process and thread handles.
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }

    return true;
}

显然,在我们渴望获取到指令返回的信息时,以上的几种方法都不如人意。考虑到‘runas’方法,那么我们能否既使用管理员权限执行指令的同时获取到指令执行返回结果信息呢?答案是肯定的。

先熟悉下windows的runas指令:

RUNAS 用法:

RUNAS [ [/noprofile | /profile] [/env] [/savecred | /netonly] ]
        /user:<UserName> program

RUNAS [ [/noprofile | /profile] [/env] [/savecred] ]
        /smartcard [/user:<UserName>] program

RUNAS /trustlevel:<TrustLevel> program

   /noprofile        指定不应该加载用户的配置文件。
                     这会加速应用程序加载,但
                     可能会造成一些应用程序运行不正常。
   /profile          指定应该加载用户的配置文件。
                     这是默认值。
   /env              要使用当前环境,而不是用户的环境。
   /netonly          只在指定的凭据限于远程访问的情况下才使用。
   /savecred         用用户以前保存的凭据。
   /smartcard        如果凭据是智能卡提供的,则使用这个选项。
   /user             <UserName> 应使用 USER@DOMAIN 或 DOMAIN\USER 形式
   /showtrustlevels  显示可以用作 /trustlevel 的参数的
                     信任级别。
   /trustlevel       <Level> 应该是在 /showtrustlevels 中枚举
                     的一个级别。
   program           EXE 的命令行。请参阅下面的例子

示例:
> runas /noprofile /user:mymachine\administrator cmd
> runas /profile /env /user:mydomain\admin "mmc %windir%\system32\dsa.msc"
> runas /env /user:user@domain.microsoft.com "notepad \"my file.txt\""

注意:  只在得到提示时才输入用户的密码。
注意:  /profile 跟 /netonly 不兼容。
注意:  /savecred 跟 /smartcard 不兼容。

那么方法就有了,只需要在使用getCmdResult()函数时,我们在传参strCmd中借用runas指定程序使用管理员权限执行即可。

    string cmd = string("runas /noprofile /user:mymachine\\administrator \"cmd /c ") + "cmd /c chcp 65001 && ping www.baidu.com -n 1 -w 1000" + "\"";
    strRe = getCmdResult(cmd);
    cout << strRe << endl;

完整的测试代码如下:

#include <iostream>

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

using namespace std;

/// 执行cmd指令并返回结果
string getCmdResult(const string &strCmd)  
{
    char buf[10240] = {0};
    FILE *pf = NULL;

    if( (pf = popen(strCmd.c_str(), "r")) == NULL )
    {
        return "";
    }

    string strResult;
    while(fgets(buf, sizeof buf, pf))
    {
        strResult += buf;
    }

    pclose(pf);

    unsigned int iSize =  strResult.size();
    if(iSize > 0 && strResult[iSize - 1] == '\n')  // linux
    {
        strResult = strResult.substr(0, iSize - 1);
    }

    return strResult;
}


int main(int argc, char *argv[])
{

    /// 获取ping指令的结果
    string strCmd = "cmd /c chcp 65001 && ping www.baidu.com -n 1 -w 1000";

    string strRe = getCmdResult(strCmd);
    cout << strRe << endl;

    /// 以管理员的身份运行程序并返回结果
    /// runas
    string cmd = string("runas /noprofile /user:mymachine\\administrator \"cmd /c ") + "cmd /c chcp 65001 && ping www.baidu.com -n 1 -w 1000" + "\"";
    strRe = getCmdResult(cmd);
    cout << strRe << endl;

    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

windows/Linux c++ 获取CMD指令执行的返回结果 的相关文章

随机推荐

  • ABP-使用Dapper框架

    ABP使用Dapper框架已经有很成熟的第三方包 简单的几句代码就能完成 一 首先准备好一个数据库建一个表 二 建一个实体表 Table BasBloodLevel public class BasBloodLevel Entity
  • 《设计模式》-代码质量评价标准和设计原则

    系列文章目录 设计模式 代码质量评价标准和设计原则 设计模式 创建型 单例模式 工厂模式 建造者模式 原型模式 设计模式 结构型 代理模式 装饰者模式 适配器模式 桥接模式 门面模式 组合模式 亨元模式 文章目录 系列文章目录 前言 一 代
  • 第10章 近似推断

    10 近似推断 在概率模型的应用中 一个中心任务是在给定观测 可见 数据变量X的条件下 计算潜在变量Z的后验概率分布 p Z X p Z X p Z X 以及计算
  • element表格翻页后回到顶部

  • Linux mode命令,linux命令

    一 inode节点号 在linux中 每一个文件都有唯一的inode号 inode号也是系统识别的唯一编码 而文件名仅仅是为了使用者区分辨认 inode index node 表中包含文件系统所有文件列表 一个节点 索引节点 是在一个表项
  • 数字IC设计——跨时钟域篇2(亚稳态)

    数字IC设计 跨时钟域篇2 亚稳态 一 建立时间与保持时间 前提条件 对任何一种触发器 在时钟触发沿前 后的一个小时间窗口内 输入信号必须稳定 输入信号应提前时钟上升沿 假设上升沿有效 T时间到达芯片 这个T就是建立时间Setup time
  • 海思3518E V200中RTSP实验自己构建RTP发送的函数代码及VLC播放器的一个播放注意事项

    在VLC播放器中 工具 首选项 设置里面需要注意必须使用下图中红色框圈出来的设置 如果选择的是后面的 RTP over RTSP TCP 的话会播放不出画面 具体原因未去深入探究 另可以参考他人的代码完成其他功能 网址如下 https bl
  • msi afterburner怎么设置最好?推荐设置

    msi afterburner是一款为显卡超频和监控提供的软件 广泛应用于游戏玩家和电脑爱好者之间 通过适当的设置 可以显著提升显卡的性能 下面就给大家介绍一下msi afterburner推荐设置 纯净之家 win7纯净版系统 win7
  • 使用Prometheus实现大规模的应用程序监视

    Prometheus是一个越来越受欢迎的开源工具 这有充分的理由 它可以为应用程序和服务器提供监视和警报 Prometheus的强大优势在于监视服务器端指标 并将其存储为时间序列数据 尽管Prometheus不适合应用程序性能管理 主动控制
  • 【转】一个FAE(AE)的体会和大家交流

    原文网址 http www 52rd com bbs dispbbs asp boardID 63 ID 228682 本人在国内某芯片设计公司工作近5年时间岗位是AE和FAE 两个工作量各一半吧 今日闲来无事写一些自己的体会与大家分享 不
  • 【一、搭建通用Arm平台的QT交叉编译环境】

    搭建通用Arm平台的QT交叉编译环境 前言 准备 一 下载arm平台交叉编译工具链 1 下载工具链 2 解压到交叉编译平台 Ubuntu 3 配置环境变量 二 下载QT源码 版本与交叉编译工具链版本保持一致 三 下载并编译tslib库 1
  • 微信小程序实现下载功能(以下载视频为例)

    首先 采用 wx downloadFile 方法 访问视频对应的Url 回调函数返回一个该视频文件的临时路径 wx downloadFile url app serverUrl me data videoInfo videoPath suc
  • getDerivedStateFromProps和componentDidUpdate的使用

    react 17版本 使用getDerivedStateFromProps接收外部数据同步到本地state componentDidUpdate里面发送异步请求 Foo js import useState from react impor
  • iMX6ULL-UBoot移植

    U Boot移植 文章目录 U Boot移植 1 获取源码 1 1 从u boot官网获取 1 2 从芯片厂商获取 1 3 从开发板厂商获取 2 移植 2 1 生成自己的配置文件 2 1 1 拷贝参考板的配置文件 2 1 2 生成修改配置文
  • pcb设计50经典实例_数字IC设计职位经典笔试面试100题(41~50)

    41 用与非门等设计全加法器 数字电子技术基础 192页 通过摩根定律化成用与非门实现 42 A B C D E进行投票 多数服从少数 输出是F 也就是如果A B C D E中1的个数比0 多 那么F输出为1 否则F为0 用与非门实现 输入
  • Unity导入模型UnityPacket

    asset gt import package gt import custom package
  • C++ 代码评审最终指南——第 1 部分

    C 语言功能强大 但也极其复杂 复杂性使其极易引发误解和过度复杂化 相比简单语言 C 中的程序错误难以发现 相比其他语言 生产环境中的 C 程序错误更难定位 简而言之 需要谨慎处理 C 甚至是用鹰眼那样锐利的目光进行评审 本篇分为两部分 第
  • 前端鉴权如何做

    登录接鉴权 用户名密码 gt 客户端 gt login gt 服务端 gt 比对数据库 gt 数据库返回数据 gt 服务端 gt 返回数据 gt 给客户端 鉴权 基础鉴权 session cookie JWT Oauth 算法加密 Base
  • eclipse 中Maven项目 的maven install 、build 、clean

    自己在对maven项目打成war包的时候 首先是maven clean 之后maven build的时候出现报错 说找不到该项目下的target 文件 具体的英文我就不复制了 自己倒腾了好长的时间 最后maven install一下皆可以了
  • windows/Linux c++ 获取CMD指令执行的返回结果

    无论是在windows还是linux下我们都可以借助popen执行终端指令并获取到返回值 执行cmd指令并返回结果 string getCmdResult const string strCmd char buf 10240 0 FILE