Winapi ShellExecute bat文件提升(FMX,Win32)

Winapi ShellExecute bat文件提升(FMX,Win32),winapi,firemonkey,c++builder,Winapi,Firemonkey,C++builder,我想从我的FMX应用程序(在Win32上)生成一个具有提升权限的批处理文件。从ShellExecute底部Remy的回答中,我找到了如何启动批处理文件。现在,我不知道如何以提升的权限启动它。下面是我的代码: String Prog = "c:\\Users\\rwp\\Desktop\\test.bat"; int nErrorCode = (int) ShellExecute(NULL, L"runas", Prog.c_str(), NULL, NULL, SW_SHOWNORMAL); i

我想从我的FMX应用程序(在Win32上)生成一个具有提升权限的批处理文件。从ShellExecute底部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");
}
如何以管理员身份执行此批处理文件

更新1:我正试图根据Remy的建议使用CreateProcess。这是我的代码(基于):

如果我如图所示运行它(右键单击exe并以管理员身份运行),它将返回0,这意味着它。如果我通过将wbAdmin命令行放入test.bat文件来运行它(请参阅代码中字符串strCmdLine正上方的注释行),则CreateProcess返回1(成功),但wbAdmin仍然没有运行。它闪烁着DOS窗口,我捕捉到了它,如下图所示。它在标题栏中显示东方字符,并表示不可识别为内部或外部命令。但是,如果我直接(提升)运行test.bat,它就可以运行wbAdmin

有什么问题吗?除此之外,我显然是无知的。(顺便说一下,我会在外壳上测试Golvind的答案,然后执行…)


您需要以管理员身份启动CMD.exe,使用
“runas”
,并将批处理文件指定为命令提示符的“运行我然后退出”(即
/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);
这里调用的两个函数都可能失败,健壮的代码将在继续之前测试是否成功

手动运行批处理文件(右键单击并以管理员身份运行)可以正常工作

因为手动启动时运行的是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
    }
#包括
...
String strCmdLine=“wbAdmin.exe启动备份-备份目标:T:-包括:C:-所有关键-安静”;
int rtrn=CreateProcess(
无效的
strCmdLine.c_str(),
NULL,//进程安全属性
NULL,//主线程安全属性
0,//句柄被继承
0,//创建标志
0,//使用父环境
0,//使用父级的当前目录
&siStartInfo,//STARTUPINFO指针
&piProcInfo);//接收进程信息
如果(!rtrn)
{
String newCmdLine=“c:\\windows\\sysnative\\wbAdmin.exe启动备份-备份目标:T:-包括:c:-所有关键-安静”;
rtrn=CreateProcess(
无效的
newCmdLine.c_str(),
NULL,//进程安全属性
NULL,//主线程安全属性
0,//句柄被继承
0,//创建标志
0,//使用父环境
0,//使用父级的当前目录
&siStartInfo,//STARTUPINFO指针
&piProcInfo);//接收进程信息
}

或者将应用程序编译为64位。

由于
bat
由一个命令组成,因此我只需使用
CreateProcess()
直接运行
wbAdmin.exe
,如果它本身还没有运行提升,那么在调用该命令之前让你的应用程序运行提升。这不是一个直接的答案,但你可以从中获得灵感:不明白为什么你可以让shell解决如何打开batfile@DavidHeffernan我相信,如果只使用批处理文件的路径作为
ShellExecute
,无论运行方式如何,它都不会请求提升。这不起作用,与我所做的CreateProcess尝试的结果相同(请参见上面的更新1)。我可以右键单击并以管理员的身份运行test.bat文件,它可以正常工作(启动wbAdmin并开始创建系统映像)。上面的代码不起作用。如果我将wbAdmin行替换为“notepad.exe”,它将打开记事本并保持CMD打开,直到我关闭记事本。看起来它不太喜欢提升。编译为64位工作-让我启动test.bat文件提升并运行wbAdmin。使用其他方法(使用c:\\windows\\sysnative路径)会导致KERNELLBASE.dll冲突。从未听说过该系统本机文件夹,但找不到它。谢谢。sysnative是一个虚拟文件夹,因此您无法找到它。它只是64位Windows系统提供的重定向机制。64位Windows将其重定向到real System 32文件夹。
WCHAR wszCmdPath[MAX_PATH];
GetEnvironmentVariableW(L"ComSpec", wszCmdPath, MAX_PATH);
ShellExecuteW(NULL, L"runas", wszCmdPath, L"/c \"C:\\Path\\BatchFile.bat\"", L"", SW_SHOW);
#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
    }