0

によって開かれたプログラムでUACプロンプトをトリガーするアプリケーションに取り組んでいますShellExecute

を実行するためのパスをハードコーディングする方法がわかりませんShellExecute。現在のところ、このプログラムはにあるパスを使用しarg[0]ます。arg[0]行の代わりに配置する文字列を作成するにはどうすればよいsinfo.lpFile = arg[0];ですか?

私は非常に新しいので、その行に文字列を入れることが私の問題を解決する理由がわからない場合は、おそらく正しいでしょう。

#include "stdafx.h"

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <shellapi.h>
#include <process.h>

#include "uac-example.h"

int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst,LPSTR cmdLine, int nCmdShow){
    LPWSTR *arg;
    int argc = 0;
    HRESULT ret = SUCCESS;
    WCHAR imagePath[MAXPATHLEN];
    WCHAR workingDir[MAXPATHLEN];
    WCHAR uacDir[MAXPATHLEN];
    WCHAR uacRunningLockFilePath[MAXPATHLEN];
    HANDLE uacRunningLockFileHandle = INVALID_HANDLE_VALUE;
    WCHAR elevatedLockFilePath[MAXPATHLEN];
    HANDLE elevatedLockFileHandle = INVALID_HANDLE_VALUE;
    arg = CommandLineToArgvW(GetCommandLineW(),&argc);
    //if(arg == NULL || argc < 2) {
    //  ERRORBOX("Missing required program arguments.\n\nUsage:\nuac-example.exe <working directory>");
    //  return FAILURE;
    //}
    GetModuleFileName(NULL, imagePath, MAXPATHLEN);
    arg[0] = imagePath;
    wcscpy_s((wchar_t *)uacDir, MAXPATHLEN, arg[1]);
    _snwprintf_s(uacRunningLockFilePath, MAXPATHLEN, MAXPATHLEN,
                    _T("%s/") _T(RUNNING_LOCK_FILE), uacDir);
    wcscpy_s(workingDir, MAXPATHLEN, imagePath);
    WCHAR *slash = wcsrchr(workingDir, '\\');
    wcscpy_s(slash, MAXPATHLEN, _T(""));
    _snwprintf_s(elevatedLockFilePath, MAXPATHLEN, MAXPATHLEN,_T("%s/") _T(ELEVATE_LOCK_FILE), workingDir);
    uacRunningLockFileHandle = CreateFileW(uacRunningLockFilePath,(GENERIC_READ | GENERIC_WRITE),0,NULL,OPEN_ALWAYS,FILE_FLAG_DELETE  _ON_CLOSE,NULL);
    if (uacRunningLockFileHandle == INVALID_HANDLE_VALUE) {
        if (_waccess(elevatedLockFilePath, F_OK) == 0 &&
                _wremove(elevatedLockFilePath) != 0) {
            return FAILURE;
        }
        elevatedLockFileHandle = CreateFileW(elevatedLockFilePath,(GENERIC_READ | GENERIC_WRITE),0,NULL,OPEN_ALWAYS,FILE_FLAG_DELETE  _ON_CLOSE,NULL);
        if(elevatedLockFileHandle == INVALID_HANDLE_VALUE){
            ERRORBOX("Unable to acquire the necessary permissions to run demo app.");
            return FAILURE;
        }
        LPWSTR spawnCmdLine = BuildCommandLine(argc - 1, arg + 1);
        if(!spawnCmdLine){
            CloseHandle(elevatedLockFileHandle);
            ERRORBOX("An error occured while respawning self.");
            return FAILURE;
        }
        SHELLEXECUTEINFO sinfo;
        memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
        sinfo.cbSize = sizeof(SHELLEXECUTEINFO);
        sinfo.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS;
        sinfo.hwnd = NULL;
        sinfo.lpFile = arg[0];
        sinfo.lpParameters = spawnCmdLine;
        sinfo.lpVerb = L"runas"; // <<-- this is what makes a UAC prompt show up
        sinfo.nShow = SW_SHOWMAXIMIZED;
        BOOL result = ShellExecuteEx(&sinfo);
        LocalFree(spawnCmdLine);
        if(result){
            WaitForSingleObject(sinfo.hProcess, INFINITE);
            CloseHandle(sinfo.hProcess);
            return SUCCESS;
        }else{
            return FAILURE;
        }
    }
    EXIT_IF_ELEVATED(elevatedLockFilePath,uacRunningLo  ckFileHandle,SUCCESS);
    LocalFree(arg);
    return SUCCESS;
}

// ----------------------------------------------------------------------
// The following code was taken directly from the Mozilla Firefox Updater
// source tree, and slightly modified to support "Wide" strings in
// Visual C++.
// ----------------------------------------------------------------------

LPWSTR
BuildCommandLine(int argc, LPWSTR *argv){
    int i;
    int len = 0;
    // The + 1 of the last argument handles the
    // allocation for null termination
    for (i = 0; i < argc; ++i) {
        len += ArgStrLen(argv[i]) + 1;
    }
    // Protect against callers that pass 0 arguments
    if (len == 0) {
        len = 1;
    }
    LPWSTR s = (LPWSTR)malloc(len * sizeof(LPWSTR));
    if (!s) {
        return NULL;
    }
    LPWSTR c = s;
    for (i = 0; i < argc; ++i) {
        c = ArgToString(c, argv[i]);
        if (i + 1 != argc) {
            *c = ' ';
            ++c;
        }
    }
    *c = '\0';
    return s;
}
int
ArgStrLen(LPWSTR s) {
  int backslashes = 0;
  int i = wcslen(s);
  BOOL hasDoubleQuote = wcschr(s, L'"') != NULL;
  // Only add doublequotes if the string contains a space or a tab
  BOOL addDoubleQuotes = wcspbrk(s, L" \t") != NULL;
  if (addDoubleQuotes) {
    i += 2; // initial and final duoblequote
  }
  if (hasDoubleQuote) {
    while (*s) {
      if (*s == '\\') {
        ++backslashes;
      } else {
        if (*s == '"') {
          // Escape the doublequote and all backslashes preceding the doublequote
          i += backslashes + 1;
        }
        backslashes = 0;
      }

      ++s;
    }
  }

  return i;
}
LPWSTR
ArgToString(LPWSTR d, LPWSTR s) {
  int backslashes = 0;
  BOOL hasDoubleQuote = wcschr(s, L'"') != NULL;
  // Only add doublequotes if the string contains a space or a tab
  BOOL addDoubleQuotes = wcspbrk(s, L" \t") != NULL;
  if (addDoubleQuotes) {
    *d = '"'; // initial doublequote
    ++d;
  }
  if (hasDoubleQuote) {
    int i;
    while (*s) {
      if (*s == '\\') {
        ++backslashes;
      } else {
        if (*s == '"') {
        // Escape the doublequote and all backslashes\
        // preceding the doublequote
          for (i = 0; i <= backslashes; ++i) {
            *d = '\\';
            ++d;
          }
        }
        backslashes = 0;
      }
      *d = *s;
      ++d; ++s;
    }
  } else {
    wcscpy(d, s);
    d += wcslen(s);
  }
  if (addDoubleQuotes) {
    *d = '"'; // final doublequote
    ++d;
  }
  return d;
}
4

1 に答える 1

1

単に:

char path[] = "C:\\program.exe";
sinfo.lpFile = path;
于 2012-11-27T00:02:29.553 に答える