
Начал делать самодельную "Оболочку для оболочки" Shell2Shell
(Пока пишу сугубо под винду но в принципе "это неточно" (поживем увидим ) )
Суть идеи в написании "универсального лаунчера"(Пускателя ) для проектов подобных "Автоматике 1111 Stable Diffusion".
(Возможно с плагинами, доступом АПИ и разной "гибридной технологии", которую лучше делать в виде обычной программы вместо того чтобы, лепить все подряд в веб-интерфейс (и питон-скрипты) (по сути это будет гибрид "NMKD Stable Diffusion GUI " и "Автоматики 1111") )
>>>Что даст это приложение,кроме вывода окна терминала? В чем отличие от обычной веб версии Автоматика ?
1 Выбор вариантов запуска (Причем одна программа сможет запускать множество разных оболочек с разными настройками)
2 Строго говоря пока что этот проект не имеет особой привязки ни к "Автоматике 1111" ни к SD
(можно запустить что угодно включая чисто онлайновые сервисы или на против сугубо консольные проекты)
3 Дико надоело то что нужно постоянно запускать браузер
("автоматический" пуск еще хуже так как вываливает все открытые окна, закладки и т.д.)
4 В ближайшем будущем сделаю парсинг консоли (терминала ) .
5 Часть вещей которых нет в веб-оболочке (или они сделаны очень неуклюже ) гораздо проще сделать в виде классической "монолитной" программы
(но с встроенными скриптами и плагинами).
6 Такую "оболочку для оболочки" по идее ничего не стоит научить полностью автоматической установке моделей и самой SD+""Автоматики 1111""
7 В дальнейшем можно сделать дополнительный "прямой доступ к API" что может вообще делать почти любые вещи на которые хватит фантазии.
Добавлено спустя 6 минут 23 секунды:
>>S2S_bin0_4_1.7z

Это разумеется не более чем ранняя альфа версия .
Но интересна идеей "инкапсуляции гибридных API" и созданием "интегральных" сборок разнородных сервисов .
"Захват консоли" идет в двух режимах "виртуальном"(в нем можно парсить консольный вывод ) и "реальном" ( обычная консоль "удочеренная" через SetParent )
"Экстренная остановка" выполняется через KillProcessTree (Все-бы хорошо да работает только в 32-х разрядном режиме )
Зы
"Виртуальная консоль" RunDosInMemo (Консольный вывод из "Автоматики 1111" изрядно наворочен и "обычный мемо" для него не слишком годится так что буду переделывать)
- Код: Выделить всё
- Procedure RunDosInMemo(CmdLine: String; AMemo: TMemo);
 Const
 ReadBuffer = 1023;
 Var
 Security: TSecurityAttributes;
 OutReadPipe, OutWritePipe: tHandle; // труба для output'a консольной проги.
 InReadPipe, InWritePipe: tHandle; // труба для input'a консольной проги.
 ErrReadPipe, ErrWritePipe: tHandle; // труба для error's консольной проги.
 // InReadPipe, ErrReadPipe и объявлены для полноты картины,но не создаются и не используются.
 start: TStartUpInfo;
 ProcessInfo: TProcessInformation;
 Buffer: Pchar;
 BytesRead: DWord;
 Apprunning: DWord;
 avail : dword;
 notread:dword;
 stop:boolean;
 Begin
 stop := false;
 With Security Do Begin // инициализация структуры
 nlength := SizeOf(TSecurityAttributes);
 binherithandle := true;
 lpsecuritydescriptor := Nil;
 End;
 Createpipe(InReadPipe, InWritePipe, @Security, 0);
 Createpipe(ErrReadPipe, ErrWritePipe, @Security, 0);
 If Createpipe(OutReadPipe, OutWritePipe, @Security, 0) Then Begin
 // создали трубу для выхлопа бэкграунд-приложения
 Buffer := AllocMem(ReadBuffer + 1);
 // создали буфер для чтения
 FillChar(Start, Sizeof(Start), #0);
 // заполнили содержимое стартовой структуры #0
 start.cb := SizeOf(start);
 start.hStdOutput := OutWritePipe;
 start.hStdError := OutWritePipe;
 start.hStdInput := InReadPipe;
 (*************************************************************
 такой себе опширненьний комментарий...
 Оказывается, мать их так, если сделать перенаправление
 вывода в трубы, но не читать его, то если он(вывод)
 будет достаточно длинный и сможет переполнить буфер,
 который изначально отводится под трубу, то пишущий поток
 остановится и будет ждать пока не освободится место в
 буфере трубы. Как только оно освободилось, он сможет
 продолжать работу и писать дальше.
 
 start.hStdOutput := OutWritePipe;
 start.hStdError := OutWritePipe;
 
 почему собственно такой странный код: два потока
 перенаправлены в одну трубу?
 Потому что некоторые замечательные проги типа 7zip свой
 вывод направляют не в StdOut, а почему то в StdErr...
 и если для этих двух потоков назначить две разных трубы,
 а читать только одну, то произойдет то, что описано выше.
 РРРРРРРРРРРРРРРРРРРРРРРРР!!!!!!!!! сопли, слюни, ярость и
 буйное помешательство на почве программирования под винду.
 
 Может стоит сделать две трубы и читать каждую в отдельное
 мемо???
 **************************************************************)
 start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
 start.wShowWindow := SW_HIDE;
 // окно прячем
 
 If CreateProcess(Nil, PChar(CmdLine), @Security, @Security, true, NORMAL_PRIORITY_CLASS,
 Nil, Nil, start, ProcessInfo) Then Begin
 // создали процесс
 Repeat
 Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 100);
 PeekNamedPipe(OutReadPipe, @Buffer[0], ReadBuffer, @BytesRead, @avail, @notread);
 // PeekNamedPipe копирует из буфера трубы и оставляет его в первоначальном состоянии
 // в то время как ReadFile читая из трубы - опустошает ее.
 // PeekNamedPipe можно использовать для того чтобы узнать сколько данных есть в трубе
 // и если в PeekNamedPipe передать 2 и 3 параметры пустыми, то она просто скажет
 // сколько данных есть в трубе
 if avail > 0 then begin
 ReadFile(OutReadPipe, Buffer[0], BytesRead, BytesRead, Nil); // *******
 // ReadFile при чтении из трубы опустошает ее(трубы) буфер.
 end
 else begin
 if Apprunning <> 258 then
 stop := true;
 end;
 // читаем через читающий конец трубы из вывода консоли
 Buffer[BytesRead] := #0;
 // последний символ #0 - конец буфера
 OemToAnsi(Buffer, Buffer);
 // перевели из кодировки DOS в кодировку WIN
 AMemo.Text := AMemo.text + String(Buffer);
 // то что прочитали приписали к тексту в мемо
 Application.ProcessMessages;
 // обработали очередь сообщений
 // Until ((Apprunning <> WAIT_TIMEOUT) or (avail < 0));
 Until stop;
 // прервемся когда процесс завершится
 End;
 FreeMem(Buffer); // освободили буфер
 CloseHandle(ProcessInfo.hProcess); // закрыли все хендлы
 CloseHandle(ProcessInfo.hThread);
 CloseHandle(OutReadPipe);
 CloseHandle(OutWritePipe);
 CloseHandle(InReadPipe);
 CloseHandle(InWritePipe);
 CloseHandle(ErrReadPipe);
 CloseHandle(ErrWritePipe);
 End;
 // конец.
 End;
Зы Зы
В качестве "браузерного движка" для веб-интерфейсов использован WebView4Delphi + Microsoft Edge WebView 2




 
  



 )
 )







 Но надеюсь   что следующая будет лучше так как причины появления "зомбиленда" наконец  обнаружены    )
  Но надеюсь   что следующая будет лучше так как причины появления "зомбиленда" наконец  обнаружены    )


