Ich wollte nur kurz anmerken, dass schon eine Version AutoItObject v.1.2.2.0 draußen ist.
Was hat sich dort eigentlich verändert? Sind die im Anfangsthread erwähnten Schwierigkeiten dadurch behoben?
Ich wollte nur kurz anmerken, dass schon eine Version AutoItObject v.1.2.2.0 draußen ist.
Was hat sich dort eigentlich verändert? Sind die im Anfangsthread erwähnten Schwierigkeiten dadurch behoben?
Hi, ich habe das bereits gelöst
Siehe die Kontextmenü-Datei: https://autoit.de/index.php/Thre…ktive-Directory
Wow, richtig genial
Wenn ich aus der Variable jetzt noch ein Objekt mit Methoden und Attributen machen könnte wäre AutoIt so ziemlich perfekt, d.h. dass die Variable noch einmal getrennt ansprechbare Eigenschaften und Funktionen enthält. Ich habe irgendwo gelesen, dass es Ansätze in AutoIt gibt, Klassen und Objekte nachzubilden. Weißt du darüber etwas?
PS: Wie lange ist eigentlich die Zeit bis ich aus dem Forum ausgeloggt werde? Irgendwie werde ich nach dem Schließen der Seite nach einigen Minuten ausgeloggt...
Was hältst du von meiner Regel-Funktion? Mein Hintergedanke war, dass dadurch jeder selbst die Regeln erstellen kann, auf deren Basis die Eingrenzung stattfindet.
Welche Befehle eignen sich bei String-Einfüge und -Löschoperationen besonders? StringRegexp? StrInStr?
Der String muss bei jeder Operation neu erstellt werden oder?
Hi, damit lässt sich einiges machen. Vielen Dank
Du hast ja das Skript in verschiedene Bereiche durch +++ aufgeteilt. Dazu könnte ich dir auch #region und #endregion empfehlen und mit Strg+T räumt ein automatisches Clean-Up programm das Skript auf: Es fügt Tabs vor den Befehlen ein und entfernt überflüssige, damit sie an der richtigen Stelle stehen, fügt Leerzeichen hinzu bei den Gleichheitszeichen etc. Gibt einige nützliche Funktionen. Was ich besonders hilfreich finde: Es legt eine Backup-Kopie des Skripts in einem Unterordner an bei jedem Durchlauf.
Meint ihr mit Dictionary bestimmte Schlüsselworte und wo diese im String zu finden sind (Position)?
Genial fände ich es, wenn das Skript auch noch zu BugFix kompatibel ist. Er schreibt ja "0|Autos" & @CRLF & "0.1|Oldies" & @CRLF
Gibt es eine Funktion, die Items an eine festgelegte Position im Tree hinzufügt oder löscht? Bei der Einfüge-/Lösch-Operation müsste ja manchmal der ganze Baum umgeschrieben werden oder?
Ich würde gerne einrichten, dass nur bestimmte Objekte als Item in den Tree aufgenommen werden, z.B. nur Ordner und Vernküpfungen. Ist es sinnvoller dies durch eine Regel-Funktion zu entscheiden oder durch eine Untersuchung des fertigen Strings?
Beispielsweise habe ich dieses Skript hier erstellt:
; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +
#include <Misc.au3>
#include <MsgBoxConstants.au3>
Global Enum $TREE_NONE = -1, $TREE_STRING, $TREE_ARRAY, $TREE_DICTIONARY, $TREE_MAP
[/autoit] [autoit][/autoit] [autoit]; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +
[/autoit] [autoit][/autoit] [autoit]Func _Tree_Mode($iMode = -1)
Local Static $iVar = -1
$iVar = (($iMode <> -1) ? ($iMode) : ($iVar))
Return $iVar
EndFunc ;==>_Tree_Mode
Func _Tree_Dir($sPath, $iLevel = -1)
Switch _Tree_Mode()
Case $TREE_NONE
MsgBox($MB_ICONERROR + $MB_TOPMOST, 'ACHTUNG', 'Die zu benutzende Methode für die Baumstruktur (String, Array, Dictionary oder Map) vorab auswählen!')
Exit
Case $TREE_STRING
Return __Tree_DirString($sPath, $iLevel)
Case $TREE_ARRAY
Return __Tree_DirArray($sPath, $iLevel)
Case $TREE_DICTIONARY
Case $TREE_MAP
EndSwitch
EndFunc ;==>_Tree_Dir
; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +
[/autoit] [autoit][/autoit] [autoit]Func __Tree_DirString($sPath, $iLevel)
Local $vTOne = __Tree_GetNextPath($sPath, 'Regulator')
Local $vTTwo, $sRet
If $iLevel And $vTOne <> -1 Then
While $vTOne <> -1
$sRet &= $iLevel & ' | ' & $vTOne & @CRLF
$vTTwo = __Tree_DirString($vTOne & '\', $iLevel - 1)
$vTOne = (($vTTwo <> -1) ? ($vTTwo) : (__Tree_GetNextPath($sPath, 'Regulator')))
WEnd
Else
Return -1
EndIf
Return StringTrimRight($sRet, 2)
EndFunc ;==>__Tree_DirString
Func __Tree_DirArray($sPath, $iLevel)
Local $avTree[1] = [0]
Local $vTOne = __Tree_GetNextPath($sPath, 'Regulator')
Local $vTTwo
If $iLevel And $vTOne <> -1 Then
While $vTOne <> -1
ReDim $avTree[$avTree[0] + 2]
$avTree[0] += 1
$avTree[$avTree[0]] = $vTOne
$vTTwo = __Tree_DirArray($vTOne & '\', $iLevel - 1)
$vTOne = (($vTTwo <> -1) ? ($vTTwo) : (__Tree_GetNextPath($sPath, 'Regulator')))
WEnd
Else
Return -1
EndIf
Return $avTree
EndFunc ;==>__Tree_DirArray
Func __Tree_DirDictionary($sPath, $iLevel)
EndFunc ;==>__Tree_DirDictionary
Func __Tree_DirMap($sPath, $iLevel)
If _VersionCompare(@AutoItVersion, '3.3.13.6') = -1 Then
MsgBox($MB_ICONERROR + $MB_TOPMOST, 'ACHTUNG', 'Zum benutzen der Map-Funktionen wird mindestens die AutoIt Version 3.3.13.6 (Beta) benötigt! Alternativ das Dictionary Objekt verwenden...')
Exit
EndIf
EndFunc ;==>__Tree_DirMap
; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +
[/autoit] [autoit][/autoit] [autoit]Func __Tree_GetNextPath($sPath, $sRegelfunktion, $bClose = False)
Local Static $avPath[1][2] = [[0, 0]]
Do
Local $i, $iFree, $iPos, $sRet, $bRetOK
For $i = 1 To $avPath[0][0]
If Not $iFree And Not $avPath[$i][0] Then $iFree = $i
If $avPath[$i][0] = $sPath Then
$iPos = $i
$i = $avPath[0][0]
EndIf
Next
If Not $iPos Then
If $iFree Then
$iPos = $iFree
Else
ReDim $avPath[$avPath[0][0] + 2][2]
$avPath[0][0] += 1
$iPos = $avPath[0][0]
EndIf
$avPath[$iPos][0] = $sPath
$avPath[$iPos][1] = FileFindFirstFile($sPath & '*')
EndIf
If $bClose Then
FileClose($avPath[$iPos][1])
$avPath[$iPos][0] = ''
Return -1
EndIf
$sRet = FileFindNextFile($avPath[$iPos][1]) ;Gibt gefundene Objekte zurück
If @error Then Return __Tree_GetNextPath($avPath[$iPos][0], $sRegelfunktion, True) ;Bricht ab, wenn alles gescannt ist
$bRetOK = Call($sRegelfunktion, $sPath, $sRet, @extended) ;Ruft Regelfunktion auf, erhält Ergebnis zurück
If $bRetOK = True Then Return $sPath & $sRet ;Prüft, ob Datei dazugenommen werden soll
Until $bRetOK = True ;Wiederholt bei false alles
EndFunc ;==>__Tree_GetNextPath
Func Regulator($sPath, $sRet, $iExtended) ;Prüft, ob Ergebnis Objekt in Tree darf
If $iExtended Or StringRegExp($sRet, '(?i)\.lnk(?!.)') Then ;Wenn Ordner oder Verknüpfung (*.lnk), dann
Return True ;Return True
Else
Return False
EndIf
EndFunc ;==>Regulator
; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +
[/autoit]Das ist übrigens ein Teil des Projekts https://autoit.de/index.php/Thre…ktive-Directory
Mit Vernküpfungen meine ich ganz normale Windows-Verknüpfungen: https://de.wikipedia.org/wiki/Dateiverkn%C3%BCpfung
Danke dir, dass du dich damit beschäftigst!
Ja, den Beitrag von BugFix habe ich tatsächlich übersehen :-O Die UDFs helfen mir auf jeden Fall weiter. Man bleibt eben weiterhin auf TreeView angewiesen, allerdings ist es schon einmal eine Hilfe. Was mir bei der UDF von BugFix noch fehlen würde, wäre eine Funktion, mit der ich aus diesem String einzelne Childs anzeigen lassen könnte.
Ich habe auch schon eine Funktion erstellt, die basierend auf einem Array mir den Pfad des Childs inkl. Eltern angeben kann und eine Funktion, die mir alle Kinder anzeigt.
Was ist eigentlich schneller? Das über ein Array oder über einen String zu betreiben? Insbesondere, wenn ich öfters nur auf Teile (Knoten) zugreifen möchte?
Ich würde gerne eine Ordner-Struktur in einem Baum ablegen, die ich aus einer CSV generiere. Im Baum sollen auch Verknüpfungen vorbereitet sein, die später Ordner untereinander verknüpfen. Am liebsten würde ich teilweise auch noch Berechtigungen dort ablegen.
Diese Ordner- und Berechtigungsstruktur soll anschließend auf einen Fileserver geschrieben werden.
Bisher habe ich CSV -> in Array -> in Ordner- und Berechtigungsstruktur auf dem Fileserver
Weil ich momentan so viele Suchoperationen habe, um Kinder und Eltern quer verteilt im Array zu finden, würde ich das am liebsten in einem Baum speichern.
Hm, das ist auch eine Idee
Wie ist diese Lösung von der Performance so?
Hallo alle zusammen,
ich würde gerne eine Datenstruktur (Ordnerstruktur) in einem Tree (Baum) speichern. Bisher habe ich das über ein Array gemacht.
Gibt es auch eine UDF, die einen Baum als so etwas wie eine Variable bereitstellt?
Sonst muss ich mir eben selbst ein Array schreiben mit entsprechenden Funktionen als UDF. Da wäre eine objektorientierte Sprache natürlich sehr nützlich
LG
Hallo alle zusammen,
ich habe viele Themen im letzten Forum abboniert.
Leider werden sie jetzt nicht mehr als abboniert angezeigt.
Hallo alle zusammen,
ich arbeite schon seit einiger Zeit an einem Projekt, mit dem ich automatisch eine Ordner- und Berechtigungsstruktur erstellen kann.
Inzwischen bin ich schon sehr weit gekommen.
Bei mir klappt es gut, allerdings kann ich keine Gewähr für die korrekte Funktionsweise übernehmen. Ich empfehle die Ausführung in einer kontrollierten Umgebung, z.B. Testumgebung oder Testbenutzer mit eingeschränkten Rechten, und anschließende Übernahme in die Produktivumgebung.
In diesen Programmen steckt viel Arbeitszeit und wir konnten die Programme bereits erfolgreich verwenden.
Kontextmenü ist eine abgespeckte Variante. Es lässt sich darüber ein Eintrag im Kontextmenü erstellen. Beim Rechtsklick auf einen Ordner lässt sich dann das Programm auswählen und automatisch eine Vollzugriff- und eine Lesezugriff-Gruppe in einer beliebigen OU erstellen.
OrdnerUndBerechtigungsstruktur ist die vollständige Version. Über eine Hauptdatei organigramm.csv lässt sich die Ordnerstruktur auswählen und für den Anhang (hier OrdnerInOrdner.csv) lassen sich Ordner auswählen, die in jedem Ordner der organigramm.csv-Datei erstellt werden sollen. Über Parameter lassen sich Verknüpfungen automatisch einrichten, bestimmen, dass die Berechtigungen der übergeordneten Ordner nicht übernommen werden, dass die OrdnerInOrdner.csv-Datei keine Anwendung auf einen Ordner findet etc.
Ich finde eine csv-Datei wesentlich einfacher und schneller zu bedienen als eine CSV.
Diese Version wollte ich jetzt einfach mal schnell hochladen, um eure Meinung einzuholen.
Es gibt noch viel zu verschönern und auch viel auskommentierten Code werde ich beim nächsten Mal löschen.
Ich freue mich über Feedback, gefundene Fehler und natürlich über alle, die Code dazu beitragen möchten.
Wahrscheinlich müsste ich so ein komplexes Skript nächstes Mal mit einer objektorientierten Sprache erstellen.
Vielen Dank an alle, deren UDFs ich verwenden durfte!
LG Florian
PS: Kennst sich noch jemand mit der Permissions-UDF aus? Weiß jemand, wo ich dazu Fragen stellen kann?
Erstmal danke für die geniale Erklärung und die Beispiele!
Wenn ich das lokal probiere, dann funktioniert es.
Im Netzwerk geht es nicht. Wenn ich http://www.traum-projekt.com/forum/66-betri…amba-share.html und http://support2.microsoft.com/?scid=kb%3Ben-us%3B812003&x=12&y=13 richtig verstanden habe, dann erlaubt das Microsoft wohl nicht.
Danke!
Dann muss ich das erst für Ordner freischalten und dann kann ich die Info zukünftig im Ordner hinterlegen wie bei Dateibeschreibungen?
Das betrifft nämlich ein ganzes Netzwerk
Möglicherweise müsste ich das dann per GPO freischalten.
Hallo alle zusammen,
ich möchte vielen, automatisch erstellten Ordnern Infotexte hinzufügen (Beschreibung).
Dazu habe ich gelesen, dass das über eine desktop.ini geht:
http://www.winfaq.de/faq_html/Conte…p?h=tip1049.htm
Wenn ich diese desktop.ini erstelle, dann verändert sich nichts.
Gibt es eine Möglichkeit per AutoIt die Beschreibung zu erstellen oder habe ich vielleicht etwas in der desktop.ini übersehen?
LG
So, ich habe nun am Anfang
[autoit]If @OSArch = 'X64' And Not @AutoItX64 Then
Run(StringTrimRight(@ScriptName, 4) & '_x64.exe') ;Führt bei x64-Installation x64-AutoIt aus
Exit
EndIf
geschrieben, damit bei 32bit 32bit-AutoIt und bei 64bit 64bit-AutoIt gestartet wird.
Und lese die Software nun per ergänzte _CI_GetSoftware-UDF aus.
#cs===============================================================================
Function Name: _CI_GetSoftware($s_RemoteComputer = '')
Description:: Liest die installierte Software mit Version aus der Registry
Parameter(s): $s_RemoteComputer = Remotecomputer (Optional)
Author(s): Protex @ AutoIt.de und Danny35d @ autoitscript.com
Überarbeitet: FKFK (UDF)
Return values: Erfolg: Array mit der installierten Software
[0][1] befindet sich die Anzahl der installierten Software.
[x>1][0] -> Programmname
[x>1][1] -> Version, sofern vorhanden
#ce===============================================================================
Func _CI_GetSoftware($s_RemoteComputer = '')
Local $Count = 1 ;Erstellen der Counter-Variable
Local $aReturn[2][2] = [['', ''],['Programm:', 'Version:']]
If $s_RemoteComputer <> '' Then $s_RemoteComputer = '\\' & StringReplace($s_RemoteComputer, '\', '') & '\' ;Wenn ein Remotecomputer angegeben ist, werden alle angegbenen "" entfernt und "\" davor geschrieben
;~ Local Const $regkey = $s_RemoteComputer & 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' ;Auszulesender Schlüssel über den die installierte Software gefunden werden kann
Local Const $aRegKeys[2] = [$s_RemoteComputer & 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', _ ;Auszulesender Schlüssel über den die installierte Software gefunden werden kann
$s_RemoteComputer & 'HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'] ;Auszulesender Schlüssel über den die installierte Software gefunden werden kann
For $sRegKey In $aRegKeys ;Dauerschleife zum Auslesen der installierten Software, Ende, wenn alles ausgelesen wurde
While 1
$key = RegEnumKey($sRegKey, $Count) ;Auszulesender Unterschlüssel wird ermittelt: Schlüssel und Position entsprechend Count -> Rückgabe des Unterschlüssels
If @error <> 0 Then ExitLoop ;Sofern der letzte Unterschlüssel erreicht wurde -> Schleife wird verlassen
$line = RegRead($sRegKey & '\' & $key, 'Displayname') ;Softwarebezeichnung wird ausgelesen
$version = RegRead($sRegKey & '\' & $key, 'DisplayVersion') ;Software-Version wird ausgelesen
$line = StringReplace($line, ' (remove only)', '') ;Die Aussage (remove only) wird aus dem String entfernt, sofern vorhanden
If $line <> '' Then ;Sollte der Softwarename nicht leer sein, werden dem Array Daten zugewiesen
ReDim $aReturn[UBound($aReturn) + 1][2] ;Erweiterung des Arrays
$aReturn[UBound($aReturn) - 1][0] = $line ;Zuweisung der Softwarebezeichnung
$aReturn[UBound($aReturn) - 1][1] = $version ;Zuweisung der Software-Version
EndIf
$Count = $Count + 1 ;Erhöhung des Counters
WEnd
Next
If Not IsDeclared('aReturn') Or Not IsArray($aReturn) Then ;Überprüft das Array auf Fehler und gibt, sofern vorhanden, Fehler zurück
Return (SetError(1, 0, ''))
ElseIf Not UBound($aReturn, 0) = 2 Then ; Überprüft auf richtige Dimensionen-Zahl und gibt ansonsten einen Fehler zurück
Return SetError(2, 0, "")
Else
$aReturn[0][0] = 'Installierte Software:'
$aReturn[0][1] = UBound($aReturn) - 1 ;Sofern keine Fehler vorhanden sind, wird die Anzahl der installierten Software ins Array gespeichert
Return (SetError(0, 0, $aReturn))
EndIf
EndFunc ;==>_CI_GetSoftware
Danke Oscar für den Link! Ich habe das auch schon so ähnlich umgesetzt, allerdings zeigt meine 32bit-Exe in beiden Registry-Pfaden das gleiche an. Windows nimmt meines Wissens ja bei 32bit-Exen den Wow6432Node und gibt ihn als den Pfad aus, unter dem die 64bit-Software gespeichert wäre. Dadurch sieht die 32bit-Exe immer nur die 32bit-Software.
Hallo alle zusammen,
nun sind drei Jahre um und fast überall gibt es 64 bit
So stehe ich vor einer neuen Frage:
Windows legt installierte Software in der Registry unter HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall und unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
Mein Skript zeigt mir in beiden Fällen nur die Software von Wow6432Node an, wahrscheinlich weil es 32 bit ist.
Gibt es eine Möglichkeit aus beiden Pfaden die Software auszulesen oder muss ich ein 64bit-Skript und für die 32bit-PCs ein 32bit-Skript erstellen?
LG FKFK
Danke für den Hinweis.
Es gibt in der Funktion ja einen Parameter ClearDACL. Ich dachte eigentlich, dass die Funktion nur dann den Inhalt löscht, wenn dieser Parameter aktiviert ist.
Es gibt auch noch den Befehl _EditObjectPermissions, er sollte nach meinem Verständnis, die Berechtigungen auf jeden Fall erhalten. In der Beschreibung steht auch:
; Remarks .......: Unlike _SetObjectPermissions, this function is able to edit the inherithed entries in the DACL, instead of adding new ones.
; + For instance if an object has a denied ace entry this function can edit it and make it a granted acces ace.
Ansonsten werde ich versuchen müssen, mit diversen Funktionen das so zusammenzubasteln, wie du das beschrieben hast.
//edit: Ich habe herausgefunden, dass ich Adminrechte benötige, sonst schlägt die Funktion fehl, die die Größe der DACL herausfinden möchte:
; #FUNCTION# ====================================================================================================================
; Name...........: _GetDaclSizeInformation
; Description ...: Returns a Dacl size information in an array
; Syntax.........: GetDaclSizeInformation(ByRef $Dacl)
; Parameters ....: $Dacl - A pointer to a Dacl.
; Return values .: Success - An array containing the ace info:
; $aRet[0] = The number of aces in the Dacl.
; $aRet[1] = The number of bytes used by the dacl
; $aRet[2] = The number of free bytes in the dacl
; Failure - An empty array and sets @error: 1 - Invalid Dacl.
; Author ........: FredAI
; Modified.......:
; Remarks .......: The total size of the Dacl is obviously $aRet[1] + $aRet[2]
; Related .......: _GetAce, _MergeDaclToArray
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _GetDaclSizeInformation(ByRef $Dacl)
Local $aRet[3] = [0,0,0]
If Not IsPtr($Dacl) Then Return SetError(1,0,$aRet)
Local $_ACL_SIZE_INFORMATION = DllStructCreate('DWORD AceCount;DWORD AclBytesInUse;WORD AclBytesFree')
Local $aCall = DllCall($h__Advapi32Dll,'bool','GetAclInformation','ptr',$Dacl, _
'ptr',DllStructGetPtr($_ACL_SIZE_INFORMATION),'dword',DllStructGetSize($_ACL_SIZE_INFORMATION),'dword',2)
If @error Or $aCall[0] = 0 Then Return SetError(2,0,$aRet)
$aRet[0] = DllStructGetData($_ACL_SIZE_INFORMATION,'AceCount')
$aRet[1] = DllStructGetData($_ACL_SIZE_INFORMATION,'AclBytesInUse')
$aRet[2] = DllStructGetData($_ACL_SIZE_INFORMATION,'AclBytesFree')
Return $aRet
EndFunc ;==> _GetDaclSizeInformation
Weiß jemand, warum? Wie kann ich das auch ohne Adminrechte machen kann?
Ich habe nun herausgefunden, dass vererbte Berechtigungen erhalten bleiben und nur nicht geerbte Berechtigungen entfernt werden. Mein Ziel ist es: Das gar nichts entfernt wird.
Ich habe eine Beispiel UDF angehängt, die Dateien als String, 1D- und 2D-Array einlesen kann.