2015-01-27 3 views
4

Я пытаюсь реализовать CreateProcessW в DLL, чтобы пользователь мог запустить приложение в отдельном процессе.CreateProcessW не выполняет командную строку

Для начала я жестко прописывать команды в коде, пока я не понять это ..

У меня

STARTUPINFO si = {sizeof(STARTUPINFO), 0}; 
si.cb = sizeof(si); 
PROCESS_INFORMATION pi = {0}; 
LPCTSTR AppName=L"c:\\utilities\\depends.exe"; 
LPTSTR Command = L"c:\\utilities\\tee.exe"; 
if (CreateProcessW(AppName, Command, 0, 0, 0, CREATE_DEFAULT_ERROR_MODE, 0, 0, &si, &pi)) { 
     CloseHandle(pi.hThread); 
     CloseHandle(pi.hProcess); 
     return GX_RESULT_OK; 
    } else { 
     .. show error msg 
    } 

Это запустит Depends, но не откроет Tee.exe. Нет ошибки, она просто игнорирует параметр командной строки. Параметры верны, и я могу запустить его в командной строке, и он работает нормально. Если я оставлю AppName пустым и задайте Depends.exe в качестве параметра командной строки также работает, но если я указываю

LPTSTR Command = L"c:\\utilities\\depends.exe c:\\utilities\\tee.exe"; 

Я получаю Ошибка 3: «Система не может найти указанный путь».

Также, указав параметр lpCurrentDirectory, он также игнорируется.

+2

Мой хрустальный шар говорит, что вы обфускали свой код, а реальный путь - не c: \ utilities. Но тот, у которого есть пробелы в имени пути. Это требует, чтобы вы добавляли двойные кавычки по пути, чтобы он не анализировался в несколько аргументов командной строки. –

+0

@HansPassant извините, но ваш шар затуманился! Я специально выбрал путь без пробелов, чтобы устранить эту потенциальную проблему. – marcp

+0

Хорошо, следующая проблема - это второй аргумент. Обратите внимание, что это LPTSTR, а не LPCTSTR. Другими словами, CreateProcess должен иметь возможность записывать в этот строковый буфер. Он не может с вашей стороны, вы передали литерал. Это определенно одна из самых блестящих функций winapi, вместо этого вы должны использовать ShellExecuteEx(). –

ответ

1

Вы должны предоставить исполняемый файл в command

  • Appname должен содержать полный путь к исполняемому файлу
  • Command должен содержать также argv[0]

, если вы хотите открыть файл t.txt с помощью блокнота, который вы можете указать следующим образом:

  • Appname = "c:/windows/notepad.exe";
  • command = "notepad c:/temp/t.txt";

Вы даже не должны поставить реальное имя программы, даже вымышленное имя будет делать эту работу, так как это только место держатель.

так: command = "fake c:/temp/t.txt";

сейчас в notepad.exe:

  • argv[0] = "notepad";
  • argv[1] = "c:/temp/t.txt";

Смотрите этот полный пример:

#include <Windows.h> 
#include <iostream> 

using namespace std; 

int main(){ 
    STARTUPINFO si = {sizeof(STARTUPINFO), 0}; 
    si.cb = sizeof(si); 
    PROCESS_INFORMATION pi = {0}; 
    LPTSTR AppName=L"C:/Windows/notepad.exe"; 
    wchar_t Command[] = L"notepad C:/Temp/t.txt"; 
    DWORD res = CreateProcess(AppName, Command, 0, 0, 0, CREATE_DEFAULT_ERROR_MODE, 0, 0, &si, &pi); 
    if (res) { 
     CloseHandle(pi.hThread); 
     CloseHandle(pi.hProcess); 
     return 0; 
    } else { 
     cerr<<"error..."<<GetLastError()<<endl; 
    }; 
    return 0; 
} 
+0

Второй параметр должен быть редактируемой памятью. Используйте 'wchar_t Command [] = L" блокнот C: /Temp/t.txt ";' –

+0

@DavidHeffernan, согласно MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425 (v = vs.85) .aspx) LPTSTR - правильный тип переменной. – marcp

+0

@marcp Да, но литерал является только «LPTSTR» из обратной совместимости с K & R C. Вам не разрешено изменять их. Я второй человек, чтобы рассказать вам об этом. Беглый веб-поиск найдет бесчисленное множество людей, говорящих то же самое. Мы действительно знаем, о чем говорим. –

Смежные вопросы