Ir para conteúdo
  • Cadastre-se

dev botao

Não consigo enviar email através da ACbrLibMail.dll (funções sempre retorna -1)


Ver Solução Respondido por sucsis,
  • Este tópico foi criado há 1513 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Bom dia,

Recentemente foi solicitado ao setor de desenvolvimento que implementássemos o envio de e-mail através da biblioteca lib ACBrMail.dll, fiz conforme está na documentação, porém os únicos comandos que funcionam são MAIL_Inicializar() e MAIL_Finalizar(), os demais sempre retornam -1, indicando erro de inicialização.

Na aplicação está assim

MAIL_Inicializar("C:\config.ini", "") - Retorna 0, indicando que foi inicializada corretamente.

MAIL_Clear() - Retorna -1, indicando erro de inicialização

... quaisquer outros comandos retornam -1, com

MAIL_Finalziar() - Retorna 0, indicando que foi finalizada corretamente

 

Gostaria de saber se algo a mais deve ser feito, pois tanto a ACbrLibMail32.dll quanto as dependências estão na pasta do executável
 

Postado

Bom dia, estou utilizando a linguagem xHarbour (temos costume aqui de utilizar várias outras DLLs). Estou num SO de 64 bits, porém o sistema é de 32 bits, peguei a DLL dessa arquitetura, convneção de chamada StdCall.

Exemplo de como foi declarado a função da DLL:

DLL32 Function MAIL_Inicializar(vArqCfg AS STRING, vChvCri AS STRING) AS _INT PASCAL FROM "MAIL_Inicializar" LIB "ACBrMail32.DLL"

Vou fazer o teste no DEMO...

Postado

O PRG está da seguinte forma

/*
* Funções do ACBrMail
*/
DLL32 Function MAIL_Inicializar (vArqCfg AS STRING,;
                                 vChvCri AS STRING) AS _INT PASCAL FROM "MAIL_Inicializar" LIB "ACBrMail32.DLL"

DLL32 Function MAIL_Finalizar       (                 ) AS _INT PASCAL FROM "MAIL_Finalizar" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_Clear           (                 ) AS LONG PASCAL FROM "MAIL_Clear" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_SetSubject      (vSubJct AS STRING) AS _INT PASCAL FROM "MAIL_SetSubject" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_AddAddress      (vEmaDes AS STRING,;
                                     vNomDes AS STRING) AS _INT PASCAL FROM "MAIL_AddAddress" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_AddReplyTo      (vEmaRem AS STRING,;
                                     vNomRem AS STRING) AS _INT PASCAL FROM "MAIL_AddReplyTo" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_AddCC           (vEmaCop AS STRING,;
                                     vNomCop AS STRING) AS _INT PASCAL FROM "MAIL_AddCC" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_AddBCC          (vEmaCop AS STRING) AS _INT PASCAL FROM "MAIL_AddBCC" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_AddBody         (vTxtBod AS STRING) AS _INT PASCAL FROM "MAIL_AddBody" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_AddAltBody      (vAltBod AS STRING) AS _INT PASCAL FROM "MAIL_AddAltBody" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_ClearAttachment (                 ) AS _INT PASCAL FROM "MAIL_ClearAttachment" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_AddAttachment   (vCamArq AS STRING,;
                                     vDscArq AS STRING,;
                                     nDisAnx AS _INT  ) AS _INT PASCAL FROM "MAIL_AddAttachment" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_Send            (nUseThd AS _INT  ) AS _INT PASCAL FROM "MAIL_Send" LIB "ACBrMail32.DLL"
DLL32 Function MAIL_SaveToFile      (vArqSav AS STRING) AS _INT PASCAL FROM "MAIL_SaveToFile" LIB "ACBrMail32.DLL"

/*
* Função para testar o envio de email
*/
Function TestarAcbr()
Local vConteudoLog:="",vArquivoLog:="C:\logAcbr.txt",;
      nLogIni:=nLogClear:=nLogAddDest:=nLogAddr:=nLogRem:=nLogSub:=nLogBod:=nLogBod2:=nLogSend:=nlogFim:=0
nLogIni   := MAIL_Inicializar("C:\config.ini","")
nLogClear := MAIL_Clear()
nLogAddr  := MAIL_AddAddress("[email protected]")
nLogRem   := MAIL_AddReplyTo("[email protected]")
nLogSub   := MAIL_SetSubject("Assunto de Teste")
nLogBod   := MAIL_AddBody("Corpo do Email teste")
nLogBod2  := MAIL_AddAltBody("Corpo do Email Alternativo")
nLogSend  := MAIL_Send(0)
nlogFim   := MAIL_Finalizar()
vConteudoLog+="=================[ACBR MAIL LOG]================="+Chr(13)
vConteudoLog+="MAIL_Inicializar...........: "+Str(nLogIni)+Chr(13)
vConteudoLog+="MAIL_Clear.................: "+Str(nLogClear)+Chr(13)
vConteudoLog+="MAIL_AddAddress............: "+Str(nLogAddr)+Chr(13)
vConteudoLog+="MAIL_AddReplyTo............: "+Str(nLogRem)+Chr(13)
vConteudoLog+="MAIL_SetSubject............: "+Str(nLogSub)+Chr(13)
vConteudoLog+="MAIL_AddBody...............: "+Str(nLogBod)+Chr(13)
vConteudoLog+="MAIL_AddAltBody............: "+Str(nLogBod2)+Chr(13)
vConteudoLog+="MAIL_Send..................: "+Str(nLogSend)+Chr(13)+Chr(13)
vConteudoLog+="MAIL_Fianlizar.............: "+Str(nlogFim)+Chr(13)+Chr(13)
MemoWrit(vArquivoLog,vConteudoLog)
Return(.T.)

 

Ao chamar a função TestarAcbr() a seguinte saída e produzida

=================[ACBR MAIL LOG]=================
MAIL_Inicializar...........:          0
MAIL_Clear.................:         -1
MAIL_AddAddress............:         -1
MAIL_AddReplyTo............:         -1
MAIL_SetSubject............:         -1
MAIL_AddBody...............:         -1
MAIL_AddAltBody............:         -1
MAIL_Send..................:         -1
MAIL_Finalizar.............:          0

Perceba que a função de inicializar e e finalizar funciona, dando o retorno esperando, porém as demais retornam -1. Obs, o arquivo de configuração config.ini está devidamente configurado e com os dados corretos...

Postado

Boa tarde,

Fiz o teste usando a classe. Não é possível nem instanciar, pois da erro de execução

Comentei algumas linhas para conseguir instanciar, mas ao tentar chamar mail:Nome() e mail:Versao() simplesmente não retorna nada...
Engraçado é que fiz um teste na linguagem C# e consegui chamar as funções normalmente, as mesmas retornaram 0 conforme esperado

Mas não estou conseguindo fazê-las funcionar no xHarbour de maneira alguma...

Quanto a declaração das DLLs, usamos várias outras DLL's aqui (FlexDocs, MySql Elgin) e sempre declaramos assim...

Postado (editado)

Consegui fazer as funções darem o retorno correto adicionando a seguinte linha antes de chamar as função da DLL

DllPrepareCall("ACBrMail32.dll", 0x0010, "MAIL_Inicializar")

 

Nãos sei por que, mas só funciona assim. Porém estou com outro problema, o método MAIL_Send() sempre retorna -10.

Obs: não é configuração de email pois com  a forma de envio anterior do sistema está enviando normalmente...

Editado por sucsis
  • Solution
Postado

Atualização

Depois de passar a tarde inteira tentando, descobri que o funcionamento da DLL é por instância, fazendo com que a forma tradicional de declaração não funcionasse como o esperado.

Exemplo: 

DLL32 Function MAIL_Finalizar() AS _INT PASCAL FROM "MAIL_Finalizar" LIB "ACBrMail32.DLL"

O código acima funcionará no sentido de expor esta função da DLL para sua aplicação, porém para cada função que você chamar, estará fazendo de um objeto diferente, assim as funções não funcionará adequadamente.

A Solução? 

Simples, no início do PRG criei uma variável global chamada xDllMail e atribuí para ela o handle da DLL carregada na memória, dessa forma:

Public xDllMail := LoadLib32("ACBrMail32.DLL")

No final do PRG, na declaração das funções, em vez de colocar LIB "ACBrMail32.DLL" coloquei LIB xDllMail, ficando a declaração das funções da seguinte forma:

DLL32 Function MAIL_Finalizar() AS _INT PASCAL FROM "MAIL_Finalizar" LIB xDllMail

Dessa forma, todas as funções foram declaradas a partir da mesma instância, fazendo a DLL funcionar corretamente.

Sobre o método Send() retornando -10, constatei que a senha estava gravada sem a criptografia, pois eu a inseri manualmente no arquivo .INI. Para funcionar a adequadamente, no código utilizei

 MAIL_ConfigGravarValor("Email","Senha","minhaSenha")
 MAIL_ConfigGravar("C:\config.ini")

Dessa forma, a senha será gravada no arquivo .INI com a criptografia, fazendo tudo funcionar corretamente.

Após isso, consegui enviar emails normalmente. Amanhã farei mais testes, se tudo correr bem encerrarei este tópico.

Postado

Bom dia Rafael,

Obrigado pelo empenho em tentar ajudar, a constante referida está sim no arquivo ACBrLib.ch, eu baixei junto com a classe ACBrMail e linkei na aplicação, infelizmente não foi possível utilizá-la.

Conforme expus na resposta anterior, consegui fazer a DLL funcionar compartilhando a mesma instância da DLL entre as chamadas das funções, carregando a DLL no inicio do .PRG com LoadLib32() e declarando as funções no final do PRG referindo a instância retornada por LoadLib32().

Com relação ao DllPrepareCall(), ela fazia o processo todo funcionar pois ela instanciava a DLL e a mantinha na memória, fazendo com que as chamadas subsequentes fossem realizadas do mesmo objeto.

×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.