1576 lines
49 KiB
AutoHotkey
1576 lines
49 KiB
AutoHotkey
#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)
|