Visual Studio C++ 远程调试 - 运行 在远程机器上以管理员身份运行 CMD
Visual Studio C++ remote debugging - running CMD as admin on remote machine
我正在使用 Visual Studio 2017 在 VM 运行ning Windows[= 上调试 C++ 代码30=] 通过 VS Remote Debugging。作为我的代码的一部分,我正在通过 std::system
执行命令,这必须 运行 作为管理员 才能成功。
当 运行宁 VS 作为管理员,并在本地调试代码——一切正常。
但是,在虚拟机上远程调试时,命令不会以管理员身份执行。我知道这是事实,因为某些命令需要这样做,并且输出明确指出并非如此。有什么办法让它起作用吗?
我不介意使用不同的 API,std::system
似乎只是命令执行的“默认值”。
我建议您可以将 Properties->Linker->Manifest File->UAC Execution Level
设置为 requireAdministrator
。
如果你想用WindowsAPI,我发现ShellExcuteEx could meet your needs. Its structure is SHELLEXECUTEINFOA。你可以参考例子:
var ExeInfo = SHELLEXECUTEINFO();
ExeInfo.lpVerb = “runas”;
感谢 Barrnet 的回答,我研究了 ShellExecuteEx
及其 “runas”动词。
这是一个完整的解决方案,运行 以管理员身份运行 cmd 并将 cmd 输出检索为字符串:(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");
}
我正在使用 Visual Studio 2017 在 VM 运行ning Windows[= 上调试 C++ 代码30=] 通过 VS Remote Debugging。作为我的代码的一部分,我正在通过 std::system
执行命令,这必须 运行 作为管理员 才能成功。
当 运行宁 VS 作为管理员,并在本地调试代码——一切正常。
但是,在虚拟机上远程调试时,命令不会以管理员身份执行。我知道这是事实,因为某些命令需要这样做,并且输出明确指出并非如此。有什么办法让它起作用吗?
我不介意使用不同的 API,std::system
似乎只是命令执行的“默认值”。
我建议您可以将 Properties->Linker->Manifest File->UAC Execution Level
设置为 requireAdministrator
。
如果你想用WindowsAPI,我发现ShellExcuteEx could meet your needs. Its structure is SHELLEXECUTEINFOA。你可以参考例子:
var ExeInfo = SHELLEXECUTEINFO();
ExeInfo.lpVerb = “runas”;
感谢 Barrnet 的回答,我研究了 ShellExecuteEx
及其 “runas”动词。
这是一个完整的解决方案,运行 以管理员身份运行 cmd 并将 cmd 输出检索为字符串:(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");
}