#Requires AutoHotkey v2.0 #SingleInstance Force #Warn ; ============================================================================= ; Lanceur de scripts v1 Benchmark de PC ; ============================================================================= ; Vérifier si le script est lancé en tant qu'administrateur if !A_IsAdmin { try { if A_IsCompiled Run '*RunAs "' A_ScriptFullPath '"' else Run '*RunAs "' A_AhkPath '" "' A_ScriptFullPath '"' } ExitApp } ; ============================================================================= ; Variables globales (déclarées au niveau du script, pas besoin de 'global' ici) ; ============================================================================= selectedCategory := "" highlightColor := "0xADD8E6" defaultColor := "Default" isSoftsCategory := false ; Flag pour savoir si on est dans la catégorie Softs isSearchMode := false ; Flag pour savoir si on est en mode recherche softsList := [] ; Liste des softs configurés searchResults := [] ; Résultats de recherche allScriptsCache := [] ; Cache de tous les scripts cpuText := "" ramText := "" osText := "" computerText := "" ipText := "" secureBootText := "" sysInfoGroup := "" lv := "" motherboardText := "" launchSelectedBtn := "" quitBtn := "" selectAllCheckbox := "" logCheckbox := "" extensionsBtn := "" hiddenFilesBtn := "" categoryLV := "" searchEdit := "" systemBtnList := [] scriptDir := A_ScriptDir scriptsPath := scriptDir "\Scripts" softsIniPath := scriptDir "\softs.ini" ; Fichier de configuration des softs licencePath := A_ScriptDir "\..\Licence Geco.txt" logPath := "C:\Geco\Log\Log_script.txt" ; ============================================================================= ; Détection de la résolution et calcul des tailles ; ============================================================================= screenWidth := A_ScreenWidth screenHeight := A_ScreenHeight ; Calcul des dimensions de la fenêtre selon la résolution if (screenWidth <= 800 || screenHeight <= 600) { ; Mode WinPE / Petite résolution (800x600) winWidth := 780 winHeight := 560 compactMode := true } else if (screenWidth <= 1024 || screenHeight <= 768) { ; Résolution moyenne (1024x768) winWidth := 950 winHeight := 700 compactMode := true } else if (screenWidth <= 1366 || screenHeight <= 768) { ; Résolution laptop standard (1366x768) winWidth := 1100 winHeight := 620 compactMode := false } else { ; Grande résolution (1920x1080+) winWidth := 1120 winHeight := 620 compactMode := false } ; Dimensions des éléments selon le mode if compactMode { categoryWidth := 150 categoryHeight := winHeight - 200 lvRows := 15 btnSpacing := 38 fontSize := 9 sysInfoHeight := 75 } else { categoryWidth := 180 categoryHeight := winHeight - 165 lvRows := 22 btnSpacing := 45 fontSize := 10 sysInfoHeight := 90 } if !DirExist(scriptsPath) { MsgBox "Le dossier '\Scripts' est introuvable dans: " scriptDir ExitApp } ; ============================================================================= ; Fonctions utilitaires ; ============================================================================= ; Fonction pour lire une valeur du registre avec valeur par défaut SafeRegRead(regPath, valueName, defaultValue := "") { try { return RegRead(regPath, valueName) } catch { return defaultValue } } ; Fonction pour obtenir toutes les catégories uniques à partir des scripts GetAllCategories(path) { local cats := Map() ; Collecter les catégories depuis les fichiers PS1 Loop Files path "\*.ps1", "F" { data := ParseMetadata(A_LoopFileFullPath) if data && data.Has("Categorie") && data["Categorie"] { categoriesList := StrSplit(data["Categorie"], ";") for _, cat in categoriesList { cat := Trim(cat) if cat cats[cat] := true } } } ; Collecter les catégories depuis les fichiers BAT/CMD Loop Files path "\*.bat", "F" { data := ParseMetadata(A_LoopFileFullPath) if data && data.Has("Categorie") && data["Categorie"] { categoriesList := StrSplit(data["Categorie"], ";") for _, cat in categoriesList { cat := Trim(cat) if cat cats[cat] := true } } } Loop Files path "\*.cmd", "F" { data := ParseMetadata(A_LoopFileFullPath) if data && data.Has("Categorie") && data["Categorie"] { categoriesList := StrSplit(data["Categorie"], ";") for _, cat in categoriesList { cat := Trim(cat) if cat cats[cat] := true } } } ; Convertir le Map en Array categoriesArray := [] for cat, _ in cats categoriesArray.Push(cat) ; Trier les catégories par ordre alphabétique (tri à bulles corrigé) categoriesArray := SortArray(categoriesArray) return categoriesArray } ; Fonction de tri à bulles corrigée pour les tableaux de chaînes SortArray(arr) { n := arr.Length if n <= 1 return arr Loop n - 1 { swapped := false Loop n - A_Index { if StrCompare(arr[A_Index], arr[A_Index + 1]) > 0 { temp := arr[A_Index] arr[A_Index] := arr[A_Index + 1] arr[A_Index + 1] := temp swapped := true } } if !swapped break } return arr } ; Fonction de tri pour les scripts (par ordre puis par nom) SortScripts(scripts) { n := scripts.Length if n <= 1 return scripts Loop n - 1 { swapped := false Loop n - A_Index { ; Comparer d'abord par ordre (numérique), puis par nom (alphabétique) ordre1 := Integer(scripts[A_Index].ordre) ordre2 := Integer(scripts[A_Index + 1].ordre) shouldSwap := false if (ordre1 > ordre2) { shouldSwap := true } else if (ordre1 = ordre2) && (StrCompare(scripts[A_Index].nom, scripts[A_Index + 1].nom) > 0) { shouldSwap := true } if shouldSwap { temp := scripts[A_Index] scripts[A_Index] := scripts[A_Index + 1] scripts[A_Index + 1] := temp swapped := true } } if !swapped break } return scripts } ; Fonction pour définir la hauteur des lignes d'un ListView SetListViewRowHeight(lvCtrl, height) { static LVM_SETIMAGELIST := 0x1003 static LVSIL_SMALL := 1 ; Créer une ImageList avec la hauteur souhaitée hIL := DllCall("ImageList_Create", "Int", 1, "Int", height, "UInt", 0, "Int", 1, "Int", 1, "Ptr") ; Associer l'ImageList au ListView SendMessage(LVM_SETIMAGELIST, LVSIL_SMALL, hIL, lvCtrl.Hwnd) } ; ============================================================================= ; Gestion des Softs (catégorie spéciale) ; ============================================================================= ; Créer le fichier softs.ini par défaut s'il n'existe pas CreateDefaultSoftsIni() { global softsIniPath if !FileExist(softsIniPath) { defaultContent := " ( ; ============================================================================= ; Configuration des Softs - Lanceur de scripts ; ============================================================================= ; Format: Nom|Chemin|Description ; Le chemin peut être relatif (ex: ..\SOFT\app.exe) ou absolu (ex: C:\Tools\app.exe) ; Utilisez %USBDRIVE% pour la racine de la clé USB ; ; Exemples: ; 7-Zip|..\SOFT\7-Zip\7zFM.exe|Gestionnaire d'archives ; Notepad++|..\SOFT\Notepad++\notepad++.exe|Éditeur de texte ; CPU-Z|%USBDRIVE%\SOFT\CPU-Z\cpuz.exe|Informations CPU ; ============================================================================= [Softs] ; Ajoutez vos softs ci-dessous (un par ligne) ; Format: Nom|Chemin|Description )" try { FileAppend(defaultContent, softsIniPath, "UTF-8") } } } ; Charger les softs depuis le fichier ini LoadSoftsFromIni() { global softsIniPath, scriptDir softs := [] if !FileExist(softsIniPath) return softs ; Déterminer la racine de la clé USB usbDrive := RegExReplace(scriptDir, "\\[^\\]+$", "") inSection := false Loop Read softsIniPath { line := Trim(A_LoopReadLine) ; Ignorer les lignes vides et commentaires if (line = "" || SubStr(line, 1, 1) = ";") continue ; Détecter la section [Softs] if (line = "[Softs]") { inSection := true continue } ; Si on est dans une autre section, arrêter if (SubStr(line, 1, 1) = "[") inSection := false if !inSection continue ; Parser la ligne: Nom|Chemin|Description parts := StrSplit(line, "|") if (parts.Length >= 2) { nom := Trim(parts[1]) chemin := Trim(parts[2]) description := parts.Length >= 3 ? Trim(parts[3]) : "" ; Remplacer les variables chemin := StrReplace(chemin, "%USBDRIVE%", usbDrive) ; Convertir chemin relatif en absolu if (SubStr(chemin, 1, 2) = "..") { chemin := scriptDir "\" chemin } ; Vérifier si le fichier existe if FileExist(chemin) { ; Récupérer la version du fichier version := GetFileVersion(chemin) softs.Push({ nom: nom, chemin: chemin, description: description, version: version }) } } } return softs } ; Récupérer la version d'un fichier exécutable GetFileVersion(filePath) { try { ; Obtenir la taille nécessaire pour les infos de version size := DllCall("Version\GetFileVersionInfoSize", "Str", filePath, "Ptr", 0, "UInt") if (size = 0) return "" ; Allouer le buffer buf := Buffer(size) ; Récupérer les infos de version if !DllCall("Version\GetFileVersionInfo", "Str", filePath, "UInt", 0, "UInt", size, "Ptr", buf) return "" ; Récupérer le pointeur vers VS_FIXEDFILEINFO if !DllCall("Version\VerQueryValue", "Ptr", buf, "Str", "\", "Ptr*", &pFFI := 0, "UInt*", &len := 0) return "" ; Lire les valeurs de version (structure VS_FIXEDFILEINFO) fileVersionMS := NumGet(pFFI, 8, "UInt") ; dwFileVersionMS fileVersionLS := NumGet(pFFI, 12, "UInt") ; dwFileVersionLS ; Extraire les 4 parties de la version v1 := (fileVersionMS >> 16) & 0xFFFF v2 := fileVersionMS & 0xFFFF v3 := (fileVersionLS >> 16) & 0xFFFF v4 := fileVersionLS & 0xFFFF ; Formater la version if (v4 = 0) { if (v3 = 0) return v1 "." v2 return v1 "." v2 "." v3 } return v1 "." v2 "." v3 "." v4 } catch { return "" } } ; Extraire l'icône d'un exécutable GetFileIcon(filePath) { static iconCache := Map() if iconCache.Has(filePath) return iconCache[filePath] ; Extraire l'icône avec Shell32 hIcon := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", filePath, "UInt", 0, "Ptr") if (hIcon > 1) { iconCache[filePath] := hIcon return hIcon } return 0 } ; Créer une ImageList avec les icônes des softs CreateSoftsImageList(softs) { ; Créer une ImageList 24x24 (ou 16x16 si tu préfères) hIL := DllCall("ImageList_Create", "Int", 20, "Int", 20, "UInt", 0x21, "Int", softs.Length, "Int", 10, "Ptr") for soft in softs { hIcon := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", soft.chemin, "UInt", 0, "Ptr") if (hIcon > 1) { DllCall("ImageList_AddIcon", "Ptr", hIL, "Ptr", hIcon, "Int") DllCall("DestroyIcon", "Ptr", hIcon) } else { ; Icône par défaut si pas d'icône trouvée hDefaultIcon := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", "shell32.dll", "UInt", 2, "Ptr") DllCall("ImageList_AddIcon", "Ptr", hIL, "Ptr", hDefaultIcon, "Int") DllCall("DestroyIcon", "Ptr", hDefaultIcon) } } return hIL } ; Afficher les softs dans le ListView RefreshSoftsList() { global lv, softsList lv.Delete() softsList := LoadSoftsFromIni() if (softsList.Length = 0) { lv.Add(, , "(Aucun soft configuré)", "Éditez softs.ini pour ajouter des softs", "", "") return } ; Créer et associer l'ImageList hIL := CreateSoftsImageList(softsList) SendMessage(0x1003, 1, hIL, lv.Hwnd) ; LVM_SETIMAGELIST, LVSIL_SMALL ; Ajouter les softs au ListView avec la version (colonne Ordre vide pour les softs) for index, soft in softsList { lv.Add("Icon" index, , soft.nom, soft.description, soft.version, "") } } ; Lancer un soft en administrateur LaunchSoftAsAdmin(softPath) { try { Run '*RunAs "' softPath '"' WriteLog("Soft: " softPath, "OK") } catch Error as e { MsgBox "Erreur lors du lancement: " e.Message WriteLog("Soft: " softPath, "ERREUR") } } ; Ouvrir le fichier softs.ini pour édition EditSoftsIni() { global softsIniPath CreateDefaultSoftsIni() try { Run 'notepad.exe "' softsIniPath '"' } catch { MsgBox "Impossible d'ouvrir le fichier de configuration." } } ; ============================================================================= ; Fonctions de recherche ; ============================================================================= ; Charger tous les scripts et softs en cache pour la recherche LoadAllItemsCache() { global scriptsPath, allScriptsCache allScriptsCache := [] ; Charger tous les scripts PS1 Loop Files scriptsPath "\*.ps1", "F" { data := ParseMetadata(A_LoopFileFullPath) if data { allScriptsCache.Push({ nom: data.Get("Nom"), description: data.Get("Description"), version: data.Get("Version"), ordre: data.Get("Ordre", "50"), type: "ps1", chemin: A_LoopFileFullPath, categorie: data.Get("Categorie") }) } } ; Charger tous les scripts BAT Loop Files scriptsPath "\*.bat", "F" { data := ParseMetadata(A_LoopFileFullPath) if data { allScriptsCache.Push({ nom: data.Get("Nom"), description: data.Get("Description"), version: data.Get("Version"), ordre: data.Get("Ordre", "50"), type: "bat", chemin: A_LoopFileFullPath, categorie: data.Get("Categorie") }) } } ; Charger tous les scripts CMD Loop Files scriptsPath "\*.cmd", "F" { data := ParseMetadata(A_LoopFileFullPath) if data { allScriptsCache.Push({ nom: data.Get("Nom"), description: data.Get("Description"), version: data.Get("Version"), ordre: data.Get("Ordre", "50"), type: "cmd", chemin: A_LoopFileFullPath, categorie: data.Get("Categorie") }) } } ; Charger tous les softs softs := LoadSoftsFromIni() for soft in softs { allScriptsCache.Push({ nom: soft.nom, description: soft.description, version: soft.version, ordre: "", type: "soft", chemin: soft.chemin, categorie: "📦 Softs" }) } } ; Événement quand le texte de recherche change OnSearchChange(*) { global searchEdit, isSearchMode, categoryLV searchText := Trim(searchEdit.Value) if (searchText = "") { ; Si la recherche est vide, revenir à la catégorie sélectionnée isSearchMode := false idx := categoryLV.GetNext() if idx { categoryName := categoryLV.GetText(idx, 1) ShowCategory(categoryName) } return } ; Activer le mode recherche isSearchMode := true ; Désélectionner la catégorie dans le ListView Loop categoryLV.GetCount() { categoryLV.Modify(A_Index, "-Select") } ; Effectuer la recherche PerformSearch(searchText) } ; Effectuer la recherche PerformSearch(searchText) { global lv, allScriptsCache, searchResults ; Recharger le cache si vide if (allScriptsCache.Length = 0) { LoadAllItemsCache() } lv.Delete() searchResults := [] searchLower := StrLower(searchText) ; Rechercher dans tous les éléments for item in allScriptsCache { nomLower := StrLower(item.nom) descLower := StrLower(item.description) ; Vérifier si le terme de recherche est dans le nom ou la description if (InStr(nomLower, searchLower) || InStr(descLower, searchLower)) { searchResults.Push(item) } } ; Afficher les résultats if (searchResults.Length = 0) { lv.Add(, , "(Aucun résultat)", "Essayez d'autres termes de recherche", "", "") return } ; Créer l'ImageList mixte (scripts + softs) hIL := CreateSearchImageList(searchResults) SendMessage(0x1003, 1, hIL, lv.Hwnd) ; Ajouter les résultats au ListView for index, item in searchResults { lv.Add("Icon" index, , item.nom, item.description, item.version, item.ordre) } } ; Créer une ImageList pour les résultats de recherche (mixte scripts et softs) CreateSearchImageList(results) { hIL := DllCall("ImageList_Create", "Int", 20, "Int", 20, "UInt", 0x21, "Int", results.Length, "Int", 10, "Ptr") ; Chemins des icônes système psPath := A_WinDir "\System32\WindowsPowerShell\v1.0\powershell.exe" cmdPath := A_WinDir "\System32\cmd.exe" for item in results { if (item.type = "ps1") { ; Icône PowerShell if FileExist(psPath) { hIcon := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", psPath, "UInt", 0, "Ptr") } else { hIcon := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", "shell32.dll", "UInt", 71, "Ptr") } } else if (item.type = "bat" || item.type = "cmd") { ; Icône CMD if FileExist(cmdPath) { hIcon := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", cmdPath, "UInt", 0, "Ptr") } else { hIcon := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", "shell32.dll", "UInt", 2, "Ptr") } } else { ; Icône du soft hIcon := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", item.chemin, "UInt", 0, "Ptr") if (hIcon <= 1) { hIcon := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", "shell32.dll", "UInt", 2, "Ptr") } } if (hIcon > 1) { DllCall("ImageList_AddIcon", "Ptr", hIL, "Ptr", hIcon, "Int") DllCall("DestroyIcon", "Ptr", hIcon) } } return hIL } ; Fonction pour créer le dossier de log s'il n'existe pas CreateLogFolder() { logDir := "C:\Geco\Log" if !DirExist(logDir) { try { DirCreate(logDir) } catch Error as e { MsgBox "Erreur lors de la création du dossier de log: " e.Message } } } ; Fonction pour écrire dans le log WriteLog(scriptName, status := "OK") { global logCheckbox, logPath if !logCheckbox.Value return CreateLogFolder() currentTime := FormatTime(A_Now, "dd/MM/yyyy HH:mm:ss") logMessage := currentTime " : " scriptName " - " status "`n" try { FileAppend(logMessage, logPath, "UTF-8") } catch Error as e { MsgBox "Erreur lors de l'écriture du log: " e.Message } } ; Fonction pour analyser les métadonnées des scripts ParseMetadata(filePath) { local fileHandle := FileOpen(filePath, "r", "UTF-8") if !fileHandle return false SplitPath(filePath, , , &ext) isBatch := (ext = "bat" || ext = "cmd") meta := Map("Nom", "", "Version", "", "Description", "", "Categorie", "", "Ordre", "50") lineNum := 0 while !fileHandle.AtEOF { line := Trim(fileHandle.ReadLine()) lineNum++ if isBatch { if InStr(line, "REM Nom:") { meta["Nom"] := RegExReplace(line, "^\s*REM\s*Nom:\s*", "") } else if InStr(line, "REM Description:") { meta["Description"] := RegExReplace(line, "^\s*REM\s*Description:\s*", "") } else if InStr(line, "REM Version:") { meta["Version"] := RegExReplace(line, "^\s*REM\s*Version:\s*", "") } else if InStr(line, "REM Categorie:") { meta["Categorie"] := RegExReplace(line, "^\s*REM\s*Categorie:\s*", "") } else if InStr(line, "REM Ordre:") { meta["Ordre"] := RegExReplace(line, "^\s*REM\s*Ordre:\s*", "") } } else { if InStr(line, "# Nom:") { meta["Nom"] := RegExReplace(line, "^\s*#\s*Nom:\s*", "") } else if InStr(line, "# Description:") { meta["Description"] := RegExReplace(line, "^\s*#\s*Description:\s*", "") } else if InStr(line, "# Version:") { meta["Version"] := RegExReplace(line, "^\s*#\s*Version:\s*", "") } else if InStr(line, "# Categorie:") { meta["Categorie"] := RegExReplace(line, "^\s*#\s*Categorie:\s*", "") } else if InStr(line, "# Ordre:") { meta["Ordre"] := RegExReplace(line, "^\s*#\s*Ordre:\s*", "") } } if meta["Nom"] && meta["Version"] && meta["Description"] && meta["Categorie"] && meta["Ordre"] != "50" break ; Limiter la lecture aux 30 premières lignes (les métadonnées sont en début de fichier) if lineNum >= 30 break } fileHandle.Close() return meta["Nom"] ? meta : false } ; Fonction pour trouver le chemin complet d'un script par son nom et sa catégorie FindScriptPath(scriptName, category) { global scriptsPath ; Chercher dans les fichiers PowerShell Loop Files scriptsPath "\*.ps1", "F" { meta := ParseMetadata(A_LoopFileFullPath) if meta && meta["Nom"] = scriptName { categoriesList := StrSplit(meta["Categorie"], ";") for _, cat in categoriesList { if Trim(cat) = category { return A_LoopFileFullPath } } } } ; Chercher dans les fichiers batch Loop Files scriptsPath "\*.bat", "F" { meta := ParseMetadata(A_LoopFileFullPath) if meta && meta["Nom"] = scriptName { categoriesList := StrSplit(meta["Categorie"], ";") for _, cat in categoriesList { if Trim(cat) = category { return A_LoopFileFullPath } } } } ; Chercher dans les fichiers cmd Loop Files scriptsPath "\*.cmd", "F" { meta := ParseMetadata(A_LoopFileFullPath) if meta && meta["Nom"] = scriptName { categoriesList := StrSplit(meta["Categorie"], ";") for _, cat in categoriesList { if Trim(cat) = category { return A_LoopFileFullPath } } } } return "" } ; ============================================================================= ; Obtenir toutes les catégories ; ============================================================================= categories := GetAllCategories(scriptsPath) if categories.Length = 0 { MsgBox "Aucune catégorie trouvée dans les scripts. Assurez-vous que vos scripts contiennent une ligne 'REM Categorie:' ou '# Categorie:'." ExitApp } ; ============================================================================= ; Interface graphique ; ============================================================================= myGui := Gui("Resize", "Lanceur de scripts v1") myGui.SetFont("s" fontSize) btnList := Map() ; Calcul des positions dynamiques lvX := categoryWidth + 30 lvWidth := winWidth - categoryWidth - 190 lvHeight := winHeight - 220 btnY := 40 + lvHeight + 10 ; Groupe des catégories avec ListView categoryGroup := myGui.Add("GroupBox", "x10 y10 w" categoryWidth " h" (winHeight - 165), "Catégories") ; Barre de recherche myGui.Add("Text", "x15 y28 w" (categoryWidth - 10), "🔍 Recherche:") searchEdit := myGui.Add("Edit", "x15 y46 w" (categoryWidth - 10) " h22") searchEdit.OnEvent("Change", OnSearchChange) categoryLV := myGui.Add("ListView", "x15 y72 w" (categoryWidth - 10) " h" (winHeight - 230) " -Multi -Hdr", ["Catégorie"]) categoryLV.SetFont("s" fontSize) ; Ajouter la catégorie spéciale "Softs" en premier categoryLV.Add(, "📦 Softs") ; Ajouter les catégories de scripts for category in categories { categoryLV.Add(, category) } categoryLV.OnEvent("ItemSelect", OnCategorySelect) ; Créer le fichier softs.ini par défaut s'il n'existe pas CreateDefaultSoftsIni() myGui.Add("Text", "x" lvX " y10 w" lvWidth " Center", "Cliquez sur un script pour le lancer ou cochez pour lancer en lot.") ; ListView principal avec cases à cocher lv := myGui.Add("ListView", "x" lvX " y40 w" lvWidth " h" lvHeight " Checked grid", ["", "Nom", "Description", "Version", "Ordre"]) lv.SetFont("s" fontSize) lv.OnEvent("DoubleClick", LaunchScript) lv.OnEvent("ContextMenu", ShowContextMenu) ; Augmenter la hauteur des lignes pour plus de lisibilité SetListViewRowHeight(lv, compactMode ? 20 : 24) ; Même chose pour le ListView des catégories SetListViewRowHeight(categoryLV, compactMode ? 18 : 22) ; Boutons sous le ListView launchSelectedBtn := myGui.Add("Button", "x" lvX " y" btnY " w180 h28", "Lancer les scripts cochés") launchSelectedBtn.OnEvent("Click", LaunchSelectedScripts) selectAllCheckbox := myGui.Add("Checkbox", "x" (lvX + 190) " y" btnY " w110 h28", "Tout sélectionner") selectAllCheckbox.OnEvent("Click", ToggleSelectAll) logCheckbox := myGui.Add("Checkbox", "x" (lvX + 310) " y" btnY " w90 h28", "Activer log") logCheckbox.OnEvent("Click", LogCheckboxClick) ; ============================================================================= ; Boutons système ; ============================================================================= spacing := btnSpacing sysBtnX := winWidth - 145 sysBtnY := 40 sysBtnWidth := compactMode ? 120 : 140 sysBtnHeight := compactMode ? 32 : 40 systemButtons := [ ["Gest. périphériques", OpenDeviceManager], ["Gestion alimentation", OpenPowerSettings], ["Msinfo32", OpenMsinfo], ["Panneau de conf", OpenControl], ["Extensions fichiers`n", ToggleExtensions], ["Fichiers cachés`n", ToggleHiddenFiles], ["Gest. de tâches", OpenTaskManager] ] for each, pair in systemButtons { btn := myGui.Add("Button", "x" sysBtnX " y" sysBtnY " w" sysBtnWidth " h" sysBtnHeight, pair[1]) btn.OnEvent("Click", pair[2]) systemBtnList.Push(btn) sysBtnY += spacing } extensionsBtn := systemBtnList[5] hiddenFilesBtn := systemBtnList[6] ; Fonction pour mettre à jour l'état des boutons UpdateButtonStates() { global extensionsBtn, hiddenFilesBtn, fontSize regPath := "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" ; Vérifier l'état des extensions hideExtValue := SafeRegRead(regPath, "HideFileExt", 1) if (hideExtValue = 1) { extensionsBtn.Text := "Extensions fichiers`nDésactivé" extensionsBtn.SetFont("s" fontSize " cRed") } else { extensionsBtn.Text := "Extensions fichiers`nActivé" extensionsBtn.SetFont("s" fontSize " cGreen") } ; Vérifier l'état des fichiers cachés hiddenValue := SafeRegRead(regPath, "Hidden", 2) if (hiddenValue = 2) { hiddenFilesBtn.Text := "Fichiers cachés`nDésactivé" hiddenFilesBtn.SetFont("s" fontSize " cRed") } else { hiddenFilesBtn.Text := "Fichiers cachés`nActivé" hiddenFilesBtn.SetFont("s" fontSize " cGreen") } } ; Bouton Licence Geco btn := myGui.Add("Button", "x" sysBtnX " y" sysBtnY " w" sysBtnWidth " h" sysBtnHeight, "Licence Geco") btn.OnEvent("Click", OpenLicence) systemBtnList.Push(btn) ; Bouton SOFT btn := myGui.Add("Button", "x" sysBtnX " y" (sysBtnY + spacing) " w" sysBtnWidth " h" sysBtnHeight, "SOFT") btn.OnEvent("Click", OpenSoftFolder) systemBtnList.Push(btn) ; Bouton Quitter (rouge) quitBtn := myGui.Add("Button", "x" sysBtnX " y" (sysBtnY + spacing * 2) " w" sysBtnWidth " h" sysBtnHeight, "Quitter") quitBtn.SetFont("s" fontSize " cWhite Bold") quitBtn.Opt("+Background0xCC0000") ; Rouge foncé quitBtn.OnEvent("Click", (*) => ExitApp()) systemBtnList.Push(quitBtn) ; ============================================================================= ; Fonctions pour les boutons système ; ============================================================================= OpenSoftFolder(*) { scriptFullPath := A_ScriptFullPath SplitPath(scriptFullPath, , ¤tScriptDir) usbRoot := RegExReplace(currentScriptDir, "\\[^\\]+$", "") softPath := usbRoot "\SOFT" if DirExist(softPath) { Run "explorer.exe /select,`"" softPath "`"" } else { Loop 26 { driveLetter := Chr(64 + A_Index) testPath := driveLetter ":\SOFT" if DirExist(testPath) { Run "explorer.exe `"" testPath "`"" return } } MsgBox "Le dossier SOFT n'a pas été trouvé sur la clé USB ou sur les lecteurs disponibles." } } OpenDeviceManager(*) { Run "devmgmt.msc" } OpenPowerSettings(*) { Run "powercfg.cpl" } OpenMsinfo(*) { Run "msinfo32" } OpenControl(*) { Run "control" } OpenTaskManager(*) { Run "taskmgr.exe" } ToggleExtensions(*) { regPath := "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" regValue := "HideFileExt" current := SafeRegRead(regPath, regValue, 1) newValue := current = 1 ? 0 : 1 RegWrite newValue, "REG_DWORD", regPath, regValue SendMessage(0x1A, 0, StrPtr("Environment"), , "ahk_class Progman") UpdateButtonStates() } ToggleHiddenFiles(*) { regPath := "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" regValue := "Hidden" current := SafeRegRead(regPath, regValue, 2) newValue := current = 2 ? 1 : 2 RegWrite newValue, "REG_DWORD", regPath, regValue SendMessage(0x1A, 0, StrPtr("Environment"), , "ahk_class Progman") UpdateButtonStates() } OpenLicence(*) { global licencePath if FileExist(licencePath) Run '"' licencePath '"' else MsgBox "Le fichier 'Licence Geco.txt' est introuvable à l'emplacement attendu:`n" licencePath } ; ============================================================================= ; Gestion des événements GUI ; ============================================================================= myGui.OnEvent("Size", GuiResize) GuiResize(thisGui, MinMax, Width, Height) { global categoryGroup, categoryLV, sysInfoGroup, lv, cpuText, ramText, osText global computerText, ipText, secureBootText, motherboardText, systemBtnList global launchSelectedBtn, selectAllCheckbox, logCheckbox global categoryWidth, btnSpacing, sysInfoHeight, compactMode, lvX if (MinMax = -1) return ; Hauteur du groupe catégories (s'arrête avant les infos système) categoryGroup.Move(, , , Height - 165) categoryLV.Move(, , , Height - 230) lvNewWidth := Width - categoryWidth - 190 lvNewHeight := Height - 220 lv.Move(, , lvNewWidth, lvNewHeight) newBtnY := 40 + lvNewHeight + 10 launchSelectedBtn.Move(lvX, newBtnY) selectAllCheckbox.Move(lvX + 190, newBtnY) logCheckbox.Move(lvX + 310, newBtnY) startY := 40 for index, sysBtn in systemBtnList { sysBtn.Move(Width - 145, startY) startY += btnSpacing } sysInfoGroup.Move(10, Height - sysInfoHeight - 30, Width - 20, sysInfoHeight) cpuText.Move(20, Height - sysInfoHeight - 10) ramText.Move(20, Height - sysInfoHeight + 10) osText.Move(20, Height - sysInfoHeight + 30) computerText.Move(Width / 2, Height - sysInfoHeight - 10) ipText.Move(Width / 2, Height - sysInfoHeight + 10) secureBootText.Move(Width / 2, Height - sysInfoHeight + 30) motherboardText.Move(20, Height - sysInfoHeight + 50) AdjustColumns(lvNewWidth) } AdjustColumns(totalWidth) { global lv totalWidth := totalWidth - 5 col1Width := Floor(totalWidth * 0.05) ; Icône col2Width := Floor(totalWidth * 0.24) ; Nom col3Width := Floor(totalWidth * 0.50) ; Description col4Width := Floor(totalWidth * 0.10) ; Version col5Width := Floor(totalWidth * 0.08) ; Ordre lv.ModifyCol(1, col1Width) lv.ModifyCol(2, col2Width) lv.ModifyCol(3, col3Width) lv.ModifyCol(4, col4Width) lv.ModifyCol(5, col5Width " Center") ; Centrer l'ordre } ; ============================================================================= ; Gestion des catégories et scripts ; ============================================================================= OnCategorySelect(LV, Item, Selected) { if Selected { categoryName := LV.GetText(Item, 1) ShowCategory(categoryName) } } ShowCategory(categoryName, *) { global selectedCategory, selectAllCheckbox, isSoftsCategory selectedCategory := categoryName ; Vérifier si c'est la catégorie Softs if (categoryName = "📦 Softs") { isSoftsCategory := true RefreshSoftsList() } else { isSoftsCategory := false RefreshList(categoryName) } selectAllCheckbox.Value := 0 } RefreshList(category) { global scriptsPath, lv lv.Delete() scripts := [] ; Collecter tous les scripts PS1 de cette catégorie Loop Files scriptsPath "\*.ps1", "F" { data := ParseMetadata(A_LoopFileFullPath) if data && data.Has("Categorie") { categoriesList := StrSplit(data["Categorie"], ";") for _, cat in categoriesList { if Trim(cat) = category { scripts.Push({ nom: data.Get("Nom"), description: data.Get("Description"), version: data.Get("Version"), ordre: data.Get("Ordre", "50"), type: "ps1" }) break } } } } ; Collecter tous les scripts BAT/CMD de cette catégorie Loop Files scriptsPath "\*.bat", "F" { data := ParseMetadata(A_LoopFileFullPath) if data && data.Has("Categorie") { categoriesList := StrSplit(data["Categorie"], ";") for _, cat in categoriesList { if Trim(cat) = category { scripts.Push({ nom: data.Get("Nom"), description: data.Get("Description"), version: data.Get("Version"), ordre: data.Get("Ordre", "50"), type: "bat" }) break } } } } Loop Files scriptsPath "\*.cmd", "F" { data := ParseMetadata(A_LoopFileFullPath) if data && data.Has("Categorie") { categoriesList := StrSplit(data["Categorie"], ";") for _, cat in categoriesList { if Trim(cat) = category { scripts.Push({ nom: data.Get("Nom"), description: data.Get("Description"), version: data.Get("Version"), ordre: data.Get("Ordre", "50"), type: "cmd" }) break } } } } scripts := SortScripts(scripts) ; Créer l'ImageList pour les icônes de scripts hIL := CreateScriptsImageList() SendMessage(0x1003, 1, hIL, lv.Hwnd) ; LVM_SETIMAGELIST, LVSIL_SMALL ; Ajouter les scripts avec leurs icônes for script in scripts { ; Icon1 = PowerShell (bleu), Icon2 = CMD/BAT (noir) iconIndex := (script.type = "ps1") ? 1 : 2 lv.Add("Icon" iconIndex, , script.nom, script.description, script.version, script.ordre) } } ; Créer l'ImageList pour les icônes CMD et PowerShell CreateScriptsImageList() { ; Créer une ImageList 20x20 hIL := DllCall("ImageList_Create", "Int", 20, "Int", 20, "UInt", 0x21, "Int", 2, "Int", 2, "Ptr") ; Icône PowerShell (depuis powershell.exe) psPath := A_WinDir "\System32\WindowsPowerShell\v1.0\powershell.exe" if FileExist(psPath) { hIconPS := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", psPath, "UInt", 0, "Ptr") } else { ; Icône par défaut si PowerShell non trouvé hIconPS := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", "shell32.dll", "UInt", 71, "Ptr") } if (hIconPS > 1) { DllCall("ImageList_AddIcon", "Ptr", hIL, "Ptr", hIconPS, "Int") DllCall("DestroyIcon", "Ptr", hIconPS) } ; Icône CMD (depuis cmd.exe) cmdPath := A_WinDir "\System32\cmd.exe" if FileExist(cmdPath) { hIconCMD := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", cmdPath, "UInt", 0, "Ptr") } else { ; Icône par défaut si CMD non trouvé hIconCMD := DllCall("Shell32\ExtractIcon", "Ptr", 0, "Str", "shell32.dll", "UInt", 2, "Ptr") } if (hIconCMD > 1) { DllCall("ImageList_AddIcon", "Ptr", hIL, "Ptr", hIconCMD, "Int") DllCall("DestroyIcon", "Ptr", hIconCMD) } return hIL } ; ============================================================================= ; Menu contextuel ; ============================================================================= ShowContextMenu(GuiCtrlObj, Item, IsRightClick, X, Y) { global isSoftsCategory, softsList if !IsRightClick || !Item return lv.Modify(Item, "Select") contextMenu := Menu() ; Menu différent selon si on est dans Softs ou non if isSoftsCategory { contextMenu.Add("Lancer en admin", (*) => LaunchSoftFromMenu(Item)) contextMenu.Add("Ouvrir l'emplacement", (*) => OpenSoftLocation(Item)) contextMenu.Add() ; Séparateur contextMenu.Add("Éditer softs.ini", (*) => EditSoftsIni()) contextMenu.Add("Rafraîchir la liste", (*) => RefreshSoftsList()) } else { contextMenu.Add("Éditer le script", (*) => EditScript(Item)) contextMenu.Add("Copier le script sur le PC", (*) => CopyScriptToPC(Item)) } contextMenu.Show() } ; Lancer un soft depuis le menu contextuel LaunchSoftFromMenu(itemIndex) { global softsList if (itemIndex <= softsList.Length) { LaunchSoftAsAdmin(softsList[itemIndex].chemin) } } ; Ouvrir l'emplacement du soft dans l'explorateur OpenSoftLocation(itemIndex) { global softsList if (itemIndex <= softsList.Length) { softPath := softsList[itemIndex].chemin Run 'explorer.exe /select,"' softPath '"' } } CopyScriptToPC(itemIndex) { global selectedCategory, scriptsPath nom := lv.GetText(itemIndex, 2) if !nom return sourceFile := FindScriptPath(nom, selectedCategory) if !sourceFile { MsgBox "Script non trouvé: " nom return } destFolder := DirSelect("*" A_Desktop, 3, "Choisir le dossier de destination") if !destFolder return SplitPath(sourceFile, &fileName) destFile := destFolder "\" fileName try { FileCopy(sourceFile, destFile, 1) MsgBox "Script copié avec succès vers:`n" destFile, "Copie réussie" WriteLog("Copie de " nom " vers " destFile, "OK") } catch Error as e { MsgBox "Erreur lors de la copie:`n" e.Message, "Erreur" WriteLog("Copie de " nom, "ERREUR") } } EditScript(itemIndex) { global selectedCategory, scriptsPath nom := lv.GetText(itemIndex, 2) if !nom return scriptFile := FindScriptPath(nom, selectedCategory) if !scriptFile { MsgBox "Script non trouvé: " nom return } SplitPath(scriptFile, , , &ext) isPs1 := (ext = "ps1") try { if isPs1 { if FileExist(A_WinDir "\System32\WindowsPowerShell\v1.0\powershell_ise.exe") { Run A_WinDir "\System32\WindowsPowerShell\v1.0\powershell_ise.exe -File `"" scriptFile "`"" } else { Run "notepad.exe `"" scriptFile "`"" } } else { Run "notepad.exe `"" scriptFile "`"" } WriteLog("Édition de " nom, "OK") } catch Error as e { MsgBox "Erreur lors de l'ouverture de l'éditeur: " e.Message WriteLog("Édition de " nom, "ERREUR") } } ; ============================================================================= ; Sélection et lancement des scripts ; ============================================================================= LogCheckboxClick(*) { global logCheckbox if logCheckbox.Value { WriteLog("Logging activé", "INFO") } } ToggleSelectAll(*) { global lv, selectAllCheckbox isChecked := selectAllCheckbox.Value Loop lv.GetCount() { if isChecked { lv.Modify(A_Index, "Check") } else { lv.Modify(A_Index, "-Check") } } } LaunchScript(*) { global selectedCategory, isSoftsCategory, softsList, isSearchMode, searchResults idx := lv.GetNext() if !idx return nom := lv.GetText(idx, 2) ; Si on est en mode recherche if isSearchMode { if (idx <= searchResults.Length) { item := searchResults[idx] if (item.type = "soft") { LaunchSoftAsAdmin(item.chemin) } else { LaunchScriptByPath(item.chemin, item.type) } } return } ; Si c'est la catégorie Softs, lancer le soft if isSoftsCategory { if (idx <= softsList.Length) { LaunchSoftAsAdmin(softsList[idx].chemin) } return } LaunchScriptByName(nom) } LaunchScriptByName(nom) { global selectedCategory, scriptsPath scriptPath := FindScriptPath(nom, selectedCategory) if !scriptPath { MsgBox "Script non trouvé: " nom WriteLog(nom, "INTROUVABLE") return } SplitPath(scriptPath, , , &ext) if (ext = "ps1") { try { RunWait 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "' scriptPath '"' WriteLog(nom, "OK") } catch Error as e { WriteLog(nom, "ERREUR") MsgBox "Erreur lors de l'exécution du script: " e.Message } } else { try { RunWait '"' scriptPath '"' WriteLog(nom, "OK") } catch Error as e { WriteLog(nom, "ERREUR") MsgBox "Erreur lors de l'exécution du script: " e.Message } } } ; Lancer un script par son chemin direct (utilisé par la recherche) LaunchScriptByPath(scriptPath, scriptType) { if (scriptType = "ps1") { try { RunWait 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "' scriptPath '"' WriteLog(scriptPath, "OK") } catch Error as e { WriteLog(scriptPath, "ERREUR") MsgBox "Erreur lors de l'exécution du script: " e.Message } } else { try { RunWait '"' scriptPath '"' WriteLog(scriptPath, "OK") } catch Error as e { WriteLog(scriptPath, "ERREUR") MsgBox "Erreur lors de l'exécution du script: " e.Message } } } LaunchSelectedScripts(*) { global lv checkedScripts := [] Loop lv.GetCount() { if lv.GetNext(A_Index - 1, "Checked") = A_Index { scriptName := lv.GetText(A_Index, 2) if scriptName checkedScripts.Push(scriptName) } } if checkedScripts.Length = 0 { MsgBox "Aucun script sélectionné.", "Information" return } result := MsgBox("Voulez-vous lancer " checkedScripts.Length " script(s) sélectionné(s) ?", "Confirmation", "YesNo") if result = "No" return WriteLog("Lancement en lot de " checkedScripts.Length " script(s)", "INFO") for scriptName in checkedScripts { LaunchScriptByName(scriptName) } WriteLog("Fin du lancement en lot", "INFO") MsgBox "Tous les scripts sélectionnés ont été lancés.", "Information" } ; ============================================================================= ; Fonctions d'information système ; ============================================================================= GetCPUInfo() { try { for obj in ComObject("WbemScripting.SWbemLocator").ConnectServer(, "root\CIMV2").ExecQuery("SELECT Name FROM Win32_Processor") return obj.Name } catch { return "Information non disponible" } } GetRAMInfo() { try { totalRAM := 0 for obj in ComObject("WbemScripting.SWbemLocator").ConnectServer(, "root\CIMV2").ExecQuery("SELECT Capacity FROM Win32_PhysicalMemory") totalRAM += obj.Capacity return Format("{:.2f} Go", totalRAM / 1073741824) } catch { return "Information non disponible" } } GetOSInfo() { try { for obj in ComObject("WbemScripting.SWbemLocator").ConnectServer(, "root\CIMV2").ExecQuery("SELECT Caption, Version FROM Win32_OperatingSystem") return obj.Caption " (" obj.Version ")" } catch { return "Information non disponible" } } GetIPAddress() { try { for obj in ComObject("WbemScripting.SWbemLocator").ConnectServer(, "root\CIMV2").ExecQuery("SELECT IPAddress FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE") if IsObject(obj.IPAddress) return obj.IPAddress[0] } catch { return "Information non disponible" } return "Non connecté" } GetSecureBootStatus() { secureBootEnabled := SafeRegRead("HKLM\SYSTEM\CurrentControlSet\Control\SecureBoot\State", "UEFISecureBootEnabled", 2) if (secureBootEnabled = 1) return "Activé" else if (secureBootEnabled = 0) return "Désactivé" return "Non pris en charge" } GetMotherboardInfo() { try { for obj in ComObject("WbemScripting.SWbemLocator").ConnectServer(, "root\CIMV2").ExecQuery("SELECT Product FROM Win32_BaseBoard") return obj.Product } catch { return "Information non disponible" } } SetSecureBootColor(status) { global secureBootText if (status = "Activé") secureBootText.Opt("+c0x008000") ; Vert else if (status = "Désactivé") secureBootText.Opt("+c0xFF0000") ; Rouge else if (status = "Non pris en charge") secureBootText.Opt("+c0x0000FF") ; Bleu else secureBootText.Opt("+c0x000000") ; Noir par défaut } ; ============================================================================= ; Initialisation de l'interface ; ============================================================================= ; Charger le cache pour la recherche LoadAllItemsCache() ; Sélectionner automatiquement la catégorie "📦 Softs" (première dans la liste) categoryLV.Modify(1, "Select") ShowCategory("📦 Softs") ; Groupe informations système sysInfoY := winHeight - sysInfoHeight - 30 sysInfoGroup := myGui.Add("GroupBox", "x10 y" sysInfoY " w" (winWidth - 20) " h" sysInfoHeight, "Informations Système") sysInfoGroup.SetFont("s" fontSize " Bold") infoY1 := sysInfoY + 20 infoY2 := sysInfoY + 38 infoY3 := sysInfoY + 56 infoY4 := sysInfoY + 74 halfWidth := winWidth / 2 cpuText := myGui.Add("Text", "x20 y" infoY1 " w" (halfWidth - 30), "CPU: " GetCPUInfo()) ramText := myGui.Add("Text", "x20 y" infoY2 " w" (halfWidth - 30), "RAM: " GetRAMInfo()) osText := myGui.Add("Text", "x20 y" infoY3 " w" (halfWidth - 30), "OS: " GetOSInfo()) computerText := myGui.Add("Text", "x" halfWidth " y" infoY1 " w" (halfWidth - 30), "Nom PC: " A_ComputerName) ipText := myGui.Add("Text", "x" halfWidth " y" infoY2 " w" (halfWidth - 30), "Adresse IP: " GetIPAddress()) secureBootStatus := GetSecureBootStatus() secureBootText := myGui.Add("Text", "x" halfWidth " y" infoY3 " w" (halfWidth - 30), "Secure Boot: " secureBootStatus) SetSecureBootColor(secureBootStatus) if !compactMode { motherboardText := myGui.Add("Text", "x20 y" infoY4 " w" (winWidth - 40), "Carte Mère: " GetMotherboardInfo()) } else { motherboardText := myGui.Add("Text", "x20 y" infoY4 " w" (winWidth - 40), "") } ; Mise à jour de l'état des boutons et affichage UpdateButtonStates() myGui.Show("w" winWidth " h" winHeight)