Native API компонента для использования установленного в системе интерпретатора Python

Компонента позволяет подключать к платформе 1С python-модули, оформленные в стиле внешней компоненты. Кроме этого, она позволяет запускать небольшие фрагменты python-кода прямо из модулей 1С. На данный момент поддерживаются платформы 8.2 — 8.3 x86 Windows.

В системе должен присутствовать совместимый интерпретатор Python. В данном случае это Python 3.3, инсталлятор которого можно скачать на официальном сайте разработчиков: http://www.python.org/ftp/python/3.3.5/python-3.3.5.msi

Интерфейс взаимодействия позволяет оформлять модули расширения максимально просто и наглядно. Для примера, вот функциональный аналог образца Native ВК от ИТС:

# -*- coding: utf-8 -*-

from interfacing import *
from time import sleep, monotonic
from threading import Thread


class Timer(Thread):
def __init__(self, ent):
self.done = False
self.ent = ent
Thread.__init__(self)

def run(self):
while not self.done:
self.ent.ExternalEvent('ComponentNative', 'Timer', str(monotonic()))
sleep(5)
self.done = False


@Component
class CAddInNative:

def __init__(self):
self.m_boolEnabled = False
self.AsyncEvent = Timer(self.Enterprise)

@Readable('IsEnabled', 'Включен')
@property
def ePropIsEnabled(self):
return self.m_boolEnabled

@Writable
@ePropIsEnabled.setter
def ePropIsEnabled(self, value):
self.m_boolEnabled = value

@Readable('IsTimerPresent', 'ЕстьТаймер')
@property
def ePropIsTimerPresent(self):
return True

@Procedure('Enable', 'Включить')
def eMethEnable(self):
self.m_boolEnabled = True

@Procedure('Disable', 'Выключить')
def eMethDisable(self):
self.m_boolEnabled = False

@Procedure('ShowInStatusLine', 'ПоказатьВСтрокеСтатуса')
def eMethShowInStatusLine(self, var):
self.Enterprise.SetStatusLine(var)
sleep(5)

@Procedure('StartTimer', 'СтартТаймер')
def eMethStartTimer(self):
self.AsyncEvent.start()

@Procedure('StopTimer', 'СтопТаймер')
def eMethStopTimer(self):
self.AsyncEvent.done = True

@Function('LoadPicture', 'ЗагрузитьКартинку')
def eMethLoadPicture(self, name):
with open(name, 'rb') as f:
return f.read()

@Procedure('ShowMessageBox', 'ПоказатьСообщение')
def eMethShowMsgBox(self):
info = self.Enterprise.GetInterface(EC_IPlatformInfo)
imsgbox = self.Enterprise.GetInterface(EC_IMsgBox)
if info is None or imsgbox is None:
return
if imsgbox.Confirm(info.GetPlatformInfo()[0]):
imsgbox.Alert('OK')
else:
imsgbox.Alert('Cancel')

def ExplicitDone(self):
self.AsyncEvent.done = True
self.AsyncEvent.join()

 В архиве есть достаточно подробная документация и комплект для тестирования.

Тестовая конфигурация

Чтобы запустить тест, нужно указать путь к компоненте, по которому должен лежать и OnePyTest.py.

30 Comments

  1. quick

    потрясно.. а я только начал ее делать.

    Reply
  2. Принт

    Интересно было бы посмотреть на другое решение.

    Ядро компоненты питоновское, так что его у меня достаточно быстро получилось портировать из предыдущей дотнетной версии.

    Reply
  3. stanru1

    ставлю плюс за идею, но практического смысла не вижу :))

    Reply
  4. Принт

    Спасибо. Мне кажется, практический смысл тот же, что и у ВК вообще.

    Reply
  5. Принт

    (как же здесь изменяются аватары?)

    Reply
  6. zan_od

    (3) stanru1, имхо практический смысл в использовании готовых питоновских библиотек. Взять хотя-бы эту — готовая библиотека для работы с API гугловских служб. Иначе приходится выкручиваться вот так — через http-запросы методом научного тыка.

    P.S. Эх, если бы можно было Java в 1С-ке использовать.

    Reply
  7. andrewks

    (6) zan_od, имеете в виду чистую Java, или JS?

    Reply
  8. zan_od

    (7) andrewks, именно Java (наподобие Elisy .Net Bridge)

    Reply
  9. zan_od

    2 homebody, не могу запустить компоненту

    Установил python (по ссылке, указанной в статье), прописал в PATH, проверил в командной строке — запускается версия 3.3. В 1С-ке функция ПодключитьВнешнююКомпоненту(ПутьККомпоненте, «Компонента», ТипВнешнейКомпоненты.Native) возвращает Ложь. В чем может быть дело?

    Reply
  10. Принт

    Если путь к компоненте задан точно, тогда:

    Питон устанавливался «для всех пользователей»? <системный диск>:windowssystem32python33.dll присутствует? (для 64-х разрядной системы путь соответственно другой) А так же в реестре, в HKLMSoftwarePythonPythonCore3.3InstallPath (HKLMSoftwareWow6432NodePythonPythonCore3.3InstallPath) путь указан верно?

    Какая версия платформы? Режим приложения?

    Reply
  11. Принт

    Меж тем, проверил на 3.3.2: тоже работает.

    Reply
  12. Stamper

    (7) andrewks, JS кое-как можно использовать в хелпе и в HTML-документе на форме.

    Reply
  13. altcavs

    На клиенте работает на ура!!, а на сервере только один первый раз.

    Как запустить на сервере???

    Reply
  14. Принт

    На сервере совсем не тестировалось — нужно разбираться.

    Reply
  15. altcavs

    (14) Принт,

    Native API только и нужно для сервера!!!

    А что внутри, embeded Python API ?

    Reply
  16. Принт

    Оно, конечно, да и даже компонента ориентировалась для работы на сервере, но разработчики 1С взяли курс в другую сторону от своего же NativeAPI. Сейчас мне кажется более правильным перенос ВК в отдельный процесс с сопутствующим IPC. По крайней мере это относится к питону.

    Внутри там что-то вроде http://habrahabr.ru/post/273401/

    Reply
  17. Serginio

    Вот здесь есть ВК для использования Питона https://github.com/mrprint/OnePy

    Кстати можно выполнять скрипты на IronPython

    http://metanit.com/sharp/tutorial/9.3.php

    Reply
  18. cool.vlad4

    (17) Serginio, там не Native ВК (и там вроде IronPython а не питон)

    а насчет IronPython, IronPython!=Python. была какая-то попытка сделать взаимодействие между ними, но по моему так и не взлетело (IronЧего-тоТам называлась , на гуглкоде). так что на аналоги публикации данной это не тянет

    Reply
  19. Serginio

    (18) Я просто дал ссылку на аналогичные разработки. Только и всего

    Мне IronPython интересен как возможность динамического исполнения кода.

    Сейчас есть уже вышла Scripting API

    http://blogs.msdn.com/b/cdndevs/archive/2015/12/01/adding-csharp-scripting-part-1.aspx

    https://joshvarty.wordpress.com/2015/10/15/learn-roslyn-now-part-14-intro-to-the-scripting-api/

    https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples

    Например http://infostart.ru/public/417830/

    Reply
  20. cool.vlad4

    (19) Serginio, сейчас?) scriptcs я еще в позапрошлом году видел. и даже как-то использовал касательно 1с (формирование word документов). просто наконец Roslyn вышел в релиз. так-то его можно было и до этого использовать в простейших сценариях.

    Reply
  21. Serginio

    (20) Он был в бэте. Сейчас релиз

    Reply
  22. cool.vlad4

    (21) Serginio, я это и написал

    Reply
  23. Serginio

    (18) Кстати а какой профит от NativeApi если

    На данный момент поддерживаются платформы 8.2 — 8.3 x86 Windows.
    Reply
  24. Принт

    (17) Там мой репозиторий и моя разработка, но поскольку считаю её безперспективной, то и оставляю за кадром. Ведь почти всё хорошее, что есть для Питона гвоздями прибито к CPython.

    (23) У меня есть рабочий черновик для Linux x86.

    Reply
  25. cool.vlad4

    (23) Serginio, ну это вопрос к автору, почему только x86. профит от Native как минимум в ненужности что либо регистрировать . ты, конечно, ответишь, что можно же зарегистрировать только одну твою компоненту-фабрику. а Native вообще ненужно регистрировать .

    Reply
  26. Serginio

    Нет не скажу. Но скажу другое. В 7.7 есть vkloader. Но я не пойму почему в 1С не сделают загрузку из фабрики по clsid зная путь к файлу. Вот код на C# для получение IDispatch

    public static object ЗагрузитьОбъект(string ИмяФайла, System.Guid clsid)
    {
    
    var module = Win32NativeMethods.LoadLibraryEx(ИмяФайла, IntPtr.Zero, 8);
    var proc = Win32NativeMethods.GetProcAddress(module, «DllGetClassObject»);
    var gco = Marshal.GetDelegateForFunctionPointer(proc,
    typeof(Win32NativeMethods.DllGetClassObjectDelegate))
    as Win32NativeMethods.DllGetClassObjectDelegate;
    
    
    object unknown;
    gco(clsid, typeof(IClassFactory).GUID, out unknown);
    var factory = unknown as IClassFactory;
    
    //var iid = typeof(IFilter).GUID;
    //var filter = factory.CreateInstance(null, ref iid) as IFilter;
    
    var iid = typeof(IDispatch).GUID;
    return factory.CreateInstance(null, iid);
    
    
    }
    

    Показать

    Reply
  27. komradz

    Вопрос, будет ли она работать с python 3.4 ?!

    Reply
  28. Infactum

    Исходники бы 🙂

    Reply
  29. Принт

    (27) komradz, Нет, не будет. Но можно рядом с 3.4 установить 3.3, без прописывания путей и интеграции в проводник.

    (28) Infactum, Там макаронного кода много, а комментариев мало. ) Я подумаю. Если будет совсем лень двигать проект вперёд, тогда открою.

    Reply
  30. Принт

    (17) Опубликовал полные исходники компоненты под IronPython. Проект не развивался, я только замазал несколько самых очевидных ляпов.

    upd

    Если кому нужны сборки для текущих питонов Windows x86 — x64, напишите в личку!

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *