ShellExecute bat файл повышен (FMX, Win32) - PullRequest
0 голосов
/ 09 февраля 2019

Я хочу создать пакетный файл из моего приложения FMX (на Win32) с повышенными привилегиями.Из ответа Реми внизу этой темы на ShellExecute я узнал, как запустить командный файл.Теперь я не могу понять, как запустить его с повышенными привилегиями.Ниже мой код:

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");
}

Я добавил "runas" для второго аргумента после прочтения this безрезультатно.Запуск пакетного файла вручную (щелкните правой кнопкой мыши и запустите от имени администратора) работает.Вот содержимое командного файла FYI (только пинки системного образа):

c:\Windows\system32\wbAdmin.exe start backup -backupTarget:D: -include:C: -allCritical -quiet

Как я могу ShellExecute этот пакетный файл от имени администратора?

ОБНОВЛЕНИЕ 1: Я пытаюсьиспользуйте CreateProcess в соответствии с предложением Реми.Вот мой код (на основе этот пример ):

//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 и запустите от имени администратора), он возвращает 0, что означает его не удалось .Если я запускаю его, помещая командную строку wbAdmin в файл test.bat (см. Закомментированную строку прямо над String strCmdLine в коде), то CreateProcess возвращает 1 (успех), но wbAdmin все еще не запущен.Он высветил окно DOS, и я запечатлел его, как показано на рисунке ниже.Он показывает восточные символы в строке заголовка и говорит, что не распознается как внутренняя или внешняя команда.Но если я запускаю этот test.bat напрямую (с повышенными правами), он запускает wbAdmin без проблем.

Есть идеи, что не так?Кроме меня, очевидно, быть невежественным.(PS После этого я вернусь к проверке ответа Голвинда на ShellExecute ...)

enter image description here

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Запуск пакетного файла вручную (щелкните правой кнопкой мыши и запустите от имени администратора) работает.

Поскольку вы запускаете 64-битную версию cmd при запуске вручную.

Показывает восточные символы в строке заголовка и говорит, что не распознается как внутренняя или внешняя команда.

Поскольку ваше приложение 32-разрядное.32-разрядное приложение не видит ту же папку System32, что и 64-разрядные приложения.Вы можете получить доступ к 64-битной папке System32 в 32-битных приложениях с помощью виртуальной папки sysnative.

#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-битную версию.

0 голосов
/ 09 февраля 2019

Вам нужно запустить CMD.exe в качестве администратора с "runas" и указать командный файл в качестве аргумента «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);

Обе функции, вызываемые здесь, могут потерпеть неудачу, и надежный код проверит успешность перед продолжением.

...