【问题标题】:Embed Batch Script file and run in C++ Console Project嵌入批处理脚本文件并在 C++ 控制台项目中运行
【发布时间】:2017-09-18 01:58:45
【问题描述】:

我将在资源项目中嵌入批处理文件,我想在控制台中运行批处理脚本。

如何运行嵌入脚本

#include "stdafx.h"
#include "iostream"
#include "conio.h"
#define WINDOWS_LEAN_AND_MEAN
#include <Windows.h>

std::wstring GetEnvString()
{
    wchar_t* env = GetEnvironmentStrings();
    if (!env)
        abort();
    const wchar_t* var = env;
    size_t totallen = 0;
    size_t len;
    while ((len = wcslen(var)) > 0)
    {
        totallen += len + 1;
        var += len + 1;
    }
    std::wstring result(env, totallen);
    FreeEnvironmentStrings(env);
    return result;
}

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

     std::wstring env = GetEnvString();
    env += L"myvar=boo";
    env.push_back('\0'); // somewhat awkward way to embed a null-terminator

    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi;

    wchar_t cmdline[] = L"cmd.exe /C f.bat";

    if (!CreateProcess(NULL, cmdline, NULL, NULL, false, CREATE_UNICODE_ENVIRONMENT,
        (LPVOID)env.c_str(), NULL, &si, &pi))
    {
        std::cout << GetLastError();
        abort();
    }

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    getch();
}

embed batch script file in c++ console

这是我想从资源项目运行的位置批处理文件

 wchar_t cmdline[] = L"cmd.exe /C f.bat";

【问题讨论】:

    标签: c++ batch-file cmd console embed


    【解决方案1】:

    你可以使用std::system:

    #include <fstream>
    #include <cstdlib>
    
    int main()
    {
        std::ofstream fl("test.bat");
        fl << "@echo off\n"
              "echo testing batch.\n"
              "cd c:\\windows\n"
              "dir";
        fl.close();
        system("test.bat");
    }
    

    但是使用系统你可以简单地执行命令,你不能得到它们的输出。要获得输出,您可以将输出从 .bat 重定向到文件,或者您可以使用 popen 并且您可以像普通文件一样读取输出。请注意,popen 只能获取标准输出,但您可以将标准错误重定向到标准输出:

    #include <cstdlib>
    #include <cstdio>
    
    int main()
    {
        FILE *p = _popen("missing_executable.exe 2>&1", "r");
        if (p)
        {
            char data[1024];
            int n = 0;
            while (fgets(data, 1024, p))
                printf("%02d: %s", ++n, data);
            int ret = _pclose(p);
            printf("process return: %d\n", ret);
        }
        else
        {
            printf("failed to popen\n");
        }
    }
    

    这是输出:

    01: 'missing_executable.exe' is not recognized as an internal or external command,
    02: operable program or batch file.
    process return: 1
    Press any key to continue . . .
    

    如果您想将 .bat 文件作为资源存储在 Windows 可执行文件中,您可以使用 FindResource/LoadResource/LockResource 从可执行文件中获取实际的 bat 文件。像这样的:

    HMODULE module = GetModuleHandle(NULL);
    // update with your RESOURCE_ID and RESOURCE_TYPE.
    HRSRC res = FindResource(module, MAKEINTRESOURCE(RESOURCE_ID), RESOURCE_TYPE);
    HGLOBAL resMem = LoadResource(module, res);
    DWORD resSize = SizeofResource(module, res);
    LPVOID resPtr = LockResource(resMem);
    
    char *bytes = new char[resSize];
    memcpy(bytes, resPtr, resSize);
    

    现在您可以将字节保存到文件并使用std::systempopen 执行它

    【讨论】:

    • 您需要获取嵌入式资源并将其保存到文件中(保存到某个临时位置),然后使用 system 或 popen 执行该 bat 文件。或者,如果您不想使用临时文件,则需要从资源中读取数据并创建一些可以使用系统执行的cmd /c param1 param2 ... 字符串。
    • @JavadRajabzade 检查更新的答案以使用FindResource/LoadResource/LockResource 加载 Windows 资源的示例代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多