(РЕШЕНО) Есть примеры, как приложению правильно перезапусти?

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

(РЕШЕНО) Есть примеры, как приложению правильно перезапусти?

Сообщение Cheb » 04.03.2020 13:33:33

У кого нибудь есть рабочие примеры?

Когда-то мне это удавалось (ещё во времена WinXP), но сейчас - что-то не срастается.
То-ли лыжи не едут, то-ли я... косорукий.

Мой не работающий код:
Код: Выделить всё
  procedure RestartMyself(param: Utf8String);
  var
    ExeName, par: Utf16String;
    SI: TStartupInfoW;
    PI: TProcessInformation;
  begin
    FillChar(SI, SizeOf(SI), 0);
    FillChar(PI, SizeOf(PI), 0);
    SI.cb:=SizeOf(SI);
    SI.wShowWindow:= 1;
    ExeName:= FileNameToUtf16(GetExeFileName(@RestartMyself)) + #0;
    par:= Utf8Decode(param) + #0;
//***TODO WHY DOESNT THIS WORK :(((((   
    CreateProcessW(PUcs2Char(ExeName), PUcs2Char(par)
                                   , Nil, Nil, false, $20, Nil, Nil, @SI, @PI);
//**** STILL DOESNT *** F FF Fff*** WORK   
    WaitForInputIdle(PI.hProcess, 10000); // because halting without waiting
    // for it to really start causes it to not start at all
    halt(0);
  end;


Пытался дебажить, вставляя MessageBoxW - в переменных правильные значения D:\chentrah\chentrah.exe и --restart
И тишинаааа...
Последний раз редактировалось Cheb 04.03.2020 21:34:44, всего редактировалось 1 раз.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Re: Есть примеры, как приложению правильно перезапустить себ

Сообщение iskander » 04.03.2020 14:06:01

Хм, а так?
Код: Выделить всё
uses
  ..., Process;
procedure Restart(const aParam: string);
begin
  with TProcess.Create(nil) do
    try
      Executable := ParamStr(0);
      Parameters.Add(aParam);
      Active := True;
    finally
      Free;
    end;
  Halt(0);
end;
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Есть примеры, как приложению правильно перезапустить себ

Сообщение Cheb » 04.03.2020 21:33:56

Мне нельзя использовать TProcess, поскольку он не юникодный.
Иначе бы я сам так и сделал.

РЕШЕНО:
Вот вы будете громко смеяться, но я передрал определение CreateProcessW из unifun.inc (в исходниках RTL W функции есть ещё со времён 2.6.4, но скомпилирована она с A ). И проглядел мааахонькую подробность, там в использующем их модуле стоит {$calling stdcall}
То есть, у меня всё крашилось при вызове CreateProcessW из-за неверно выставленного соглашения о вызове, но исключение молча глоталось, поскольку все подсистемы движка к этому моменту уже остановлены.
Дописал прощёлканное клювом stdcall; - и всё сразу заработало.


Добавлено спустя 12 часов 13 минут 54 секунды:
Re: (РЕШЕНО) Есть примеры, как приложению правильно перезапусти?
Дополнение: чтобы работали параметры командной строки, второй параметр функции должен начинаться с названия екзешника в кавычках.
В MSDN этот момент не объясняется.
Также, WinAPI пишет во вторую переданную строку, используя ея в качестве буфера.

Код: Выделить всё
  procedure RestartMyself(param: Utf8String);
  var
    ExeName, par: Utf16String;
    SI: TStartupInfoW;
    PI: TProcessInformation;
  begin
    FillChar(SI, SizeOf(SI), 0);
    FillChar(PI, SizeOf(PI), 0);
    SI.cb:= SizeOf(SI);
    SI.wShowWindow:= 1;
    ExeName:= FileNameToUtf16(GetExeFileName(@RestartMyself));
    par:= Utf16String('"') + ExeName + '" ' + Utf8Decode(param) + #0;
    ExeName+= #0;
   
    ReleaseTheOnlyInstanceMutex;
   
    CreateProcessW(@(ExeName[1]), @(par[1])
                                   , Nil, Nil, false, $20, Nil, Nil, @SI, @PI);
    Halt(0);
  end;
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Re: (РЕШЕНО) Есть примеры, как приложению правильно перезапу

Сообщение zoltanleo » 05.03.2020 19:06:44

Cheb писал(а):Мне нельзя использовать TProcess, поскольку он не юникодный.

Документация говорит, что это не совсем так :)

Кроме того, Ваш способ, скорее всего, НЕкроссплатформенный.
Аватара пользователя
zoltanleo
постоялец
 
Сообщения: 457
Зарегистрирован: 17.10.2013 10:55:01

Re: (РЕШЕНО) Есть примеры, как приложению правильно перезапу

Сообщение Cheb » 06.03.2020 21:19:39

1. Мой движок - лазаренезависимый. Фактически, я перестал пользоваться лазарем даже как редактором кода, пересев на MseIDE. Так что, нету такого класса, как TProcessUTF8.
2. Конечно же, для пингвинов - отдельный вариант. Который ещё предстоит отлаживать, я его годами не проверял.
Код: Выделить всё
  procedure RestartMyself(param: Utf8String);
  begin
    ReleaseTheOnlyInstanceMutex;
    fpExecL(ParamStr(0), [param]);
    Halt(0);
  end;
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Re: (РЕШЕНО) Есть примеры, как приложению правильно перезапу

Сообщение pupsik » 09.03.2020 17:33:01

угу: есть mseprocess.... чем он не угодил.?
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: (РЕШЕНО) Есть примеры, как приложению правильно перезапу

Сообщение Cheb » 10.03.2020 11:46:57

..тем, что я не знал о нём?..
Спасибо, посмотрю его.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Re: (РЕШЕНО) Есть примеры, как приложению правильно перезапу

Сообщение Alex2013 » 10.03.2020 15:11:28

Уже писал когда-то ... но искать по форуму лень.
Если приложение использует LCL то можно просто сделать примерно так
В модуле с формой что-то вроде этого..
Код: Выделить всё
const
  Restart:boolean=False;

  Procedure AppRestart;
  begin
      Restart:=True;
   { Тут  не забыть очистить память выделенную
     самостоятельно в обход конструкторов/деструкторов     
     и сбросить глобальные флаги.
      В нормальном приложении ничего такого быть не должно..
      но вдруг! }
     Application.Terminate;
  end;

А в проекте как-то так.
Код: Выделить всё
...
repeat
  Restart:=False;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
until not Restart;
..

Использовал для переключения языков интерфейса .
Alex2013
долгожитель
 
Сообщения: 2923
Зарегистрирован: 03.04.2013 11:59:44

Re: (РЕШЕНО) Есть примеры, как приложению правильно перезапу

Сообщение Cheb » 11.03.2020 16:59:06

Интересная идея, но это только если использовать лазарус.

Также, неприменимо, когда:
- внутреннее состояние запорото, очистка невозможна
- произошёл крах и исключение пробило куда не должно было

Мне в движке перезапуск нужен для случая "Всё упало. Перезапустить?". Позже, может быть , добавится переключение между GL/ANGLE или мониторами.
И вообще, начать с чистого листа - надёжнее.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 22

Рейтинг@Mail.ru