c++ 读取修改xml文件,程序控制其他软件的打开关闭

继续这个软件开发,接收到指令后启动、关闭或者部署软件。

关闭软件,我这里是执行一个批处理文件,

void OnStop()
{
    char* killPath = "softwarePath";
    ShellExecute(NULL, "open", _T("softwareName.bat"), NULL, killPath, SW_SHOWNA);
    printf("kill all. err code:%d\n", GetLastError());
}

打开软件,根据需要,先改几个xml配置文件,再创建几个进程,再执行一个批处理文件。

读取xml文件获取进程列表,将列表中每个进程名称取出来, XML 解析器之一 :MSXML使用教程(转)_mannhello的博客-CSDN博客_msxml.h

还不能修改xml内容,另外发现读到的进程名称有的不带后缀名,没有后缀的名称启动进程不成功,还得加后缀名。。

头文件#include <msxml6.h>

void CommandRespond::getProcessList(std::string name, std::string value)
{
    // const char* 转 char*
    char *tmpStr, *token, *strc = const_cast<char*>(value.c_str());
    std::vector<std::string> resVec;
    // 分解字符串
    token = strtok_s(strc, "/", &tmpStr);
    while (token)
    {
        std::string tokenStr = token;
        tokenStr.erase(tokenStr.find_last_not_of(" .") + 1);
        if (tokenStr.size() > 0)
        {
            // 查看文件名是否包含exe后缀
            std::string::size_type idx = tokenStr.find(".");
            if (idx == std::string::npos)
                tokenStr = tokenStr + ".exe";
            resVec.push_back(tokenStr);
        }            
        token = strtok_s(NULL, "/", &tmpStr);
    }
    m_ProcessMap[name] = resVec;
}

 //读取xml文件
void CommandRespond::readXml(OLECHAR* xmlFileName, OLECHAR* queryStr, OLECHAR* attributeName)
{
    IXMLDOMDocument2    *pXmlDoc = NULL;
    VARIANT                vSrc;
    VARIANT_BOOL        status;
    IXMLDOMParseError    *pObjError = NULL;
    BSTR                bstr = NULL, BStr, BStrValue;
    IXMLDOMNodeList        *pNodeList = NULL;
    long                Length, I;
    IXMLDOMNode            *Node, *IDNode;
    IXMLDOMNamedNodeMap    *NodeMap;
    
    CoInitialize(NULL);    
    HRESULT hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, __uuidof(IXMLDOMDocument2), (void**)&pXmlDoc);
    if (FAILED(hr))
        printf("failed to CoCreate an instance of an XML DOM. err code: %d", hr);

    hr = pXmlDoc->put_async(VARIANT_FALSE); //加载方式不为“同步”
    if (FAILED(hr))
        printf("failed to set async property. err code: %d", hr);

    hr = pXmlDoc->put_validateOnParse(VARIANT_FALSE); //文档结构有错误时,停止解析
    if (FAILED(hr))
        printf("failed to set validateOnParse. err code: %d", hr);

    hr = pXmlDoc->put_resolveExternals(VARIANT_FALSE);
    if (FAILED(hr))
        printf("failed to disable resolving externals. err code: %d", hr);

    VariantInit(&vSrc);
    V_BSTR(&vSrc) = SysAllocString(xmlFileName);
    V_VT(&vSrc) = VT_BSTR;

    hr = pXmlDoc->load(vSrc, &status);
    if (status != VARIANT_TRUE)
    {
        hr = pXmlDoc->get_parseError(&pObjError);
        hr = pObjError->get_reason(&bstr);
        printf("failed to load DOM from xml. err code: %S", bstr);
    }

    if (bstr)
        SysFreeString(bstr);
    if (&vSrc)
        VariantClear(&vSrc); //清理一个VARIANT对象
    if (pObjError)
        pObjError->Release();

    if (pXmlDoc == NULL)
        printf("loadXML ProcessControllerConfig.xml failed. err code: %d", GetLastError());

    if (pXmlDoc->selectNodes(queryStr, &pNodeList) != S_OK)
        printf("no nodes like //Application. err code: %d", GetLastError());

    hr = pNodeList->get_length(&Length);
    if (FAILED(hr))
        printf("no length. err code: %d", hr);

    for (I = 0; I < Length; I++)
    {
        if (pNodeList->get_item(I, &Node) == S_OK)
        {
            char IDBuffer[512];
            char Buffer[1024];
            if (Node->get_attributes(&NodeMap) == S_OK)
            {                
                if (NodeMap->getNamedItem(attributeName, &IDNode) == S_OK)
                {
                    if (IDNode->get_text(&BStrValue) == S_OK)
                    {                        
                        WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, BStrValue, -1, IDBuffer, sizeof(IDBuffer), NULL, NULL);
                        puts(IDBuffer);
                        puts("");
                        SysFreeString(BStrValue);                        
                    }
                    IDNode->Release();
                }
                NodeMap->Release();
            }
            if (Node->get_text(&BStr) == S_OK)
            {                
                WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, BStr, -1, Buffer, sizeof(Buffer), NULL, NULL);
                puts(Buffer);
            }
            getProcessList(IDBuffer, Buffer);
            SysFreeString(BStr);
            Node->Release();
        }
    }
    pXmlDoc->Release();
    CoUninitialize();
}

创建进程,C++ 创建进程的方法 - 积跬步---行千里 - 博客园 (cnblogs.com)

void CommandRespond::OnStart()
{
    char* filePath = "D:/";
    // Process.xml
    OLECHAR* xmlFileName = L"D:/Process.xml";
    OLECHAR* queryStr = L"//Application/Process/Mode";
    OLECHAR* attributeName = L"ID";// 取到xml
    readXml(xmlFileName, queryStr, attributeName);        
    std::string runName = "Stand";
    std::map<std::string, std::vector<std::string> >::iterator iter;
    iter = m_ProcessMap.find(runName);
    std::vector<std::string> proList = iter->second;    
    for (int i=0; i<proList.size(); i++)
    {
        std::string dirPath = "D:/";
        dirPath = dirPath + proList[i];
        LPCSTR PATH = dirPath.c_str();
        // 创建进程
        STARTUPINFO startupInfo = { 0 };
        PROCESS_INFORMATION processInformation = { 0 };
        BOOL bSuc = CreateProcess(PATH, NULL, NULL, NULL, FALSE, NULL, NULL, filePath, &startupInfo, &processInformation);         //TEXT("D:/MAXSim7.1.1/Applications/SSGProduct/bin/x64/release/BalloonMotion.exe")
        if (bSuc)
            printf("process started. processID:%d", processInformation.dwProcessId);
        else
            printf("process started failed. err code: %d", GetLastError());
    }
    // 执行启动的批处理软件
    ShellExecute(NULL, "open", _T("Process.bat"), NULL, filePath, SW_SHOWNA);
}

 为了查看怎么修改xml内容,又发现了这篇文章C++ DOM读写xml(msxml6)_gdizcm的博客-CSDN博客_c++ dom

然后重新写了读取xml的方法,并实现了修改内容,根据自己的业务需要将读和改都写进去了,代码更短些。

加头文件

#include <atlbase.h>
#pragma comment(lib, "msxml6.lib")

另外把#include<windows.h>写进了#include "stdafx.h"文件里

void CommandRespond::readXml(LPCSTR filenName, BSTR queryStr, BSTR attriName, BSTR attriValue, BOOL UPDATEMARK)
{
    CoInitialize(NULL);
    CComPtr<IXMLDOMDocument> spXmldoc;
    HRESULT hr = spXmldoc.CoCreateInstance(CLSID_DOMDocument60);    
    if (SUCCEEDED(hr))
    {
        VARIANT_BOOL isSuccessful;
        spXmldoc->load(CComVariant(filenName), &isSuccessful);
        if (VARIANT_TRUE == isSuccessful)
        {
            CComBSTR bstrXml;
            CComPtr<IXMLDOMElement> spRoot = NULL;
            CComPtr<IXMLDOMElement> spElement = NULL;
            hr = spXmldoc->get_documentElement(&spRoot);
            spRoot->get_xml(&bstrXml);
            if (hr == S_OK)
            {
                CComPtr<IXMLDOMNode> spNode;
                CComPtr<IXMLDOMNodeList> pNodeList = NULL;
                LONG length;
                // 通过xpath寻找节点
                //hr = spRoot->selectSingleNode(L"/SSU/General", &spNode);
                hr = spRoot->selectNodes(queryStr, &pNodeList);
                hr = pNodeList->get_length(&length);
                if (hr == S_OK)
                {
                    for (LONG i = 0; i < length; i++)
                    {
                        if (pNodeList->get_item(i, &spNode) == S_OK)
                        {
                            if (UPDATEMARK == TRUE)
                            {
                                spNode->get_xml(&bstrXml); //<General GBBConfig="BC31" Mission="Basic Demo5"/>
                                spElement = spNode;
                                CComVariant varID(attriValue);
                                spElement->setAttribute(attriName, varID);
                                //spElement->setAttribute(L"ID", varID);
                                spXmldoc->save(CComVariant(filenName));
                   VariantClear(&varID); }
else { char IDBuffer[512]; char Buffer[1024]; spElement = spNode; CComVariant varID; hr = spElement->getAttribute(L"ID", &varID); //spRoot->get_xml(&bstrXml); WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, varID.bstrVal, -1, IDBuffer, sizeof(IDBuffer), NULL, NULL); hr = spNode->get_text(&bstrXml); WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, bstrXml, -1, Buffer, sizeof(Buffer), NULL, NULL); getProcessList(IDBuffer, Buffer);
                   VariantClear(&varID); } } } } spNode.Release();
          pNodeList.Release(); }    

        SysFreeString(bstrXml);
        spElement.Release();
        spRoot.Release();

        }
    }
    spXmldoc.Release();
    CoUninitialize();
}

这样把onstart函数也改下就可以实现启动了!

void CommandRespond::OnStart(std::string missionName, int mode)
{
    // 可能从ini文件读到的引擎配置文件目录
    std::string path = "D:/";
    
    //// 从指令获取
    //std::string missionName = "test";    // 想定名称
    //int mode = -1;                        // 运行模式mode: - 1:单机, - 2:回放, - 3:态势,0~n:分布式 node:“129.168.1.1”
    
    // 改 xxx.xml,设置想定名称
    std::string ssuPath = path + "xxx.xml";
    LPCSTR filenName = ssuPath.c_str();
    BSTR queryStr = L"/xxx/xxxx";
    BSTR attriName = L"xx";
    BSTR attriValue = _com_util::ConvertStringToBSTR(missionName.c_str());
    BOOL UPDATEMARK = TRUE;
    readXml(filenName, queryStr, attriName, attriValue, UPDATEMARK);

    // 改 xxxx.xml,设置运行模式
    std::string sysPath = path + "xxxx.xml";
    filenName = sysPath.c_str();
    queryStr = L"/xxxx/xxxx";
    attriName = L"xx";
    if (mode == -1)
        attriValue = L"xx";
    else if (mode == -2)
        attriValue = L"xxx";
    else if (mode == -3)
    {
    }else if (mode >= 0)
        attriValue = L"xxxx";
    UPDATEMARK = TRUE;
    readXml(filenName, queryStr, attriName, attriValue, UPDATEMARK);

    // 读 xxxxx.xml,获取进程列表存储 m_ProcessMap
    std::string processPath = path + "xxxxx.xml";
    filenName = processPath.c_str();
    queryStr = L"/xxxxx/xxxxx/xxxxx";
    UPDATEMARK = FALSE;
    readXml(filenName, queryStr, attriName, attriValue, UPDATEMARK);
    
    //std::string runName = "StandAlone";
    std::string runName = _com_util::ConvertBSTRToString(attriValue);
    std::map<std::string, std::vector<std::string> >::iterator iter;
    iter = m_ProcessMap.find(runName);
    std::vector<std::string> proList = iter->second;

    // 应用程序所在目录
    char* filePath = "D:/";

    for (int i = 0; i < proList.size(); i++)
    {
        std::string dirPath = "D:/";
        dirPath = dirPath + proList[i];
        LPCSTR PATH = dirPath.c_str();
        // 创建进程
        STARTUPINFO startupInfo = { 0 };
        PROCESS_INFORMATION processInformation = { 0 };
        BOOL bSuc = CreateProcess(PATH, NULL, NULL, NULL, FALSE, NULL, NULL, filePath, &startupInfo, &processInformation);         //TEXT("D:/xxx.exe")
        if (!bSuc)
            //printf("process started. processID:%d", processInformation.dwProcessId);
        //else
            printf("process started failed. err code: %d", GetLastError());
    }
    // 执行启动的批处理软件
    bool a=ShellExecute(NULL, "open", _T("xxx.bat"), NULL, filePath, SW_SHOWNA);
    if (!a)
        printf("start xxx. err code:%d\n", GetLastError());
}

 

posted @ 2022-12-06 16:05  yangly  阅读(329)  评论(0编辑  收藏  举报