Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Программа и интерфейс
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 15.02.2024, 20:39
T232006 T232006 вне форума
Прохожий
 
Регистрация: 17.11.2022
Сообщения: 49
Версия Delphi: Delphi XE5
Репутация: 10
Печаль Запуск консольного приложения из 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;
	}
}
В чем может быть дело? Почему shellExecute отрабатывает, а описанная выше отрабатывает только тестовые? Весь день уже убил.
Ответить с цитированием
  #2  
Старый 16.02.2024, 23:44
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

В свое время мучался с подобной проблемой с POS-терминалом.
Решилось подбором нужной комбинации параметров/флагов у CreateProcess.

Еще можно попробовать запустить это дело через cmd.exe
Если правильно помню, то
Код:
cmd.exe /c [command] [args]
В таком виде хоть можно будет смотреть что там выводится, если перенаправить вывод в файл.
Ответить с цитированием
  #3  
Старый 17.02.2024, 10:32
T232006 T232006 вне форума
Прохожий
 
Регистрация: 17.11.2022
Сообщения: 49
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

данное консольное приложение ничего не выводит на экран и при запуске из командной строки отрабатывает прекрасно (файл появляется в GoogleDrive). Даже с ShellExecute работает прекрасно. Очевидно, что ShellExecute запускает CreateProcess с какими-то параметрами, но вот с какими... В delphi он вызывается из dll ShellAPI и подглядеть что там и как не представляется возможным. Насчет игры с параметрами - возможно, однако все параметры CreateProcess известны и я даже не знаю, в каком из них может быть подвох.
Ответить с цитированием
  #4  
Старый 17.02.2024, 21:33
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну, для начала, тогда если у тебя CreateProcess вернул FALSE (т.е не выполнился), то надо вызвать GetLastError и посмртреть код ошибки.
Ответить с цитированием
  #5  
Старый 18.02.2024, 10:18
T232006 T232006 вне форума
Прохожий
 
Регистрация: 17.11.2022
Сообщения: 49
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

нет, createProcess не вернул false. Он отработал нормально, появилось окно и сразу исчезло, хотя должно было висеть всё время пока идет закачка.
Ответить с цитированием
  #6  
Старый 19.02.2024, 20:41
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Это значит, что все-таки процесс запускается. Но, например, параметры переданы не совсем правильно.
Сделай командный файл и внутри него выведи какие парамерты передаются. Ну или в своей тестовой обманке выведи в файл лога.
Например, у тебя в пути есть пробелы. В этом случае надо кавычить значения.
Ответить с цитированием
  #7  
Старый 19.02.2024, 22:25
T232006 T232006 вне форума
Прохожий
 
Регистрация: 17.11.2022
Сообщения: 49
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

Это первое, что пришло в голову и именно для этого и создан файл-обманка. в параметрах нет ошибки, иначе бы не сработал shellexecute. А он, как я уже говорил, работает превосходно.
Ответить с цитированием
  #8  
Старый 20.02.2024, 13:46
Shaft Shaft вне форума
Новичок
 
Регистрация: 15.05.2013
Сообщения: 74
Версия Delphi: 7/10.4
Репутация: 12
По умолчанию

Код:
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  
Старый 20.02.2024, 20:15
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Если у тебя параметр "развалится", ShellExecute сработает нормально, ему главное найти сам бинарник (кстати, ShellExecute может найти его, а вот CreateProcess требует точного указания пути), зато само приложение получит не правильные параметры и не сработает.

Например:
myapp.exe c:\temp folder\temp file.txt
В этом случае запускаемое приложение получит 3 разных параметра.
А вот если так:
myapp.exe "c:\temp folder\temp file.txt"
то приложение получит один параметр.
Для ShellExecute все ок, а вот для приложения - нет.
Ответить с цитированием
  #10  
Старый 20.02.2024, 20:39
T232006 T232006 вне форума
Прохожий
 
Регистрация: 17.11.2022
Сообщения: 49
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

Да, shellexecute найдет бинарник, но не сработает, если параметр будет неверным. В любом случае, обманка выводит на экран список параметров и они верны.
Ответить с цитированием
  #11  
Старый 20.02.2024, 20:40
T232006 T232006 вне форума
Прохожий
 
Регистрация: 17.11.2022
Сообщения: 49
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

Цитата:
Сообщение от Shaft
А если так попробовать?
В списке параметров нет пробелов
Ответить с цитированием
  #12  
Старый 20.02.2024, 21:03
Shaft Shaft вне форума
Новичок
 
Регистрация: 15.05.2013
Сообщения: 74
Версия Delphi: 7/10.4
Репутация: 12
По умолчанию

Цитата:
Сообщение от T232006
В списке параметров нет пробелов
Дело не в пробелах, там в CreateProcess вся команда передается вторым аргументом вместе с параметрами, я всегда так CreateProcess юзаю, проблем не было
Ответить с цитированием
  #13  
Старый 20.02.2024, 21:18
T232006 T232006 вне форума
Прохожий
 
Регистрация: 17.11.2022
Сообщения: 49
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

Цитата:
Сообщение от Shaft
Дело не в пробелах, там в CreateProcess вся команда передается вторым аргументом вместе с параметрами, я всегда так CreateProcess юзаю, проблем не было
Тот же эффект: моргнет и исчезнет.
Ответить с цитированием
  #14  
Старый 20.02.2024, 21:33
Shaft Shaft вне форума
Новичок
 
Регистрация: 15.05.2013
Сообщения: 74
Версия Delphi: 7/10.4
Репутация: 12
По умолчанию

Цитата:
Сообщение от T232006
Тот же эффект: моргнет и исчезнет.
А можно посмотреть строку которая передается в CreateProcess, вместе с параметрами целиком. Если там логины пароли вместо них рандомные слова
Ответить с цитированием
  #15  
Старый 20.02.2024, 23:07
Shaft Shaft вне форума
Новичок
 
Регистрация: 15.05.2013
Сообщения: 74
Версия Delphi: 7/10.4
Репутация: 12
По умолчанию

Как вариант еще вот так попробовать
Код:
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.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:47.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter