我想从我的FMX应用程序(在Win32上)以提升的特权生成一个批处理文件。在ShellExecute底部of this thread的Remy回答中,我找到了如何启动批处理文件。现在,我不知道如何以提升的特权启动它。下面是我的代码:
String Prog = "c:\\Users\\rwp\\Desktop\\test.bat";
int nErrorCode = (int) ShellExecute(NULL, L"runas", Prog.c_str(), NULL, NULL, SW_SHOWNORMAL);
if (nErrorCode <= 32) {
ShowMessage("an error occured");
}
我在读完this后第二个参数中添加了“ runas”,但无济于事。可以手动运行批处理文件(右键单击并以admin身份运行)。这是批处理文件fyi(仅是系统映像的一击)的内容:
c:\Windows\system32\wbAdmin.exe start backup -backupTarget:D: -include:C: -allCritical -quiet
我如何以管理员身份ShellExecute此批处理文件?
更新1:我正在尝试根据Remy建议使用CreateProcess。这是我的代码(基于this example):
//Code is inside a __fastcall button click
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.lpReserved = NULL;
siStartInfo.lpReserved2 = NULL;
siStartInfo.cbReserved2 = 0;
siStartInfo.lpDesktop = NULL;
siStartInfo.dwFlags = 0;
// String strCmdLine = "C:\\Users\\rwpatter\\Desktop\\test.bat";
String strCmdLine = "C:\\Windows\\System32\\wbAdmin.exe start backup -backupTarget:T: -include:C: -allCritical -quiet";
// Create the child process.
int rtrn = CreateProcess(
NULL,
strCmdLine.c_str(),
NULL, // process security attributes
NULL, // primary thread security attributes
0, // handles are inherited
0, // creation flags
0, // use parent's environment
0, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
// Wait for the processs to finish
DWORD rc = WaitForSingleObject(
piProcInfo.hProcess, // process handle
INFINITE);
ShowMessage(IntToStr(rtrn));
如果我如图所示运行它(右键单击exe并以admin身份运行),它将返回0,表示它为failed。如果我通过将wbAdmin命令行放入test.bat文件(请参见代码中String strCmdLine
上方的注释行)来运行它,则CreateProcess返回1(成功),但wbAdmin仍未运行。它闪烁了一个DOS窗口,我如下图所示捕获了它。它在标题栏中显示东方字符,并说未被识别为内部或外部命令。但是,如果我直接运行该test.bat(提升),它将运行wbAdmin没问题。
关于什么是错的任何想法?除了我,我显然很无知。 (对。在此之后,我将在ShellExecute上测试Golvind的答案...)
答案 0 :(得分:1)
手动运行批处理文件(右键单击并以管理员身份运行)是可行的。
因为您在手动启动时正在运行64位版本的cmd。
它在标题栏中显示东方字符,并说未识别 作为内部或外部命令。
因为您的应用程序是32位的。一个32位应用程序看不到与64位应用程序相同的System32文件夹。您可以使用虚拟sysnative文件夹访问32位应用程序中的64位System32文件夹。
#include <shellapi.h>
...
String strCmdLine = "wbAdmin.exe start backup -backupTarget:T: -include:C: -allCritical -quiet";
int rtrn = CreateProcess(
NULL,
strCmdLine.c_str(),
NULL, // process security attributes
NULL, // primary thread security attributes
0, // handles are inherited
0, // creation flags
0, // use parent's environment
0, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
if (!rtrn)
{
String newCmdLine = "c:\\windows\\sysnative\\wbAdmin.exe start backup -backupTarget:T: -include:C: -allCritical -quiet";
rtrn = CreateProcess(
NULL,
newCmdLine.c_str(),
NULL, // process security attributes
NULL, // primary thread security attributes
0, // handles are inherited
0, // creation flags
0, // use parent's environment
0, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
}
或将您的应用程序编译为64位。
答案 1 :(得分:0)
您需要使用"runas"
以管理员身份启动CMD.exe,并将批处理文件指定为命令提示符下的“先运行然后退出”(即/c
)参数,这样:
WCHAR wszCmdPath[MAX_PATH];
GetEnvironmentVariableW(L"ComSpec", wszCmdPath, MAX_PATH);
ShellExecuteW(NULL, L"runas", wszCmdPath, L"/c \"C:\\Path\\BatchFile.bat\"", L"", SW_SHOW);
此处调用的两个函数都可能失败,而健壮的代码将在继续之前测试成功。