Bug 552

Summary: Команда в 1С КомандаСистемы () выполняется паралельно, а не последовательно
Product: WINE@Etersoft Reporter: Александр Пликус <pav>
Component: Консоль ; Вызов программAssignee: Anton Rudnev <mibori>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P5 CC: amorozov, baraka, kondratyuk, lav
Version: 1.0.6   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Whiteboard:
Заявки RT: Связано с:
Дата напоминания:
Bug Depends on: 1035    
Bug Blocks: 760, 3305    

Description Александр Пликус 2007-04-14 20:13:47 MSD
команда в 1С

 КомандаСистемы ("какой то скрипт");

скрип допустим вызывает xterm

Выполнение скрипта в 1С не останавливается на вызове xterm, а моментально продолжается.

Интересно а как это в Windows работает?
Comment 1 Синицын Иван 2007-04-16 15:51:32 MSD
В винде работает как положено, т.е. при вызове (например - блокнота) выполнение останавливается и продолжается только после закрытия блокнота.
Comment 2 Vitaly Lipatov 2007-12-19 14:22:46 MSK
Интересно, там наверняка используется CreateProcess.
По умолчанию CreateProcess ничего не ждёт. Надо бы проверить.
Comment 3 Константин Кондратюк 2007-12-28 12:41:28 MSK
Проверю, что там.
CreateProcess() ничего и не может ждать. Обычно это функцией WaitForSingleObject() реализуется. Видимо, какой-то эвент ошибочно генерируется, и 1С считает процесс завершённым
Comment 4 Константин Кондратюк 2007-12-28 19:06:21 MSK
В windows КомандаСистемы("noted") аналогична
нашей
wineconsole cmd.exe /c notepad.exe

Даже окно 1С перестаёт перерисовываться
так же.
Comment 5 Anton Rudnev 2009-01-30 21:39:15 MSK
http://lists.etersoft.ru/pipermail/wine-patches/2009-January/000270.html

исправляет проблему.

Итак, при запуске в 1С функции КоманадаСистемы("что-то"), 1С порождает процесс 

     cmd /c что-то

cmd /c string под виндой дожидается завершения процесса, прежде чем передать управленив консоль, а у нас не дожидается.
соответственно, сама 1С в баге не учавствует, баг на стороне cmd.

ожидание завершения запущенного процесса работает следующим образом:
создаётся какой-то процесс через CreateProcess(..., LPPROCESS_INFORMATION lpProcessInformation ) http://msdn.microsoft.com/en-us/library/ms682425.aspx
последним параметром там, является структра в которую складывается информация о процессе после его запуска http://msdn.microsoft.com/en-us/library/ms684873(VS.85).aspx

Оттуда нужна взять поле дескриптора процесса HANDLE hProcess, для того, что бы использовать в функции WaitForSingleObject (pe.hProcess, INFINITE);

эта функция завершит своё выполнение только тогда, когда завершит своё выполнение процесс.

Перед тем как запускать функцию WaitForSingleObject, нужно удостоверится, что
файл, который мы запускаем -- это консольное приложение.

в нашем cmd это делается путём анализа результата функции SHGetFileInfo (http://msdn.microsoft.com/en-us/library/bb762179(VS.85).aspx)

если это консольное приложение, то нижнее слово == {'P','E'}, верхнее слово == 0x0 (см. мсдн)

ошибка заключалась в том, что проверялось только верхнее слово.

решение состоит в том, что проверяется теперь, только нижнее слово.

также в дальнейшем ошибка может обнаружится в функции SHGetFileInfo, поскольку в этом случае она всё-таки должна была сделать верхнее слово нулевым
(значение, которое оно возвращает полностью -- 0x4004550 == 0x[0400]['E','P'], предполагаю, что значение [0x00,0x04] устанавливается в ней ошибочно).

про ComSpec напишу чуть позже...
Comment 6 Александр Морозов 2009-02-02 11:16:33 MSK
> Перед тем как запускать функцию WaitForSingleObject,
> нужно удостоверится, что
> файл, который мы запускаем -- это консольное
> приложение.

Если верить MSDN, LOWORD = PE не только для консольных приложений.

> если это консольное приложение, то нижнее
> слово == {'P','E'}, верхнее слово == 0x0 (см. мсдн)

Да, а если не консольное, то нижнее слово такое же, а верхнее - версия Windows.

> ошибка заключалась в том, что проверялось
> только верхнее слово.
>
> решение состоит в том, что проверяется
> теперь, только нижнее слово.

А почему не оба слова вместе?
Comment 7 Anton Rudnev 2009-02-02 14:34:52 MSK
> Если верить MSDN, LOWORD = PE не только для
> консольных приложений.
Ок, что мы должны делать в других случаях?

> Да, а если не консольное, то нижнее слово
> такое же, а верхнее - версия Windows.
0x400 -- это номер версии Windows?

> А почему не оба слова вместе?
то есть так: LOWORD == PE && HIWORD == 0x400 ?

Comment 8 Александр Морозов 2009-02-02 14:42:18 MSK
Для начала надо определиться, какие приложения надо ждать, только консольные или все. Если только консольные, то проверяем старшее слово на равенство 0. Если для консольного приложения старшее слово оказывается не равным 0, то это баг в SHGetFileInfo.
Comment 9 Anton Rudnev 2009-02-02 16:42:01 MSK
про ComSpec (по крайней мере в 1c80)

1c всё-таки использует ComSpec с одной оговоркой.
Исполняемый файл указанный в ComSpec должен быть Windows PE-файлом, а не скриптом.

Эксперимент проводился очень просто.
в разделе реестра HKLM\System\CurrentControlSet\Control\SessionManager\Environment
значение параметра "ComSpec" поменял на "c:\\windows\\system32\\notepad.exe"

при запуске 1С-овской фукции КомандаСистемы("notepad.exe") запускается блокнот с сообщением

"файл notepad.exe не существует. Хотите создать новый файл"

при запуске блокнота это сообщение может возникнуть только в одном случае:

если была выполнена команда notepad.exe notepad.exe

это значит что ComSpec используется.
Comment 10 Денис Баранов 2009-02-13 18:49:18 MSK
eter41\eter17
Принято