Page 4 of 17

Posted: Wed Mar 14, 2012 12:38 pm
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) и восстановлением переменных окружения - теперь всё работает.

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

Posted: Wed Mar 14, 2012 2:27 pm
by DV
FeyFre wrote:Нужно требовать ожидание фактического создания процесса перед возвратом
... для чего потребуется что-то новое в реализации Log::Output ;)

Posted: Thu Mar 15, 2012 9:42 am
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;
}

Posted: Thu Mar 15, 2012 9:44 am
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

Posted: Thu Mar 15, 2012 11:06 am
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 мс :)

Posted: Thu Mar 15, 2012 11:25 am
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);
}

Posted: Thu Mar 15, 2012 11:58 am
by FeyFre
Уточните. Вот эти юзекейсы - только для последнего запущенного процесса? Ведь я захочу запустить параллельно штук 5.

Posted: Thu Mar 15, 2012 12:24 pm
by DV
FeyFre wrote:Ведь я захочу запустить параллельно штук 5.
Это как? Ведь в окне Output показывается выполнение текущего (т.е. одного) процесса.

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

Code: Select all

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

Posted: Thu Mar 15, 2012 1:31 pm
by Instructor
DV wrote:Непорядок! ;)
См. SearchReplace.js "Найти все".

Posted: Thu Mar 15, 2012 1:57 pm
by VladSh
В Scripts.zip и PlugsPack.zip скрипт SearchReplace.js от 19.02, и в нём нет вхождений "Найти все" или "Call("Log::Output", 4,".

Строка

Code: Select all

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

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

Code: Select all

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

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

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

Posted: Thu Mar 15, 2012 2:10 pm
by VladSh
DV wrote:Но это же страшно сложно!
Я ж об этом чуть выше.
Но не то, чтобы сложно, а геморно.
DV wrote:- затем вычитать весь текст из этого окна,
- затем добавить к этому тексту свою строку,
Параметр "Заменять или добавлять".