Имя: Пароль:
1C
1С v8
Использование (вызов) WinAPI-функций в 1С8.2
0 AlexCom
 
13.10.17
23:41
Господа программисты!

Помогите решить следующую задачу:

Мне нужно запустить 1С8.2 базу и зафиксировать ID этого процесса
Стал эту задачу решать так:


WinAPI = ПолучитьCOMОбъектИзМакета("DynamicWrapperX", "DynamicWrapperX");                    // подключение DynamicWrapperX (это всё работает)
Если WinAPI <> Неопределено Тогда
    WinApi.Register("Kernel32.DLL", "CreateProcess", "i=sspplppspp", "f=l", "r=l");

    I0=WinAPI.Space(256);
    I1=WinAPI.Space(256);
    I2=WinAPI.Space(256);
    I3=WinAPI.Space(256);
    I4=WinAPI.Space(256);
    I5=WinAPI.Space(256);
    I6=WinAPI.Space(256);
    
    StartupInfo=WinAPI.Space(256*4+128);

    Info=WinAPI.Space(256);         // необходимо 4 DWord
           pStr=WinAPI.StrPtr(Info);    // Запоминаю указатель (в будущем потребуется)

    WinApi.Register("Kernel32.DLL", "CreateProcess", "i=ssppllpspp", "f=s", "r=l");      // регистрация прошла успешно
    I=WinAPI.CreateProcess("",СтрокаЗапуска,I1,I2,0,0,I5,Директория,StartupInfo,Info);  // Вот это НЕ РАБОТАЕТ
КонецЕсли;


Если блок заработает, то из Info получу ID потока.
Но блок не работает!

Где-то ошибаюсь с параметрами функции CreateProcess типа указатель, неправильно вызываю ...
Может у кого-нибудь был опыт использования функций WinApi или решение проще ...
1 H A D G E H O G s
 
13.10.17
23:54
WinAPI.CreateProcess("",СтрокаЗапуска,

СтрокаЗапуска - тут требуется указатель.
2 kittystark
 
14.10.17
10:06
Функция ПолучитьPID()
    Перем oLocator, oService, oShell, oApp, oChildProcess;
    Перем чPID;

    чPID = -1;
    Попытка
        oLocator = СоздатьОбъект("WbemScripting.SWbemLocator");
        oService = oLocator.ConnectServer(".", "root\CIMV2");
        
        // Запускаем дочерний rundll32.exe
        oShell = СоздатьОбъект("WScript.Shell");
        oApp = oShell.Exec("rundll32.exe kernel32,Sleep");
        // Получаем rundll32 по PID'у
        oChildProcess = oService.Get("Win32_Process.Handle=" + oApp.ProcessID);
        // Получаем PID родительского процесса - 1с
        чPID = oChildProcess.ParentProcessID;
        // Завершаем rundll32, чтобы не мусорить
        oChildProcess.Terminate();
    Исключение
        // нуу, может не быть прав на эти вещи, например.
    КонецПопытки;
    Возврат чPID;
КонецФункции // ПолучитьPID()

Процедура Сформировать()
    Сообщить("PID: " + ПолучитьPID());
КонецПроцедуры // Сформировать()
3 AlexCom
 
14.10.17
11:56
kittystark, Можно по подробнее
Уточню задачу:
у меня куча баз 1С.
Когда я запускаю какую-нибудь из них, я хочу зафиксировать где-нибудь ID этого процесса для того, чтобы грохнуть в последствии (по ID найду и уничтожу).

Написал вызов на Delphi:

procedure TForm5.Button1Click(Sender: TObject);
Var ProcessInfo: TProcessInformation;
     StartUpInfo: TStartUpInfo;
begin
FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0);
CreateProcess(Pchar('C:\Program Files (x86)\1cv8\8.3.7.1917\bin\1cv8.exe'),' ENTERPRISE /F...',
                nil, nil, false,NORMAL_PRIORITY_CLASS, nil,Nil, StartUpInfo, ProcessInfo);
end;
Это работает!

Мне надо просто разобраться с работой с указателями в 1С, переложить этот код в 1С (допустим), что не получается у меня
4 AlexCom
 
14.10.17
12:00
H A D G E H O G s, как конкретно написать указатель в 1С
Можно кусок кода?
5 kittystark
 
14.10.17
14:08
значит смотри, чуток академических знаний: указатель как тип данных есть в С / C++ / Pascal / Delphi и т.д., но в 1С его нет (работа с системной памятью напрямую недостпуна, т.к. есть своя модель объектов, и воспользоваться фишками ООП типа наследование / полиморфизм / инкапуляция от этой модели не получится)

код приведенный в (2) можно попытаться выполнить в ПриНачалеРаботыСистемы() модуля приложения (или модуля управляемого приложения) и полученный PID уже оттуда впихнуть куда-нибудь, например в файл и т.д.

подумай на тему того, что может тебе лучше воспользоваться COM-сервером 1С тип Application или connector для своих целей?

запустить для того чтобы потом грохнуть...
можно конечно по разному использовать 1С, что в процессе работы нужно то?
6 AlexCom
 
14.10.17
14:56
kittystark, спасибо за ответ, но это я знаю.
Вопрос только в том, что КАК воткнуть Delphi-код в модуль 1С. Мне не удается перевести в язык 1С указатели (как Вы писали, в 1С их нет - в том то и дело). Или может быть весь Delphi-код как макрос можно вставить в 1С, но я не знаю, как это сделать. Вопрос - какие параметры (в каком виде) подсунуть в функцию CreateProcess() в модуле 1С, как инициализировать StartUpInfo, ProcessInfo - это же указатели

А задача такая:
Пользователь открывает свои базы, работает ...
В некоторый момент администратор отключает некоторые базы или меняет права на доступ к базам. Удаленный пользователь попучает уведомление на экран, что определенная база отключается, допустим, на регламентные работы, и через 3 минуты, допустим, база закрывается сама. Для закрытия мне нужно знать ID процесса. Примерно так. Мне легче написать службу на Delphi, и раскатить её на все компы, но установка компании - писать всё на 1С, и это наверное правильно. Приходится придумывать. В принципе всё почти готово, остался этот кусок пройти.
Получается, кроме как в ID процесса мне привязаться не к чему.
Путь2: При запуске 1С-базы командная строка вызова тоже привязывается к win-процессу. Зная командную строку процесса и строку вызова 1С (они почти равны), я могу найти рабочий win процесс по этой строке. И опять упираются в API-функции (Process32First ...). Т.е. легче не стало. 1 вариант легче :)
7 Филиал-msk
 
14.10.17
15:02
(6) И тут внезапно 1С падает не успев сообщить тебе о закрытии и через некоторое время ее пид получает фотошоп (:

1С тут совсем не нужна. Совсем. Пиды с легкостью вычитываются по необходимости из списка процессов при желании их убийства. Экземпляр базы определяется по параметрам командной строки.
8 Филиал-msk
 
14.10.17
15:07
И вообще, не ипи народу мозг переводом кода с престарелого дельфи на актуальный 1С.
Напиши на своем дельфи внешнюю компоненту, грузи ее в 1С и извращайся как душа пожелает.
9 kittystark
 
14.10.17
15:19
а...   свою выгонялку пользователей пишешь...
во первых есть стандартный функционал блокировки сеансов
во вторых таких поделок много, поищи

если хочется посношаться, то как вариант - заводишь одну константу - кол-во секунд до выхода, при логине каждого пользователя в приначалеработысистемы подключаешь обработчик ожидания скажем раз в 30 сек., в котором анализируешьь ее и по ее значению
- или вывоводишь сообщение (>0)
- или выгоняшь и блокруешь вход (=-1)
- или оставляешь работать (=0)

а вторую константу - пользователь блокировщик
чтоб под ним можно было всегда войти не взирая на значение первой константы, ну и плюс чтоб его не выкидывало
10 AlexCom
 
15.10.17
09:31
Так как начался флуд, тема закрыта
11 AlexCom
 
15.10.17
11:13
kittystark, Это тоже известно
У нас баз - несколько сотен, большинство типовых, не снятых с поддержки, конфигурация закрыта или почти закрыта, в общем менять нельзя и т. д.
Задача не должна затрагивать конфигурации, т. к. базы появляются и удаляются ...
Задача наверное должна решаться в том виде, как предложено, как отдельный обший механизм

2. Блокировка сеансов? А если файловый вариант?
12 Филиал-msk
 
15.10.17
12:09
... и тысячи паровых машин. При этом программированием занимается не 1Сник, а дельфист. Сказочная контора.
13 Филиал-msk
 
15.10.17
12:12
Менять нельзя, но при старте конфигурация должна научится что-то делать с pid. Причем все тысячи баз. Волшебство!
14 TormozIT
 
гуру
15.10.17
13:31
15 TormozIT
 
гуру
15.10.17
13:33
(14) Не подойдет. Надо будет дописать свою функцию, взяв за основую метод Run.
16 AlexCom
 
15.10.17
18:39
TormozIT, Большое спасибо !!!
Буду смотреть
Самое главное - исходники есть!
17 lamina
 
15.10.17
22:06
(16) а разве можно подключить внешнюю компоненту без снятия все ваших баз с поддержки или подключений расширений?
18 Филиал-msk
 
15.10.17
22:20
(17) Тссссс =)
Чувак в 09.31 тему вообще закрыл. Он Пытается с Заглавной Буквы.
19 MM
 
16.10.17
08:37
(0) А разве в структуре STARTUPINFO не нужно заполнить поле cb - The size of the structure, in bytes?
20 TormozIT
 
гуру
29.10.17
00:05
(17) Конечно можно. ИР же это делает как раз через native ВК, ссылку на которую я дал в (14).