簡體   English   中英

Visual Studio C++ 遠程調試 - 在遠程計算機上以管理員身份運行 CMD

[英]Visual Studio C++ remote debugging - running CMD as admin on remote machine

我正在使用Visual Studio 2017通過VS Remote Debugging在運行Windows的 VM 上調試 C++ 代碼。 作為我的代碼的一部分,我通過std::system執行命令,必須以管理員身份運行才能成功。

以管理員身份運行 VS 並在本地調試代碼時——一切正常。

但是,在 VM 上遠程調試時,命令不會以管理員身份執行 我知道這是事實,因為某些命令需要這樣做,並且 output 明確指出事實並非如此。 有沒有辦法讓它工作?

我不介意使用不同的 API, std::system似乎只是命令執行的“默認值”。

我建議您可以將Properties->Linker->Manifest File->UAC Execution Level設置為requireAdministrator

如果您想使用 Windows API,我發現ShellExcuteEx可以滿足您的需求。 它的結構是SHELLEXECUTEINFOA 你可以參考這個例子:

var ExeInfo = SHELLEXECUTEINFO();
ExeInfo.lpVerb = “runas”;

感謝 Barrnet 的回答,我研究了ShellExecuteEx及其“runas”動詞

這是一個完整的解決方案,用於以管理員身份運行 cmd 並檢索 cmd output 作為字符串:(必須將 UAC 設置為最小,以避免彈出窗口)

#include <Windows.h>
#include <vector>
#include <string>
#include <fstream>

inline void Validate (const bool expression) 
{
    if (!expression) 
        throw std::exception(); 
}

class TemporaryFile
{
public:
    TemporaryFile()
    {
        std::vector<char> tmpPath(MAX_PATH + 1, 0);
        Validate(0 != GetTempPathA(MAX_PATH, tmpPath.data()));
        std::vector<char> tmpFilename(MAX_PATH + 1, 0);
        Validate(0 != GetTempFileNameA(tmpPath.data(), "tmp", 0, tmpFilename.data()));
        _fullPath = std::string(tmpFilename.data());
    }

    ~TemporaryFile()
    {
        DeleteFileA(_fullPath.c_str());
    }

    std::string GetPath()
    {
        return _fullPath;
    }
    
private:
    std::string _fullPath{};
};

std::string ReadFileContents(const std::string& filename)
{
    std::ifstream ifs(filename);
    return std::string((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
}

std::string RunCmdAsAdmin(const std::string& cmd)
{
    // file to hold cmd output
    TemporaryFile output;

    // the cmd will be passed to cmd.exe via '/c' flag, output will be written to tempfile
    const std::string modifiedCmd = "/c " + cmd + " > \"" + output.GetPath() + "\"";

    // create and launch cmd (async operation -- a seperate process is launched)
    SHELLEXECUTEINFO shellExecInfo{};
    shellExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    shellExecInfo.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS;
    shellExecInfo.lpVerb = "runas";
    shellExecInfo.lpFile = "cmd.exe";
    shellExecInfo.lpParameters = modifiedCmd.c_str();
    shellExecInfo.nShow = SW_SHOWNORMAL;
    Validate(TRUE == ShellExecuteEx(&shellExecInfo));

    // wait for cmd to finish running and retrieve output
    static const DWORD MAX_WAIT_MS{ 5000 };
    Validate(WAIT_OBJECT_0 == WaitForSingleObject(shellExecInfo.hProcess, MAX_WAIT_MS));
    CloseHandle(shellExecInfo.hProcess);
    return ReadFileContents(output.GetPath());
}

int main()
{
    const auto& cmdOutput = RunCmdAsAdmin("ipconfig"); 
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM