Estimado Heraclio,
1. Solución al Error LNK2005: Duplicated symbol: OCCURS
El problema es que estás enlazando dos bibliotecas de compatibilidad que intentan hacer lo mismo: hbfoxpro.lib (funciones de FoxPro) y xhb.lib (funciones de xHarbour). Ambas definen la función OCCURS().
El enlazador de Microsoft (MSVC) es muy estricto y no permite esta ambigüedad.
La Solución:
Generalmente, en FiveWin se recomienda priorizar xhb.lib sobre hbfoxpro.lib
- Abre tu archivo de proyecto (.hbp o makefile).
- Busca la línea que incluye hbfoxpro.hbc o -lhbfoxpro.
- Elimínala.
- Asegúrate de tener incluída xhb.hbc.
¿Por qué funciona esto?
La librería xhb ya contiene una implementación de OCCURS(). Al quitar hbfoxpro, eliminas la colisión. Si tu código usa otras funciones específicas de FoxPro que no están en xhb, avísame, pero para Occurs, xhb es suficiente.
---
2. Solución al GPF (Crash) en el método :Send()
Este es el problema más crítico. El SAT (y el DOF) han actualizado sus servidores para rechazar conexiones que no sean TLS 1.2 o superior. Los componentes OLE (MSXML2 y WinHttp) a veces fallan catastróficamente (GPF) en Windows 11 al negociar estos certificados desde un entorno Harbour/MSVC, especialmente si el Garbage Collector intenta limpiar una variable mientras la conexión OLE sigue "colgada" o en proceso de cierre.
Mi recomendación fuerte: Deja de usar OLE para esto. Pásate a hbcurl.
hbcurl es la implementación nativa de libcurl en Harbour. Es infinitamente más estable, maneja TLS 1.2/1.3 automáticamente y no depende de las caprichosas DLLs de Windows.
Opción A: La solución robusta (hbcurl)
Añade hbcurl.hbc a tu archivo .hbp y usa este código para descargar la lista:
Code: Select all | Expand
FUNCTION DescargarListaNegraSAT()
Local cUrl := "http://omawww.sat.gob.mx/cifras_sat/Documents/Listado_Completo_69-B.csv" // Ejemplo URL
Local cSaveFile := "c:\temp\lista69b.csv"
Local hCurl
Local nResult
// Inicializar Curl
hb_curl_global_init()
hCurl := curl_easy_init()
IF ! Empty( hCurl )
// Configurar URL
curl_easy_setopt( hCurl, HB_CURLOPT_URL, cUrl )
// Configurar descarga a archivo
curl_easy_setopt( hCurl, HB_CURLOPT_DOWNLOAD, .T. )
curl_easy_setopt( hCurl, HB_CURLOPT_DL_FILE_SETUP, cSaveFile )
// CRÍTICO PARA EL SAT: Seguir redirecciones y saltar errores de certificado si es necesario
curl_easy_setopt( hCurl, HB_CURLOPT_FOLLOWLOCATION, .T. )
curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. ) // Útil si el SAT cambia la CA intermedia
curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYHOST, .F. )
// Ejecutar
nResult := curl_easy_perform( hCurl )
IF nResult == 0
MsgInfo( "Descarga exitosa: " + cSaveFile )
ELSE
MsgAlert( "Error en descarga: " + hb_ntos(nResult) )
ENDIF
// Limpieza
curl_easy_cleanup( hCurl )
ENDIF
hb_curl_global_cleanup()
RETURN NIL
Opción B: Insistir con WinHttp (Parche)
Si no puedes cambiar a curl ahora mismo, debes forzar el protocolo de seguridad antes del Send(). Sin embargo, esto no garantiza que el GPF desaparezca si el problema es de memoria en MSVC, pero suele ayudar:
Code: Select all | Expand
TRY
oHttp := CreateObject( "WinHttp.WinHttpRequest.5.1" )
// 2048 = TLS 1.1, 4096 = TLS 1.2, 8192 = TLS 1.3 (aprox)
// Forzamos TLS 1.2 (0x00000800 = 2048 en hexa, pero el valor suele ser 2048 o 128 según la versión de winhttp)
// En Windows modernos, usa la constante:
oHttp:Option( 9 ) := 2048 // WinHttpRequestOption_SecureProtocols
oHttp:Open( "GET", "https://www.sat.gob.mx/...", .F. ) // .F. para síncrono
oHttp:Send()
cResp := oHttp:ResponseBody
CATCH oErr
MsgStop( "Error de conexión: " + oErr:Description )
END
Nota: MSXML2.ServerXMLHTTP es aún más propenso a fallar que WinHttp.WinHttpRequest.5.1 en descargas directas.
Resumen del Plan de Acción
- Edita tu .hbp: Elimina hbfoxpro.hbc (o la librería -lhbfoxpro). Mantén xhb.hbc.
- Añade a tu .hbp: hbcurl.hbc.
- Reemplaza tu rutina de descarga OLE por la rutina hbcurl que te puse arriba.