using Microsoft.Extensions.Logging;
using Microsoft.Win32;
using System.Runtime.InteropServices;
namespace CredentialManager.Services;
///
/// Informazioni su un provider OLE DB installato nel sistema
///
public class OleDbProviderInfo
{
/// ProgID del provider (es. VFPOLEDB.1, Microsoft.ACE.OLEDB.12.0)
public string ProgId { get; set; } = string.Empty;
/// Descrizione leggibile del provider
public string Description { get; set; } = string.Empty;
/// Indica se è un provider Visual FoxPro (solo 32-bit)
public bool IsVfpProvider { get; set; }
/// Nota aggiuntiva (es. avviso 32-bit)
public string? Note { get; set; }
}
///
/// Interfaccia per il servizio di discovery dei provider OLE DB installati
///
public interface IOleDbProviderDiscoveryService
{
///
/// Ottiene la lista dei provider OLE DB noti installati nel sistema
///
List GetInstalledProviders();
///
/// Verifica se almeno un provider Visual FoxPro è installato
///
bool IsVfpProviderInstalled();
}
///
/// Servizio per la discovery dei provider OLE DB installati tramite il registro di Windows.
/// Controlla un elenco di provider noti verificando la presenza della chiave HKEY_CLASSES_ROOT\{ProgId}.
///
public class OleDbProviderDiscoveryService : IOleDbProviderDiscoveryService
{
private readonly ILogger _logger;
///
/// Provider OLE DB noti: ProgID → Descrizione
///
private static readonly (string ProgId, string Description, bool IsVfp)[] KnownProviders =
{
("VFPOLEDB.1", "Microsoft OLE DB Provider per Visual FoxPro 8.0/9.0 (32-bit)", true),
("VFPOLEDB", "Microsoft OLE DB Provider per Visual FoxPro (32-bit)", true),
("Microsoft.ACE.OLEDB.12.0", "Microsoft Access Database Engine 2010", false),
("Microsoft.ACE.OLEDB.16.0", "Microsoft Access Database Engine 2016", false),
("Microsoft.Jet.OLEDB.4.0", "Microsoft Jet 4.0 OLE DB Provider (Access/Excel 97-2003)", false),
("SQLOLEDB", "Microsoft OLE DB Provider for SQL Server (legacy)", false),
("SQLNCLI11", "SQL Server Native Client 11.0", false),
("MSOLEDBSQL", "Microsoft OLE DB Driver for SQL Server", false),
("MSDAORA", "Microsoft OLE DB Provider for Oracle (legacy)", false),
};
public OleDbProviderDiscoveryService(ILogger logger)
{
_logger = logger;
}
public List GetInstalledProviders()
{
var installed = new List();
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
_logger.LogWarning("OLE DB è supportato solo su Windows. Nessun provider restituito.");
return installed;
}
foreach (var (progId, description, isVfp) in KnownProviders)
{
try
{
using var key = Registry.ClassesRoot.OpenSubKey(progId);
if (key != null)
{
var note = isVfp ? "⚠ Solo 32-bit — pubblicare con --runtime win-x86" : null;
installed.Add(new OleDbProviderInfo
{
ProgId = progId,
Description = description,
IsVfpProvider = isVfp,
Note = note
});
_logger.LogDebug("Provider OLE DB trovato: {ProgId}", progId);
}
}
catch (Exception ex)
{
_logger.LogDebug("Errore nel verificare il provider {ProgId}: {Message}", progId, ex.Message);
}
}
_logger.LogInformation("Provider OLE DB installati trovati: {Count}", installed.Count);
return installed;
}
public bool IsVfpProviderInstalled()
{
return GetInstalledProviders().Any(p => p.IsVfpProvider);
}
}