|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Запуск консольного приложения из Delphi
Здравствуйте!
У меня есть консольное приложение, написанное на C#, закидывающее некий файл на GoogleDrive. Это приложение нужно запустить из приложения Delphi, но при этом дождаться окончания загрузки (то есть, ничего не делать, пока консольное приложение работает). Через ShellExecute всё работает замечательно, но приложение не дожидается окончания работы консоли. Я использую следующую функцию: Код:
function WinExecAndWait(Filename, params, dir: string):cardinal; var WorkDir, programName:string; StartupInfo:TStartupInfo; ProcessInfo:TProcessInformation; begin GetDir(0,WorkDir); programName:=WorkDir+'\'+dir+'\'+FileName; FillChar(StartupInfo,Sizeof(StartupInfo),#0); StartupInfo.cb:= Sizeof(StartupInfo); StartupInfo.dwFlags:= STARTF_USESHOWWINDOW; StartupInfo.wShowWindow:= SW_SHOW; if not CreateProcess(PChar(ProgramName), PChar(params), nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then result := 0 else begin WaitforSingleObject(ProcessInfo.hProcess, INFINITE); GetExitCodeProcess(ProcessInfo.hProcess, result); end; end; Код консольного приложения такой: Код:
internal class Program { static async Task Main(string[] args) { var gu = GoogleUploader.Upload(args[0], args[1], args[2]); await gu; } } |
#2
|
|||
|
|||
В свое время мучался с подобной проблемой с POS-терминалом.
Решилось подбором нужной комбинации параметров/флагов у CreateProcess. Еще можно попробовать запустить это дело через cmd.exe Если правильно помню, то Код:
cmd.exe /c [command] [args] |
#3
|
|||
|
|||
данное консольное приложение ничего не выводит на экран и при запуске из командной строки отрабатывает прекрасно (файл появляется в GoogleDrive). Даже с ShellExecute работает прекрасно. Очевидно, что ShellExecute запускает CreateProcess с какими-то параметрами, но вот с какими... В delphi он вызывается из dll ShellAPI и подглядеть что там и как не представляется возможным. Насчет игры с параметрами - возможно, однако все параметры CreateProcess известны и я даже не знаю, в каком из них может быть подвох.
|
#4
|
|||
|
|||
Ну, для начала, тогда если у тебя CreateProcess вернул FALSE (т.е не выполнился), то надо вызвать GetLastError и посмртреть код ошибки.
|
#5
|
|||
|
|||
нет, createProcess не вернул false. Он отработал нормально, появилось окно и сразу исчезло, хотя должно было висеть всё время пока идет закачка.
|
#6
|
|||
|
|||
Это значит, что все-таки процесс запускается. Но, например, параметры переданы не совсем правильно.
Сделай командный файл и внутри него выведи какие парамерты передаются. Ну или в своей тестовой обманке выведи в файл лога. Например, у тебя в пути есть пробелы. В этом случае надо кавычить значения. |
#7
|
|||
|
|||
Это первое, что пришло в голову и именно для этого и создан файл-обманка. в параметрах нет ошибки, иначе бы не сработал shellexecute. А он, как я уже говорил, работает превосходно.
|
#8
|
|||
|
|||
Код:
cmd:='C:\Project1.exe "param1" "param2" "param3"'; CreateProcess(nil, PChar(cmd), nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo); |
#9
|
|||
|
|||
Если у тебя параметр "развалится", ShellExecute сработает нормально, ему главное найти сам бинарник (кстати, ShellExecute может найти его, а вот CreateProcess требует точного указания пути), зато само приложение получит не правильные параметры и не сработает.
Например: myapp.exe c:\temp folder\temp file.txt В этом случае запускаемое приложение получит 3 разных параметра. А вот если так: myapp.exe "c:\temp folder\temp file.txt" то приложение получит один параметр. Для ShellExecute все ок, а вот для приложения - нет. |
#10
|
|||
|
|||
Да, shellexecute найдет бинарник, но не сработает, если параметр будет неверным. В любом случае, обманка выводит на экран список параметров и они верны.
|
#11
|
|||
|
|||
Цитата:
|
#12
|
|||
|
|||
Цитата:
|
#13
|
|||
|
|||
Цитата:
|
#14
|
|||
|
|||
Цитата:
|
#15
|
|||
|
|||
Как вариант еще вот так попробовать
Код:
function WinExecAndWait(Filename, params, dir: string):cardinal; var WorkDir, programName:string; StartupInfo:TStartupInfo; ProcessInfo:TProcessInformation; begin GetDir(0,WorkDir); programName:=WorkDir+'\'+dir+'\'+FileName; FillChar(StartupInfo,Sizeof(StartupInfo),#0); StartupInfo.cb:= Sizeof(StartupInfo); StartupInfo.dwFlags:= STARTF_USESHOWWINDOW; StartupInfo.wShowWindow:= SW_SHOW; if not CreateProcess(nil, PChar(ProgramName+' '+params), nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, PChar(ExtractFilePath(programName)), StartupInfo, ProcessInfo) then result := 0 else begin WaitforSingleObject(ProcessInfo.hProcess, INFINITE); GetExitCodeProcess(ProcessInfo.hProcess, result); end; end; //юзал WinExecAndWait('test.exe','"param1" "param2" "param3"','testdir'); Последний раз редактировалось Shaft, 20.02.2024 в 23:11. |