323 lines
No EOL
12 KiB
Python
323 lines
No EOL
12 KiB
Python
"""
|
|
🔬 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") |