Log plugin

Discuss and announce AkelPad plugins
  • Author
  • Message
DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

FeyFre wrote:на сколько я понимаю окружение наследуется от процесса.
Вот и я так понимаю.
Но почему на деле получается, что WshShell.Run и AkelPad.Exec подхватывают предварительно установленные переменные, передавая их дочернему процессу, а Log::Output - нет?

Добавлено чуть позже:
Хотя нет, у меня есть мысли по поводу того, как такое могло произойти. Сразу после запуска команды в RunMe.js я восстанавливаю первоначальное значение переменных окружения. Т.е. если AkelPad.Call("Log::Output", 1, cmd, dir) вернул управление до того, как дочерний процесс фактически стартовал, скрипт может успеть восстановить переменные окружения ещё до того, как дочерний процесс их подхватит. Опять гонки фронтов, короче...

Добавлено ещё чуть позже:
Да, так и есть, врот ми имейл... Поставил WScript.Sleep(2000) между runCommand(cmd, fileDir) и восстановлением переменных окружения - теперь всё работает.

Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

DV, фух, я уже начал думать невесть что(что CreateProcess халтурит, и среда "унаследуется" значительно позже чем CreateProcess возвращает управление. Уже Руссиновича хотел искать.). Но заглянул в исходник и обнаружил что AkelPad.Call("Log::Output", 1 фактически порождает поток, который и запустит дитё, ну и остается работать дальше. Тогда да, создание дитя может быть начато после возврат исходной среды. Правда ждать эти две секунды - тоже не надежный выход. Нужно требовать ожидание фактического создания процесса перед возвратом.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

FeyFre wrote:Нужно требовать ожидание фактического создания процесса перед возвратом
... для чего потребуется что-то новое в реализации Log::Output ;)

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

DV
В версии 1.8:

Code: Select all

WScript.Echo(GetOutputExecThread(true));

function GetOutputExecThread(bWait)
{
  var lpExecThread;
  var hExecThread=0;
  var oSys=AkelPad.SystemFunction();

  if (lpExecThread=AkelPad.MemAlloc(_X64?8:4 /*sizeof(HANDLE)*/))
  {
    AkelPad.Call("Log::Output", 3, lpExecThread);
    hExecThread=AkelPad.MemRead(lpExecThread, 2 /*DT_QWORD*/);
    if (hExecThread && bWait)
      oSys.Call("kernel32::WaitForSingleObject", hExecThread, 0xFFFFFFFF /*INFINITE*/);
    AkelPad.MemFree(lpExecThread);
  }
  return hExecThread;
}

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Добавлено: внешний вызов с кодом 3 для получения информации о текущем запущенном приложении (Log::Output).

Added: external call with code 3 to get information about the current executed application (Log::Output).


Log plugin v1.8

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

Instructor wrote:GetOutputExecThread.js
В моём случае несколько сложней будет. Что-то вроде такого:

Code: Select all

// поток ещё не стартовал
hThread = 0;
hProcess = 0;
do {
  Sleep(100);
  Call("Log::Output", 3, hThread, hProcess);
} while (!hThread && !hProcess);
// поток и процесс уже стартовали
// теперь можно восстанавливать переменные окружения
Тут главное, чтобы процесс не успел начаться и завершиться за 100 мс :)

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

DV

Code: Select all

AkelPad.Call("Log::Output", 1, "program.exe");
//Тут hThread уже существует, hProcess может не существовать.

//Дождемся старта процесса или выхода из выполнения.
for (;;)
{
  AkelPad.Call("Log::Output", 3, hThread, hProcess);
  if (!hThread || hProcess) break;
  WScript.Sleep(100);
}

Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

Уточните. Вот эти юзекейсы - только для последнего запущенного процесса? Ведь я захочу запустить параллельно штук 5.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

FeyFre wrote:Ведь я захочу запустить параллельно штук 5.
Это как? Ведь в окне Output показывается выполнение текущего (т.е. одного) процесса.

Посмотрел ещё список возможностей плагина и с удивлением обнаружил, что нет такой команды, как

Code: Select all

AkelPad.Call("Log::Output", 4, "Строка, которую я хочу вывести в панель Output из своего скрипта")
Непорядок! ;)

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

DV wrote:Непорядок! ;)
См. SearchReplace.js "Найти все".

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

В Scripts.zip и PlugsPack.zip скрипт SearchReplace.js от 19.02, и в нём нет вхождений "Найти все" или "Call("Log::Output", 4,".

Строка

Code: Select all

AkelPad.Call("Log::Output", 4, "Строка, которую я хочу вывести в панель Output из своего скрипта");
не работает.

Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

Это как? Ведь в окне Output показывается выполнение текущего (т.е. одного) процесса.
1. Ну а кто сказал что я хочу в это окно. Может я хочу в новую вкладку. И каждый процесс в свою.
2. Я себе захочу настроить регулярку для избирательно вывода. Таким образом даже тысяча запущенных детей особо за одно окно не поругаются.
Посмотрел ещё список возможностей плагина и с удивлением обнаружил, что нет такой команды, как
Зачем? Ведь есть такая

Code: Select all

AkelPad.Call("Log::Output", 2, WINDOW);
AkelPad.SetEditWnd(WINDOW)
AkelPad.SetSel(-1,-1)
AkelPad.ReplaceSel("blah")

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

FeyFre wrote:Зачем? Ведь есть такая...
Чтобы меньше напрямую с API работать.
Скоро многие скрипты будут использовать вывод в консоль, и это что, во все скрипты копипастить этот (ещё и функцию получения hWndOutput) код? В большинстве случаев гораздо проще и лучше вывести текст в консоль лога одной строкой - методом с определёнными параметрами (оставить параметр boolean для bSelect).
Last edited by VladSh on Thu Mar 15, 2012 2:12 pm, edited 2 times in total.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

Instructor wrote:См. SearchReplace.js "Найти все".
Но это же страшно сложно! :shock: Нет, правда:
- сначала нужно узнать хэндл окна Output,
- затем вычитать весь текст из этого окна,
- затем добавить к этому тексту свою строку,
- и, наконец, установить новый текст.
И это всё можно было бы сделать с помощью одной строчки кода AkelPad.Call("Log::Output", 4, "Моя новая строка").

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

DV wrote:Но это же страшно сложно!
Я ж об этом чуть выше.
Но не то, чтобы сложно, а геморно.
DV wrote:- затем вычитать весь текст из этого окна,
- затем добавить к этому тексту свою строку,
Параметр "Заменять или добавлять".
Post Reply