提升的 ShellExecute bat 文件(FMX、Win32)
ShellExecute bat file elevated (FMX, Win32)
我想从我的 FMX 应用程序(在 Win32 上)生成一个具有提升权限的批处理文件。从雷米在 ShellExecute 底部 of this thread 的回答中,我找到了如何启动批处理文件。现在,我不知道如何以提升的权限启动它。下面是我的代码:
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",但无济于事。 运行 手动批处理文件(right-click 和 运行 作为管理员)工作。以下是批处理文件的内容(只是系统映像的启动):
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));
如果我 运行 它如图所示(right-click 在 exe 上 运行 作为管理员)它 returns 0 这意味着它 failed。如果我 运行 它通过将 wbAdmin 命令行放在 test.bat 文件中(请参阅代码中 String strCmdLine
正上方的注释行)然后 CreateProcess returns a 1(成功)但是wbAdmin 仍然不是 运行ning。它闪烁了一个 DOS window,我如下图所示捕获了它。它在标题栏中显示东方字符,并表示无法识别为内部或外部命令。但是,如果我 运行 那个 test.bat 直接(提升)它 运行s wbAdmin 没问题。
有什么问题吗?除了我显然是无知的。 (p.s。之后我将在 ShellExecute 上测试 Golvind 的答案...)
您需要使用 "runas"
以管理员身份启动 CMD.exe,并将批处理文件指定为命令提示符的 "run-me-then-exit"(即 /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);
此处调用的两个函数都可能失败,健壮的代码会在继续之前测试是否成功。
Running the batch file manually (right-click and run as admin) works.
因为你是运行手动启动cmd时的64位版本。
It shows oriental characters in the title bar and says not recognized
as internal or external command.
因为您的应用程序是 32 位的。 32 位应用程序看不到与 64 位应用程序相同的 System32 文件夹。在32位应用程序中可以通过虚拟sysnative文件夹访问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 位。
我想从我的 FMX 应用程序(在 Win32 上)生成一个具有提升权限的批处理文件。从雷米在 ShellExecute 底部 of this thread 的回答中,我找到了如何启动批处理文件。现在,我不知道如何以提升的权限启动它。下面是我的代码:
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",但无济于事。 运行 手动批处理文件(right-click 和 运行 作为管理员)工作。以下是批处理文件的内容(只是系统映像的启动):
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));
如果我 运行 它如图所示(right-click 在 exe 上 运行 作为管理员)它 returns 0 这意味着它 failed。如果我 运行 它通过将 wbAdmin 命令行放在 test.bat 文件中(请参阅代码中 String strCmdLine
正上方的注释行)然后 CreateProcess returns a 1(成功)但是wbAdmin 仍然不是 运行ning。它闪烁了一个 DOS window,我如下图所示捕获了它。它在标题栏中显示东方字符,并表示无法识别为内部或外部命令。但是,如果我 运行 那个 test.bat 直接(提升)它 运行s wbAdmin 没问题。
有什么问题吗?除了我显然是无知的。 (p.s。之后我将在 ShellExecute 上测试 Golvind 的答案...)
您需要使用 "runas"
以管理员身份启动 CMD.exe,并将批处理文件指定为命令提示符的 "run-me-then-exit"(即 /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);
此处调用的两个函数都可能失败,健壮的代码会在继续之前测试是否成功。
Running the batch file manually (right-click and run as admin) works.
因为你是运行手动启动cmd时的64位版本。
It shows oriental characters in the title bar and says not recognized as internal or external command.
因为您的应用程序是 32 位的。 32 位应用程序看不到与 64 位应用程序相同的 System32 文件夹。在32位应用程序中可以通过虚拟sysnative文件夹访问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 位。