PerryWerneck/python3-tn3270

Funciona com o pw3270 5.1 com autenticação de identidade digital?

vinifrancosilva opened this issue · 12 comments

Olá!

Foi uma grata surpresa encontrar esse projeto e outra ainda maior de ver que é de Brasileiros!

Existe algum truque pra fazê-lo funcionar? Ao rodar o script de exemplo, aparecem os seguintes erros:

import tn3270
print(tn3270.revision())
Traceback (most recent call last):
File "<pyshell#9>", line 1, in
print(tn3270.revision())
AttributeError: module 'tn3270' has no attribute 'revision'
session = tn3270.Session(":a")
Traceback (most recent call last):
File "<pyshell#10>", line 1, in
session = tn3270.Session(":a")
AttributeError: module 'tn3270' has no attribute 'Session'

Obrigado.

Pra ser sincero não tenho certeza. Até existe um módulo python para a versão 5.1; pelo que eu me lembro era pra python2 e só funcionava em linux; já as últimas versões, para python3, foram criadas usando a API da versão 5.3 do pw3270.

Adicionalmente não existe pw3270 com autenticação de identidade digital, então, acredito que você esteja usando uma versão personalizada que pode ou não ter suporte para os módulos que dão suporte a API necessária para o módulo funcionar.

Uma dica: se o suporte para API externa estiver ativo o título da janela muda e passa a conter o identificador da sessão que você usa ao criar o objeto (geralmente pw3270:a na primeira, pw3270:b na segunda e por ai vai).

Como fica aqui na minha máquina:

image

Pra ser sincero não tenho certeza. Até existe um módulo python para a versão 5.1; pelo que eu me lembro era pra python2 e só funcionava em linux; já as últimas versões, para python3, foram criadas usando a API da versão 5.3 do pw3270.

Adicionalmente não existe pw3270 com autenticação de identidade digital, então, acredito que você esteja usando uma versão personalizada que pode ou não ter suporte para os módulos que dão suporte a API necessária para o módulo funcionar.

Uma dica: se o suporte para API externa estiver ativo o título da janela muda e passa a conter o identificador da sessão que você usa ao criar o objeto (geralmente pw3270:a na primeira, pw3270:b na segunda e por ai vai).

Como fica aqui na minha máquina:

image

Humm... Essa é uma versão personalizada então.
Eu sei que está habilitado pra funcionar via API porque funciona com vba no Excel.

Eu fiz o caminho inverso, cheguei no github após ter instalado o módulo via pypi.org
Agora que vi que para instalar o módulo no Windows existem outros passos a serem seguidos.
Vou testar aqui e dou retorno.

Já retornando... Infelizmente não vou conseguir acessar... esses procedimentos que usam senha de adm ou necessita instalação no sistema de pacotes e programas, não é possível na minha máquina corporativa. Aqui eu rodo o WinPython e uma versao 3.6.0 instalada pelo suporte... Triste kkkkk achei que essa seria minha saída.

Obrigado pela resposta.

Se funciona com VBA ele até deve ter o módulo instalado, porém, na 5.1 em windows esse módulo era exclusivo para VBA. Já vi algumas pessoas fazendo "gambiarras" para usar o módulo VBA em python com ctypes mas não sei se fica muito estável (provavelmente não); também tem bem menos recursos que a API nova.

Olá @PerryWerneck!

A necessidade de fazer essa conexão surgiu novamente.
Estou tentando usar o ctypes pra fazer a "gambiarra" como falou acima.
Esses foram os passos que dei até agora:

import ctypes
dll = ctypes.windll.LoadLibrary(r'C:\Program Files\pw3270\libhllapi64.dll')
# dll = ctypes.windll.LoadLibrary(r'C:\Program Files\pw3270\libhllapi32.dll')

if not dll.hllapi_init('pw3270:A'):
    print('Deu pau!!')
    exit()
dll.hllapi_set_unlock_delay(1)

qtde = 9
txt = ctypes.c_wchar_p(qtde)
dll.hllapi_get_screen_at(ctypes.c_int(17), ctypes.c_int(16), ctypes.byref(txt))
print(txt)
print(dll.hllapi_get_screen_at(17, 16, 9))

print('fim')

e o retorno é:

c_wchar_p(9)
1
fim

Você poderia me orientar qual o caminho pra conseguir usar essa libhllapi? É minha única opção já que atualizar o terminal não é uma possibilidade.

  • pw3270 versão 5.1
  • Windows 10
  • Python 3.7

Obrigado

Me parece que funcionou. Resta ver como converter o c_wchar_p(9)em uma string python. Deve ter método pronto pra isso.

Nota: Acho que no python 3 tem forma mais fácil de fazer isso. Descobri uma tal de FFI ao analisar o código do py_vmdetect; me pareceu bem mais "esperta" que a ctype; nela você declara os métodos tal qual aparecem no cabeçalho da biblioteca e cria um objeto python para manipulá-los.

Muitíssimo obrigado pelo retorno.
Fiz o teste com o pw3270 fechado e retornou o mesmo resultado, acredito que não tenha conectado :(
Eu vou tentar esse caminho que você sugeriu e vou postando aqui os resultados.
Obrigado!

Fechado deveria ter dado erro no init, pelo menos em teoria. Essa versão que você está usando é tão antiga que não lembro se o tratamento de erros funcionava direito.

@PerryWerneck Bom dia!
Desculpe as perguntas noobies que preciso fazer, não tenho experiência com essas coisas mais low level.
Onde eu consigo as definições das funções internas da lib pra fazer a declaração no cdev da ffi? Como no exemplo que você mandou:

ffi.cdef("int vm_by_cpuid();\
                  int isVMware();\
                  int isHyperV();\
                  int detectVZ();\
                  int isUserModeLinuxOrKvm();\
                  int detect_XEN_domU();\
                  int detectFreeBSDJAIL();\
                  ")

Obrigado mais uma vez!

Da versão atualizada tem em https://github.com/PerryWerneck/libhllapi/blob/master/src/include/lib3270/hllapi.h da versão 5.1 vai dar um pouco mais de trabalho pra achar. Não lembro se houveram grandes mudanças nas assinaturas nos últimos anos.

Todas as funções retornam int?
Pra função init, por exemplo, ficaria assim?
ffi.cdef("int HLLAPI_API_CALL hllapi_init(LPSTR mode);")
ou assim:
ffi.cdef("int hllapi_init(LPSTR mode);")
ou nenhuma das alternativas anteriores!? (rsrs)

Quase! Pelo que me lembro do windows LPSTR converte para char * em sistemas normais.

No caso ficaria algo do tipo (da uma olhada na documentação porque tem detalhes extras em windows):

ffi.cdef("int hllapi_init(char * mode);")

@PerryWerneck
Cara, muitíssimo obrigado pelo seu tempo e pela sua ajuda!
Deu certo! Cffi foi a solução! Consegui conectar, ler a tela, fazer input, etc.
Agora bora fazer um wrapper pra facilitar a vida e desenvolver o scraper que preciso.
Obrigado mais uma vez!