Es ist in der Tat ein interessantes Phänomen, dass Ihr AutoHotkey v1-Skript scheinbar ohne Administratorrechte einen Registrierungsschlüssel unter HKEY_LOCAL_MACHINE
löschen kann, während Ihr v2-Skript dies nicht vermag und unterschiedliche Fehler meldet. Die Gründe hierfür liegen tief in den Unterschieden zwischen den AutoHotkey-Versionen, deren Umgang mit Windows-Sicherheitsmechanismen und der genauen Syntax der verwendeten Befehle.
HKEY_LOCAL_MACHINE
in einen benutzerspezifischen, virtuellen Speicher umleitet. Das Löschen erscheint erfolgreich, betrifft aber nicht den globalen Schlüssel.ErrorLevel
). Ohne Adminrechte wird der Zugriff verweigert.RegDelete()
mit einer Syntax, die dazu führt, dass es versucht, einen Wert an einem falschen Ort zu löschen, anstatt des gewünschten Schlüssels. Dies ist der Hauptgrund, warum es auch mit Adminrechten den "Schlüssel nicht findet".Das scheinbar erfolgreiche Löschen des Registrierungsschlüssels durch Ihr v1-Skript ohne explizite Administratorrechte ist primär auf die sogenannte UAC-Registrierungsvirtualisierung (User Account Control Virtualization) von Windows zurückzuführen.
Wenn ein Prozess ohne Administratorrechte versucht, in geschützte Bereiche der Registrierung zu schreiben (wie z.B. viele Unterschlüssel von HKEY_LOCAL_MACHINE
), leitet Windows diese Schreibvorgänge automatisch und transparent in einen benutzerspezifischen, virtualisierten Bereich um. Dieser befindet sich typischerweise unter HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\...
.
Ihr v1-Skript, das ohne erhöhte Rechte läuft, löscht also nicht den tatsächlichen, systemweiten Registrierungsschlüssel, sondern eine Kopie oder einen Eintrag im virtualisierten Speicher dieses Benutzers. Für das Skript selbst sieht es so aus, als wäre die Operation erfolgreich gewesen.
Abbildung: Die hierarchische Struktur der Windows-Registrierung, wobei HKEY_LOCAL_MACHINE systemweite Einstellungen enthält.
ErrorLevel
und die Bestätigung des ErfolgsNach dem RegDelete
-Befehl prüft Ihr v1-Skript ErrorLevel
. Da der Löschvorgang im virtualisierten Speicher (aus Sicht des Skripts) erfolgreich war, wird ErrorLevel
auf 0 gesetzt (oder einen Wert, der Erfolg signalisiert, je nach genauer AHK v1 Implementierung und Windows-Antwort auf den virtualisierten Schreibvorgang). Auch der nachfolgende RegRead
-Befehl würde zuerst im virtualisierten Speicher nachsehen und den Schlüssel dort nicht mehr finden, was die Annahme bestärkt, er sei gelöscht.
RegDelete
In AutoHotkey v1 lautet die Syntax RegDelete, RootKey, SubKey [, ValueName]
. Ihr v1-Code:
RegDelete, HKEY_LOCAL_MACHINE, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager\OneDrive!S-1-5-21-2521903504-3487558158-1517850901-1001!Business1|6c1348004bd841569fb5faed4854b4bb\UserSyncRoots
Hier ist HKEY_LOCAL_MACHINE
der RootKey
und der lange Pfad inklusive UserSyncRoots
der SubKey
. Wenn ValueName
weggelassen wird, zielt der Befehl darauf ab, den gesamten SubKey
(also den Schlüssel UserSyncRoots
und alle seine Werte und Unterschlüssel) zu löschen. Diese Syntax ist korrekt für die Absicht in v1.
Das Scheitern Ihres v2-Skripts hat mehrere Ursachen, die von grundlegenden Änderungen in AutoHotkey v2 bis hin zu einem spezifischen Syntaxfehler in Ihrem Code reichen.
AutoHotkey v2-Anwendungen sind oft so konfiguriert, dass sie weniger oder gar nicht von der automatischen UAC-Registrierungsvirtualisierung betroffen sind wie v1-Skripte. Ein Versuch, ohne Administratorrechte direkt in HKEY_LOCAL_MACHINE
zu schreiben oder zu löschen, führt daher korrekterweise zu einem "Zugriff verweigert"-Fehler, da das Betriebssystem den direkten Zugriff auf diesen geschützten Bereich blockiert.
RegDelete()
in v2Dies ist der kritischste Punkt für das Verhalten Ihres v2-Skripts. Die Funktion RegDelete()
in AutoHotkey v2 hat die folgende grundlegende Signatur: RegDelete(KeyName [, ValueName])
.
KeyName
) übergeben werden, und der zweite Parameter (ValueName
) wird weggelassen.KeyName
und der Name des zu löschenden Wertes als ValueName
übergeben.ValueName
weggelassen wird oder ein leerer String ist, wird der Standardwert des als KeyName
angegebenen Schlüssels gelöscht.Ihr v2-Skript verwendet:
RegDelete("HKEY_LOCAL_MACHINE", "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager\OneDrive!S-1-5-21-2521903504-3487558158-1517850901-1001!Business1|6c1348004bd841569fb5faed4854b4bb\UserSyncRoots")
Hier interpretiert AutoHotkey v2:
KeyName
als "HKEY_LOCAL_MACHINE"
ValueName
als den gesamten langen Pfadstring "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager\OneDrive!S-1-5-21-...\UserSyncRoots"
Das Skript versucht also, einen Wert mit dem sehr langen Namen "SOFTWARE\..."
direkt unter HKEY_LOCAL_MACHINE
zu löschen. Ein solcher Wert existiert höchstwahrscheinlich nicht. Dies erklärt, warum das Skript auch mit Administratorrechten den "Schlüssel nicht findet" – es sucht nach einem nicht existenten Wert an der falschen Stelle, nicht nach dem Schlüssel UserSyncRoots
an seinem korrekten Ort.
Die korrekte Syntax in v2, um den Schlüssel UserSyncRoots
zu löschen, wäre:
RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager\OneDrive!S-1-5-21-2521903504-3487558158-1517850901-1001!Business1|6c1348004bd841569fb5faed4854b4bb\UserSyncRoots")
(Beachten Sie, dass der gesamte Pfad zum Schlüssel als erster Parameter übergeben wird und der zweite Parameter fehlt.)
AutoHotkey v2 verwendet für die Fehlerbehandlung Exceptions anstelle von ErrorLevel
. Wenn eine Operation wie RegDelete()
fehlschlägt (z.B. wegen fehlender Berechtigungen oder weil das Ziel nicht gefunden wurde), wird eine Exception ausgelöst, die mit einem try...catch
-Block abgefangen werden kann, wie Sie es in Ihrem v2-Skript korrekt tun. Dies führt zu einer expliziteren Fehlermeldung.
Die folgende Tabelle fasst die wichtigsten Unterschiede zusammen, die das Verhalten Ihres Skripts beeinflussen:
Aspekt | AutoHotkey v1 | AutoHotkey v2 |
---|---|---|
RegDelete Syntax (Schlüssel löschen) |
RegDelete, RootKey, SubKeyToDelete |
RegDelete("Full\Path\To\KeyToDelete") |
Interpretation von RegDelete, HK..., "Path..." |
Löscht Schlüssel "Path..." unter HK... | (Bei RegDelete("HK...", "Path...") ) Löscht Wert "Path..." unter "HK...", nicht den Schlüssel "Path...". |
Fehlerbehandlung | Setzt ErrorLevel |
Wirft Exceptions (Ausnahmen) |
UAC-Registrierungsvirtualisierung | Profitiert oft davon bei Nicht-Admin-Ausführung (Umleitung in virtuellen Speicher) | Weniger/keine automatische Virtualisierung; direkterer Zugriff |
Adminrechte-Erfordernis für HKEY_LOCAL_MACHINE |
Prinzipiell ja, aber durch Virtualisierung oft "umgangen" | Ja, für tatsächliche Änderungen erforderlich |
Dieses Diagramm visualisiert verschiedene Faktoren und wie sie sich auf das Verhalten Ihrer Skripte in v1 und v2 (Original und korrigiert) auswirken. Die Werte reichen von 1 (problematisch/niedrig) bis 5 (korrekt/hoch).
Wie Sie sehen, ist die "Syntaxkorrektheit" und "Zielpfad-Interpretation" bei Ihrem originalen v2-Skript niedrig bewertet, was die Hauptprobleme aufzeigt. Ein korrigiertes v2-Skript mit Adminrechten würde in diesen Bereichen punkten.
Diese Mindmap verdeutlicht die zentralen Unterschiede zwischen AutoHotkey v1 und v2 im Kontext Ihres Problems und wie diese zu den unterschiedlichen Ergebnissen führen.
Um Ihr AutoHotkey v2-Skript funktionsfähig zu machen, sodass es den gewünschten Registrierungsschlüssel tatsächlich löscht, sind folgende Anpassungen notwendig:
RegDelete
-SyntaxPassen Sie den Aufruf von RegDelete()
an, sodass der vollständige Pfad des zu löschenden Schlüssels als erster und einziger Parameter übergeben wird (wenn Sie den gesamten Schlüssel löschen möchten):
DeleteRegistryWord2003_v2_corrected()
{
local keyPath := "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager\OneDrive!S-1-5-21-2521903504-3487558158-1517850901-1001!Business1|6c1348004bd841569fb5faed4854b4bb\UserSyncRoots"
; Tooltip before deleting the key
ToolTip "Prüfe und lösche Registrierungsschlüssel UserSyncRoots (v2 korrigiert)..."
Sleep 2000
try {
RegDelete(keyPath) ; Korrigierte Syntax
; If deletion succeeds, check if the key is really gone
try {
RegRead(keyPath) ; RegRead benötigt nur den KeyPath, um dessen Existenz/Standardwert zu prüfen
ToolTip "Error: Schlüssel existiert immer noch nach Löschversuch!"
} catch { ; ObjectNotfoundError oder ähnliches wird erwartet, wenn der Schlüssel weg ist
ToolTip "Success: Schlüssel wurde erfolgreich gelöscht und ist nicht mehr vorhanden!"
}
} catch as e {
ToolTip "Error beim Löschen des Schlüssels: " . e.Message . " (Stellen Sie sicher, dass das Skript als Administrator ausgeführt wird)"
}
Sleep 2000
ToolTip
}
Hinweis: In Ihrem ursprünglichen v2-Code haben Sie RegRead("HKEY_LOCAL_MACHINE", "SOFTWARE\...")
verwendet, was ebenfalls einen Wert liest. Um zu prüfen, ob ein Schlüssel existiert oder dessen Standardwert zu lesen, genügt es, RegRead(keyPath)
zu verwenden. Wenn der Schlüssel nicht existiert, löst RegRead
eine Ausnahme aus, die im catch
-Block aufgefangen wird, was den Erfolg des Löschens bestätigt.
Da Sie einen Schlüssel unter HKEY_LOCAL_MACHINE
modifizieren möchten, benötigt Ihr Skript Administratorrechte. Sie können dies sicherstellen, indem Sie:
#Requires Admin
hinzufügen. AutoHotkey wird dann beim Start versuchen, erhöhte Rechte anzufordern.In seltenen Fällen können Unterschiede zwischen der 32-Bit- und 64-Bit-Ansicht der Registrierung eine Rolle spielen, insbesondere wenn Skripte als 32-Bit-Prozesse auf einem 64-Bit-System laufen (oder umgekehrt) und auf Schlüssel zugreifen, die nur in einer bestimmten Ansicht existieren. Falls nach der Syntaxkorrektur und mit Adminrechten immer noch Probleme auftreten, könnten Sie die Funktion SetRegView
in Betracht ziehen (z.B. SetRegView(64)
oder SetRegView(32)
vor dem Registrierungszugriff), um explizit die gewünschte Ansicht festzulegen. Für den von Ihnen angegebenen Schlüsselpfad ist dies aber üblicherweise nicht das Hauptproblem.
Die Unterschiede zwischen AutoHotkey v1 und v2 sind vielfältig und gehen über reine Syntaxänderungen hinaus. Das folgende Video gibt einen allgemeinen Einblick, wie man mit beiden Versionen arbeiten kann, was beim Umstieg hilfreich sein kann:
Dieses Video erläutert, wie man Skripte in AutoHotkey v1 und v2 ausführt und Dateiendungen (.ahk vs. .ahk2) nutzen kann, um beide Versionen parallel zu verwenden.