Ir para conteúdo
  • Cadastre-se

dev botao

Programa fecha esporadicamente ao utilizar a dll ACBrNFe32.dll


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

Recommended Posts

Postado

Bom dia a todos!

Estou migrando minha emissão de NFe do AcbrMonitorPlus para AcbrNfeLib, tudo está funcionando perfeitamente com a LIB, o único problema que tenho atualmente é do programa fechar esporadicamente.

As vezes fecha logo na primeira emissão de nfe, as vezes fecha na segunda ou terceira NFe.

Meu programa é em xHarbour, e optei em carregar a DLL sempre quando vou utiliza-la e em seguida descarrego, mas já tentei carregar ela na abertura do programa e descarregar no fechamento do programa, assim como os métodos NFE_Inicializar e NFE_Finalizar, também tentei trocar DllLoad() por LoadLibrary(), LibLoad() e DllPrepareCall(), e a DllUnLoad() por LibFree() e FreeLibrary().
Tentei utilizar a dll Cdecl e também a StdCall.

Já fiz todas as combinações possíveis.

Creio que essa ajuda é para xHarbour e não para a lib, pois no log da lib todos os métodos são executados.
Agradeço a todos desde já.

 

FUNCTION ACBR_CRIA_ASSINA_VALIDA_ENVIA(xTxt,xChaveNfe)
	LOCAL nRetMet,cRet,xLocalXml,xXml,lAssinaValidaEnvia:=.T.
	LOCAL xPara,xCopias,xAssunto,xMensagem
	LOCAL pDllNfe:=DllLoad("ACBrNFe32.dll")
	
	** Nome do XML e local de onde será salvo
	xXml:=xChaveNfe+"-nfe.xml"
	xLocalXml:=pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\XML\"
	xPdf:=xChaveNfe+"-nfe.pdf"
	xLocalPdf:=pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\PDF\"

	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Inicializar",pUnidadeUf+"_NFE.INI","") //Retorno 0
	cRet:=space(1024)
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Consultar",xChaveNfe,.T.,cRet)	//Retorno 0
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","") //Retorno 0
	
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Inicializar",pUnidadeUf+"_NFE.INI","") //Retorno 0
	
	if at("Autorizado o uso da NF-e",cRet)>0
		lAssinaValidaEnvia:=.F.
		
		** Pega a data correta em que a Nfe foi emitida
		q:="select concat(year(b09demi),lpad(month(b09demi),2,'0')) as pasta from nfec where chavenfe='"+xChaveNfe+"'"
		v:=F_GETCON(q)
		xPastaAno:=v[1,1]
		xLocalXml:=xLocalXml+xPastaAno+"\"
		xLocalPdf:=xLocalPdf+xPastaAno+"\"
	else
		xLocalXml:=xLocalXml+strZero(year(date_sql()),4)+strZero(month(date_sql()),2)+"\"
		xLocalPdf:=xLocalPdf+strZero(year(date_sql()),4)+strZero(month(date_sql()),2)+"\"
	endif
	
	if lAssinaValidaEnvia
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_CarregarINI",xTxt) //Retorno 0
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Assinar") //Retorno 0
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Validar") //Retorno 0
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_GravarXml",0,xXml,xLocalXml) //Retorno 0
		cRet:=space(1024)
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Enviar",0,.T.,.T.,.F.,cRet) //Retorno 0
	else
		** Se o XML já está autorizado apenas o carrga
		** Para poder imprimir e enviar por e-mail
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_CarregarXML",xLocalXml+xXml,"") //Retorno 0
	endif

	nRetMet:=DLLCALL(pDllNfe,32,"NFE_ImprimirPDF") //Retorno 0
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_EnviarEmail",xPara,xLocalXml+xXml,.T.,xAssunto,xCopias,,xMensagem) //Retorno 0
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","") //Retorno 0
	DllUnload(pDllNfe)
	
	RETURN .T.

 

 

 

Postado

@Rafael Dias, eu sempre consulto a chave antes de emitir a nfe, reparei que no log, a consulta da segunda Nfe emitida retorna SetRetorno(-10, 
Access violation), os métodos de validar, assinar, enviar que são chamados em seguida retorna 0, mas ao finalizar a lib o programa se fecha.

 

Seria a segunda NFE nesta estrutura que dá o erro:

	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Inicializar",pUnidadeUf+"_NFE.INI","") //Retorno 0
	cRet:=space(1024)
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Consultar",xChaveNfe,.T.,cRet)	//Retorno 0 //Na segunda NFE retorna -10 Access violation
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","") //Retorno 0

 

 

Log: ACBrLibNFE-20201221.log

Postado

@Rafael Dias, adaptei meu programa para usar o PRG do  exemplo do SVN, e estou tendo o retorno  "-10, Access violation" no método de validar regras de negócio.

o Erro é na chamada do método CheckResult, coloquei em vermelho as linhas que o xHarbour destaca ao fechar o programa.

 

METHOD ValidarRegrasdeNegocios() CLASS ACBrNFe
    local hResult
    hResult := DllCall(::hHandle, DLL_OSAPI, "NFE_ValidarRegrasdeNegocios")
    ::CheckResult(hResult)
    RETURN nil

 

METHOD CheckResult(hResult) CLASS ACBrNFe
    local buffer, bufferLen, oErr
    if hResult >= 0 
       RETURN nil
    endif    

    bufferLen := STR_LEN
    buffer := Space(bufferLen)

    DllCall(::hHandle, DLL_OSAPI, "NFE_UltimoRetorno", @buffer, @bufferLen)
    if bufferLen > STR_LEN
        buffer := Space(bufferLen)
        DllCall(::hHandle, DLL_OSAPI, "NFE_UltimoRetorno", @buffer, @bufferLen)        
    endif    

    oErr := ErrorNew()
    oErr:Severity := ES_ERROR
    oErr:Description := hb_UTF8ToStr(buffer)
    Throw(oErr)
    RETURN nil

 

Abaixo está o meu PRG modificado.

 

Log ACBR:  ACBrLibNFE-20201223.log

 

FUNCTION ACBR_CRIA_ASSINA_VALIDA_ENVIA(xTxt,xChaveNfe)
	LOCAL cRet,xLocalXml,xXml,lAssinaValidaEnvia:=.T.
	LOCAL xPara,xCopias,xAssunto,xMensagem
	
	** Nome do XML e local de onde será salvo
	xXml:=xChaveNfe+"-nfe.xml"
	xLocalXml:=pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\XML\"
	xPdf:=xChaveNfe+"-nfe.pdf"
	xLocalPdf:=pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\PDF\"
	
	** Iniciar arquivo de configurações do ACBR
	nfe:=ACBrNFe():New(pUnidadeUf+"_NFE.INI","")
	
	** Consulta a chave para saber se já é uma NFe Autorizada para uso
	cRet:=nfe:Consultar(xChaveNfe,.T.)	
	if at("Consumo Indevido",cRet)>0
		alert("Consumo Indevido;;Aguarde alguns minutos e tente novamente")
		nfe:Destroy()
		RETURN .F.
	endif
	
	if at("Autorizado o uso da NF-e",cRet)>0
		lAssinaValidaEnvia:=.F.
		
		** Pega a data correta em que a Nfe foi emitida
		q:="select concat(year(b09demi),lpad(month(b09demi),2,'0')) as pasta from nfec where chavenfe='"+xChaveNfe+"'"
		v:=F_GETCON(q)
		if len(v)==0
			alert("Erro ao localizar a chave no Nfec;"+xChaveNfe)
			nfe:Destroy()
			RETURN .F.
		endif
		xPastaAno:=v[1,1]
		xLocalXml:=xLocalXml+xPastaAno+"\"
		xLocalPdf:=xLocalPdf+xPastaAno+"\"
		
		** Verifica se o arquivo XML existe na pasta
		if ! FILE(xLocalXml+xXml)
			** Para garantir cria a pasta do anomes do XML e PDF
			FT_MKDIR(xLocalXml)
			FT_MKDIR(xLocalPdf)
			alert("NFe autorizada, porem arquivo xml nao localizado na pasta:;"+xLocalXml+xXml+";Faca o download pelo site do SEFAZ e coloque na pasta indicada")
			nfe:Destroy()
			RETURN .F.
		endif
	else
		xLocalXml:=xLocalXml+strZero(year(date_sql()),4)+strZero(month(date_sql()),2)+"\"
		xLocalPdf:=xLocalPdf+strZero(year(date_sql()),4)+strZero(month(date_sql()),2)+"\"
	endif
	
	** Para garantir cria a pasta do anomes do XML e PDF
	FT_MKDIR(xLocalXml)
	FT_MKDIR(xLocalPdf)
	
	if lAssinaValidaEnvia
		** Carrega o arquivo TXT da NFe
		nfe:CarregarINI(xTxt)
		
		** Valida regras de negócio da NFe
		cRet:=nfe:ValidarRegrasdeNegocios()
		cRet:=strTran(cRet,chr(0),"")	//Elimina um quadrado "[]" do retrono 
		cRet:=strTran(cRet,chr(32),"")	//Elimina um quadrado "[]" do retrono 
	
		if ! empty(cRet)
			alert(cRet)
			nfe:Destroy()
			RETURN .F.
		endif
		
		** Assina NFe que está carregada pelo NFE_CarregarINI
		nfe:Assinar()

		** Validar XML assinado na pasta correta
		nfe:Validar()

		** Grava XML assinado na pasta correta
		nfe:GravarXml(0,xXml,xLocalXml)
		
		** Enviar XML par ao SEFAZ
		nfe:Enviar(0,.T.,.T.,.F.)
	else
		** Se o XML já está autorizado apenas o carrga
		** Para poder imprimir e enviar por e-mail
		nfe:CarregarXML(xLocalXml+xXml)
	endif
	
	nfe:ImprimirPDF()
	FileCopy(pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\PDF\"+xPdf,xLocalPdf+xPdf)

	mVar:=ACBR_EMAIL(xChaveNfe)
	xPara:=mVar[1]
	xCopias:=mVar[2]
	xAssunto:=mVar[3]
	xMensagem:=mVar[4]

	nfe:EnviarEmail(xPara, xLocalXml+xXml,.T.,xAssunto,xMensagem,xCopias)
	nfe:Destroy()
	
	RETURN .T.

 

Postado

@Rafael Dias, fiz algumas modificações no prg acbrnfe.prg e funcionou!

São elas:

Método ValidarRegrasdeNegocios não tinha variável para o retorno.
Método EnviarEmail estava com variáveis invertidas na chamada do método do prg e do método da dll
Destroy() não era um método e sim uma procedure, mudei para método

 

As correções ficaram assim:

METHOD ValidarRegrasdeNegocios() CLASS ACBrNFe
    local hResult, buffer, bufferLen
    bufferLen := STR_LEN
    buffer := Space(bufferLen)
    hResult := DllCall(::hHandle, DLL_OSAPI, "NFE_ValidarRegrasdeNegocios", @buffer, @bufferLen)
    ::CheckResult(hResult)
    RETURN ::ProcessResult(buffer, bufferLen)

 

METHOD EnviarEmail(ePara, eChaveNFe, aEnviaPDF, eAssunto, eCc, eAnexos, eMensagem) CLASS ACBrNFe
    local hResult
    hResult := DllCall(::hHandle, DLL_OSAPI, "NFE_EnviarEmail", hb_StrToUTF8(ePara), hb_StrToUTF8(eChaveNFe), aEnviaPDF, eAssunto, hb_StrToUTF8(eCc), hb_StrToUTF8(eAnexos),  eMensagem)
    ::CheckResult(hResult)
    RETURN nil

METHOD Destroy CLASS ACBrNFe
    DllCall(::hHandle, DLL_OSAPI, "NFE_Finalizar")
    DllUnload(::hHandle)
    RETURN nil

 

obrigado pela ajuda!

  • Este tópico foi criado há 1437 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Visitante
Este tópico está agora fechado para novas respostas
×
×
  • 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.