""" 🔬 DIAGNOSTIC APPROFONDI CRYSTAL REPORTS Découvre pourquoi Crystal ne fonctionne pas après redémarrage """ import os import winreg import subprocess import sys def diagnostic_complet_crystal(): """Diagnostic exhaustif de l'installation Crystal""" print("="*70) print("🔬 DIAGNOSTIC APPROFONDI CRYSTAL REPORTS") print("="*70) problemes = [] solutions = [] # ========================================== # 1. VÉRIFIER SI CRYSTAL EST INSTALLÉ # ========================================== print("\n📁 1. Vérification présence des fichiers...") chemins_installation = [ r"C:\Program Files\SAP BusinessObjects", r"C:\Program Files (x86)\SAP BusinessObjects", r"C:\Program Files\SAP\Crystal Reports", r"C:\Program Files (x86)\SAP\Crystal Reports", ] crystal_trouve = False chemin_crystal = None for chemin in chemins_installation: if os.path.exists(chemin): print(f" Dossier trouvé : {chemin}") crystal_trouve = True chemin_crystal = chemin # Afficher taille try: total_size = 0 for dirpath, dirnames, filenames in os.walk(chemin): for f in filenames: fp = os.path.join(dirpath, f) try: total_size += os.path.getsize(fp) except: pass size_mb = total_size / (1024 * 1024) print(f" Taille : {size_mb:.1f} MB") if size_mb < 100: print(f" Taille suspecte (attendu: 300-800 MB)") problemes.append("Installation incomplète (taille trop petite)") except Exception as e: print(f" Impossible de calculer taille : {e}") else: print(f" Absent : {chemin}") if not crystal_trouve: print("\n PROBLÈME MAJEUR : Crystal Reports n'est pas installé") problemes.append("Crystal Reports non installé") solutions.append("Télécharger et installer SAP Crystal Reports Runtime") return {"problemes": problemes, "solutions": solutions, "installe": False} # ========================================== # 2. CHERCHER LES DLL CRITIQUES # ========================================== print("\n📦 2. Recherche DLL critiques...") dll_critiques = { 'crpe32.dll': 'Crystal Reports Print Engine (CRITIQUE)', 'crxf_pdf.dll': 'Export PDF (CRITIQUE)', 'crdb_adoplus.dll': 'Connexion base de données', 'CrystalDecisions.CrystalReports.Engine.dll': 'Moteur Crystal .NET', } dll_trouvees = {} for dll_nom, description in dll_critiques.items(): trouve = False for root, dirs, files in os.walk(chemin_crystal): if dll_nom.lower() in [f.lower() for f in files]: dll_path = os.path.join(root, dll_nom) dll_trouvees[dll_nom] = dll_path print(f" {dll_nom}") print(f" {dll_path}") trouve = True break if not trouve: print(f" {dll_nom} - {description}") if "CRITIQUE" in description: problemes.append(f"{dll_nom} manquante") if len(dll_trouvees) < 2: print("\n Trop peu de DLL trouvées - Installation corrompue") problemes.append("DLL manquantes - Installation corrompue") solutions.append("Réinstaller Crystal Reports Runtime") # ========================================== # 3. VÉRIFIER LE REGISTRE # ========================================== print("\n📋 3. Vérification registre Windows...") prog_ids = [ "CrystalRuntime.Application.140", "CrystalRuntime.Application.13", "CrystalRuntime.Application.12", "CrystalRuntime.Application", "CrystalDesignRunTime.Application", ] prog_ids_trouves = [] for prog_id in prog_ids: try: # Vérifier existence key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, prog_id) print(f" {prog_id}") # Lire le CLSID try: clsid_key = winreg.OpenKey(key, "CLSID") clsid, _ = winreg.QueryValueEx(clsid_key, "") print(f" CLSID: {clsid}") # Vérifier que le CLSID existe aussi try: clsid_path = f"CLSID\\{clsid}" clsid_key_check = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, clsid_path) # Lire InprocServer32 (chemin DLL) try: server_key = winreg.OpenKey(clsid_key_check, "InprocServer32") dll_path, _ = winreg.QueryValueEx(server_key, "") print(f" DLL: {dll_path}") # Vérifier que la DLL existe if not os.path.exists(dll_path): print(f" DLL INTROUVABLE: {dll_path}") problemes.append(f"{prog_id}: DLL manquante ({dll_path})") else: prog_ids_trouves.append(prog_id) except: print(f" InprocServer32 non trouvé") except: print(f" CLSID {clsid} non trouvé dans registre") problemes.append(f"{prog_id}: CLSID cassé") except: print(f" Pas de CLSID") winreg.CloseKey(key) except: print(f" {prog_id}") if not prog_ids_trouves: print("\n Aucun ProgID valide - Enregistrement COM échoué") problemes.append("ProgID non enregistrés correctement") solutions.append("Réenregistrer les DLL Crystal avec regsvr32") # ========================================== # 4. VÉRIFIER ARCHITECTURE (32 vs 64 bit) # ========================================== print("\n🔧 4. Vérification architecture...") # Architecture Python python_arch = "64-bit" if sys.maxsize > 2**32 else "32-bit" print(f" Python : {python_arch}") # Architecture système import platform sys_arch = platform.machine() print(f" Système : {sys_arch}") # Détecter architecture Crystal installée crystal_arch = None if dll_trouvees: first_dll = list(dll_trouvees.values())[0] if "win64_x64" in first_dll or "x64" in first_dll: crystal_arch = "64-bit" elif "win32_x86" in first_dll or "x86" in first_dll: crystal_arch = "32-bit" if crystal_arch: print(f" Crystal : {crystal_arch}") if python_arch != crystal_arch: print(f"\n INCOMPATIBILITÉ ARCHITECTURE") print(f" Python {python_arch} ne peut pas utiliser Crystal {crystal_arch}") problemes.append(f"Incompatibilité: Python {python_arch} vs Crystal {crystal_arch}") solutions.append(f"Réinstaller Crystal en version {python_arch}") # ========================================== # 5. VÉRIFIER SERVICES WINDOWS # ========================================== print("\n🔄 5. Vérification services Windows...") try: result = subprocess.run( ['sc', 'query', 'type=', 'service'], capture_output=True, text=True, timeout=10 ) services_crystal_attendus = [ "SAP Crystal Reports", "Crystal Reports", "CrystalReports", ] services_trouves = [] for service in services_crystal_attendus: if service.lower() in result.stdout.lower(): services_trouves.append(service) print(f" Service trouvé: {service}") if not services_trouves: print(f" Aucun service Crystal trouvé") print(f" (Normal pour Runtime léger)") except Exception as e: print(f" Impossible de vérifier services: {e}") # ========================================== # 6. TEST INSTANCIATION COM DÉTAILLÉ # ========================================== print("\n🧪 6. Test instanciation COM détaillé...") import win32com.client for prog_id in prog_ids_trouves: print(f"\n Test: {prog_id}") try: obj = win32com.client.Dispatch(prog_id) print(f" Instanciation RÉUSSIE") # Lister méthodes disponibles print(f" Méthodes disponibles:") for attr in dir(obj): if not attr.startswith('_') and callable(getattr(obj, attr, None)): print(f" - {attr}()") return { "problemes": problemes, "solutions": solutions, "installe": True, "prog_id_fonctionnel": prog_id } except Exception as e: print(f" Échec: {e}") print(f" Type erreur: {type(e).__name__}") print(f" Code: {e.args if hasattr(e, 'args') else 'N/A'}") # ========================================== # 7. RÉSUMÉ ET RECOMMANDATIONS # ========================================== print("\n" + "="*70) print("📊 RÉSUMÉ DU DIAGNOSTIC") print("="*70) print(f"\n📁 Installation détectée: {'OUI' if crystal_trouve else 'NON'}") print(f"📦 DLL trouvées: {len(dll_trouvees)}/{len(dll_critiques)}") print(f"📋 ProgID valides: {len(prog_ids_trouves)}") print(f"🔧 Architecture: Python {python_arch}, Crystal {crystal_arch or 'INCONNUE'}") if problemes: print(f"\n PROBLÈMES DÉTECTÉS ({len(problemes)}):") for i, pb in enumerate(problemes, 1): print(f" {i}. {pb}") if solutions: print(f"\n💡 SOLUTIONS RECOMMANDÉES:") for i, sol in enumerate(solutions, 1): print(f" {i}. {sol}") print("\n" + "="*70) return { "problemes": problemes, "solutions": solutions, "installe": crystal_trouve, "dll_trouvees": list(dll_trouvees.keys()), "prog_ids_valides": prog_ids_trouves, "architecture_ok": python_arch == crystal_arch if crystal_arch else False } if __name__ == "__main__": resultats = diagnostic_complet_crystal() print("\n💾 Résultats sauvegardés dans diagnostic_crystal.txt") # Sauvegarder dans fichier with open("diagnostic_crystal.txt", "w", encoding="utf-8") as f: f.write("="*70 + "\n") f.write("DIAGNOSTIC CRYSTAL REPORTS\n") f.write("="*70 + "\n\n") f.write(f"Installation détectée: {resultats['installe']}\n") f.write(f"DLL trouvées: {', '.join(resultats.get('dll_trouvees', []))}\n") f.write(f"ProgID valides: {', '.join(resultats.get('prog_ids_valides', []))}\n") f.write(f"Architecture OK: {resultats.get('architecture_ok', False)}\n\n") f.write("PROBLÈMES:\n") for pb in resultats['problemes']: f.write(f" - {pb}\n") f.write("\nSOLUTIONS:\n") for sol in resultats['solutions']: f.write(f" - {sol}\n")