Beiträge von alpines
-
-
-
Das ist zwar kein Fehler von AutoIt, wohl aber ein potenzieller 'Stolperstein'. Wäre dies also ein Punkt, den ich in den Sammelthread unter Inkonsistenz eintragen sollte ?
Schau dir mal GUISetState und GUICtrlSetState an.
-
Wie kann ich diese beiden Dateien so in das Setup-Programm einfügen, dass sie beim Setup extrahiert werden können
Du kannst sie als Binärstring hinterlegen und Schritt für Schritt in eine Datei schreiben oder dir das Leben leichter machen und FileInstall nutzen.
-
https://www.autoitscript.com/autoit3/docs/l…/_IsPressed.htm
Probiers mal mit X1 und X2 Mouse Button, ansonsten wirst du wohl (wenn du eine Maus mit 20 Tasten hast) den Weg über eine DLL vom Hersteller gehen oder andersweitig hooken müssen, z.B. RawInput.au3 wobei ich nicht weiß ob RawInput auch Mäuse unterstützt.
-
ahh er crashed bei dokumente und einstellungen und dieser ist leer, ne idee wie ich das abfangen kann?
Abfragen ob das Array mehr als 0 Einträge hat? UBound solltest du doch kennen.
-
Schau mal nach bei welchem $path er crasht, ich schätze mal du greifst auf C:\$WINDOWS.~BT$ (oder so ähnlich) zu und da sind keine Dateien enthalten, deswegen crasht es bei mir.
-
-
Ist das wechseln im Script zwischen GuiGetMessage/OnEvent nicht teufelszeug?
Kann man schon machen, aber man verliert schnell den Überblick darüber, welche Fenster klickbar sind und welche nicht.
Wenn man schon wechselt, sollte man darauf achten, dass alle anderen Fenster versteckt oder disabled sind, da ansonsten die Events nicht verarbeitet werden.
Aber es ist nach wie vor das alte Problem, UDFs sind nicht konsistent. Einige arbeiten lieber mit einer Messageloop, einige widerum mit dem OnEventMode.
Gäbe es eine einheitliche Wahl würde dieses Problem nicht existieren.
-
Wie lange würde es dauern das zu machen?
Das kommt ganz darauf an wie die Daten aufbereitet sind und vorliegen.
Das Versenden der Mails an sich sollte kein Problem sein, da gibt es z.B. CDO.Message (Objekt) um damit über SMTP-Nachrichten zu verschicken (auch SSL-verschlüsselte).
Wenn ihr aber Outlook schon installiert habt und von dort eure Mails abschickt kann man auch direkt die Outlook UDF verwenden, dann sollte das ganze etwas besser laufen als direkt mit dem Objekt.
Dann das ganze zu kopieren sollte denke ich kein Problem sein.
Wenn man sich ein Bild von der Situation gemacht hat sollte das nicht länger als ein paar Stunden (<10h) Arbeit sein um das ganze zum Laufen zu bekommen.
Was würde das Kosten?
Das ist immer unterschiedlich, und variiert stark je nach dem ob du mit Stundenlohn bezahlst oder einen Festpreis ermittelst. (Dazu kommen ja noch etwaige Updates, Bugfixes, etc).
Das ganze würde nur für ca ein Jahr genutzt denn dann wird das alles über unsere Webseite gesteuert.
Bekommt ihr dann das Interface schon gestellt oder wird es erst dann programmiert? Ihr könntet doch direkt auf die Webvariante gehen und spart euch den Umweg über eine Exe oder sehe ich das falsch?
-
Oscar movest du das bitte nach H&Ü?
-
Die PN lässt übrigens noch auf sich warten.
-
Für mich dann doch ein wenig Kompliziert
Das ist ja wohl die faulste Ausrede die ich seit langem gehört habe, du gibst dir ja nicht mal Mühe das ganze zu verstehen.
Der Hauptgegentand ist die For-Schleife in dem die Prozesse aufgelistet werden, hast du das Skript nicht mal ausgeführt?
Alles was du machen musst ist nur die Prozessliste durchgehen und zu prüfen ob der Username mit dem übereinstimmt den du vergleichen willst, das sind vielleicht 2 Minuten Arbeit.
-
Das würde mir ja auch nichts bringen, da das Programm ja geschlossen wurde aber das Script läuft ja weiterhin.
Wenn es ein externes Programm ist kannst du das auch über WMI machen, hier mal ein Thread aus dem blauen Forum. https://www.autoitscript.com/forum/topic/94…user-or-system/
Code
Alles anzeigen_ProcessRetrieve() Func _ProcessRetrieve($host = @ComputerName,$usr=0) $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $host & "\root\cimv2") If not IsObj($objWMIService) Then Return 0 $colItems = $objWMIService.ExecQuery ("SELECT * FROM Win32_Process") For $objItem in $colItems $objItem.GetOwner($usr) ConsoleWrite($objItem.Name & ":" & $objItem.ProcessId & @TAB) ConsoleWrite($usr & @CRLF) Next Return 1 EndFuncDort kriegst du den Usernamen des Benutzers angezeigt der den Prozess ausgeführt hat.
-
Was macht denn _Singleton genau?
Ein Blick in die Dokumentation genügt:
Enforce a design paradigm where only one instance of the script may be running
Es erlaubt dir dein AutoIt-Skript nur einmal pro System am laufen zu haben. Das $sOccurenceName ist dabei der Identifikator.
Du nimmst als Identifikator einfach den Benutzernamen und versuchst das Skript zu starten, startet es mit einer Fehlermeldung von _Singleton weißt du, dass der aktuelle Benutzer es noch benutzt.
Startet es ohne Fehlermeldung, weißt du, dass es nicht läuft und kannst es beenden und dich ausloggen.
-
Wenn du mit RegEx umgehen kannst kannst du einfach ein Replace-Pattern drüber laufen lassen und alles automatisch umwandeln.
-
Ich hoffe es stört nicht, dass ich doppelt poste, aber so kannst du einfacher zu den Themen verlinken die du in den ersten Beiden Beiträgen angeschnitten hattest.
TreeView DeleteChildren-Bug/Inkonsistenz (Win7 x64 - Au3: 3.3.14.5)
Hier wurde einfach schlecht programmiert.
Einige _GUICtrlTreeView-Funktionen akzeptieren das Standard-AutoIt-TreeViewItem (welches man mit der ID anspricht) aber DeleteChildren sträubt sich da, der Grund ist auch "schnell" gefunden.
Einige Funktionen rufen nämlich intern noch _GUICtrlTreeView_GetItemHandle auf und arbeiten mit dem hWnd des Controls weiter, allerdings passiert das bei _GUICtrlTreeView_DeleteChildren nicht.
Übergibt man kein hWnd (also einfach nur die ID vom Standard-TreeView-Control), so wird der Else-Zweif in der Funktion ausgeführt und als $lParam von GUICtrlSendMsg wird die AutoIt-Interne-ID eines Items weitergegeben.
Das selbe Problem sollte auch beim Nicht-Else Zweif auftreten, allerdings muss man dann GUICtrlGetHandle um das TreeView packen und das Item normal übergeben was niemand machen würde.
CodeFunc _GUICtrlTreeView_DeleteChildren($hWnd, $hItem) Local $bResult If IsHWnd($hWnd) Then $bResult = _SendMessage($hWnd, $TVM_EXPAND, BitOR($TVE_COLLAPSE, $TVE_COLLAPSERESET), $hItem, 0, "wparam", "handle") Else $bResult = GUICtrlSendMsg($hWnd, $TVM_EXPAND, BitOR($TVE_COLLAPSE, $TVE_COLLAPSERESET), $hItem) EndIf Return $bResult EndFuncAllerdings erwartet $TVM_EXPAND als $lParam ein hWnd (einen Pointer!) und keine AutoIt-Interne-ID.
AutoIt erkennt das nicht automatisch und so wird als lParam einfach die ID gesendet welches auf einen ungültigen Speicherplatz zeigt und folglich das Control nicht gelösht werden kann.
Fix: GUICtrlGetHandle verwenden wenn man Items an _GUICtrlTreeView_DeleteChildren versendet, dann übergibt man nämlich einen Pointer.
Oder man setzt vollständig auf die UDF und verwendet kein einziges Standardcontrol, dann bräuchte man ehrlich gesagt aber die Tausend Abfragen nicht die in der UDF enthalten sind (die die Standardcontrols akzeptierbar machen).
C
Alles anzeigen#include <GUIConstantsEx.au3> #include <GuiTreeView.au3> #include <WinAPI.au3> $hGUI = GUICreate("DeleteChildren-Bug", 242, 210, 192, 124) $hTV = GUICtrlCreateTreeView(8, 8, 225, 161) $hA = GUICtrlCreateTreeViewItem("A", $hTV) $hA1 = GUICtrlCreateTreeViewItem("A1", $hA) $hB = GUICtrlCreateTreeViewItem("B", $hTV) $hB1 = GUICtrlCreateTreeViewItem("B1", $hB) $hB11 = GUICtrlCreateTreeViewItem("B1.1", $hB1) $hC = GUICtrlCreateTreeViewItem("C", $hTV) _GUICtrlTreeView_Expand($hTV) GUISetState(@SW_SHOW, $hGUI) MsgBox(64, "Info", "Es wird nun _GUICtrlTreeView_DeleteChildren($hTV, $hA) aufgerufen." & @CRLF & _ "Ziel ist es, alle Untereelemente von A zu löschen.") ConsoleWrite("_GUICtrlTreeView_DeleteChildren($hTV, $hA) = " & _GUICtrlTreeView_DeleteChildren($hTV, $hA) & @CRLF) _WinAPI_InvalidateRect($hTV) MsgBox(64, "Info", "Es wurde aber kein Unterelement gelöscht." & @CRLF & _ @CRLF & _ "Nun wird " & @CRLF & _ "_GUICtrlTreeView_DeleteChildren($hTV, GUICtrlGetHandle($hA))" & @CRLF & _ "aufgerufen.") ConsoleWrite("_GUICtrlTreeView_DeleteChildren($hTV, GUICtrlGetHandle($hA)) = " & _GUICtrlTreeView_DeleteChildren($hTV, GUICtrlGetHandle($hA)) & @CRLF) _WinAPI_InvalidateRect($hTV) MsgBox(64, "Info", "Und die Unterelemente sind weg.") #cs https://docs.microsoft.com/en-us/windows/desktop/controls/tvm-expand Im Code von _GUICtrlTreeView_DeleteChildren wird aber explizit abgefragt ob es sich bei dem übergebenen Item um ein hWnd Objekt handelt oder nicht, wenn nicht, dann wird die interne Funktion GUICtrlSendMsg aufgerufen. allerdings löscht diese die Items nicht. Es wird außerdem als $lParam beim Else-Zweif einfach das Item übergeben obwohl die $TVM_EXPAND eindeutig einen Pointer zu dem Control haben möchte und keine AutoIt-Interne Nummer, diese wird nämlich nicht angepasst abgeschickt! ; #FUNCTION# ==================================================================================================================== ; Author ........: Paul Campbell (PaulIA) ; Modified.......: Gary Frost (gafrost) ; =============================================================================================================================== Func _GUICtrlTreeView_DeleteChildren($hWnd, $hItem) Local $bResult If IsHWnd($hWnd) Then $bResult = _SendMessage($hWnd, $TVM_EXPAND, BitOR($TVE_COLLAPSE, $TVE_COLLAPSERESET), $hItem, 0, "wparam", "handle") Else $bResult = GUICtrlSendMsg($hWnd, $TVM_EXPAND, BitOR($TVE_COLLAPSE, $TVE_COLLAPSERESET), $hItem) EndIf Return $bResult EndFunc ;==>_GUICtrlTreeView_DeleteChildren Außerdem wird $TVM_EXPAND verwendet um die Items zu löschen obwohl das keinen Sinn macht, weil, wie wir gerade festgestellt haben, das [+] noch bleibt. Stattdessen hätte man $TVM_DELETEITEM für alle Unterelemente aufrufen müssen. #ce While GUIGetMsg() <> $GUI_EVENT_CLOSE WEndDass hier, $TVM_EXPAND zum löschen mit $TVE_COLLAPSERESET verwendet wird, will ich mal außen vor lassen, bei mir erzeugt das einen visuellen Bug.
Das [+] vor dem "A" verschwindet nicht, obwohl das Item keine Unteritems mehr hat und man es auch nicht mehr expandieren kann.
-
Tolle Aktion

Damit das jeder nachvollziehen kann hier der Code zum TreeView-Bug / "-1"-Bug (Win7 x64 - Au3: 3.3.14.5)
Es wird eine $hMainGUI erstellt die angezeigt wird. Diese dient als Haupt-GUI und öffnet die TreeView GUI und nachdem die TV-GUI angezeigt wird, @SW_DISABLEn wir die Haupt-GUI.
Nun können wir wahllos Items anklicken und neue Unteritems spawnen lassen und es taucht eine neue GUI von _ArrayDisplay auf.
Diese schließen wir und versuchen neue Items zu spawnen, dies ist allerdings nur auf den Items möglich die schon existierten.
Spawnen wir ein Neues Item und versuchen mit dem Klick auf das Neue Item "Neu" wieder ein neues zu spawnen schlägt das fehl,
denn das Event wurde nicht gesetzt. Da im GUICtrlCreateTreeViewItem kein -1 auftaucht sondern mit der Variable gearbeitet wird wird das Item zumindest erstellt.
Der Bug ist also der, dass das Setzen von Events (oder andern Sachen die mit -1 funktionieren) auf Controls nicht funktionieren, die korrekt erstellt wurden,
während eine andere GUI "aktiv" war. Denn das -1 bezieht sich immer auf das letzte Control und inklusive auf die letzte "aktive" GUI. (Aktiv im Sinne von SetState benutzt und nicht unbedingt Controls darauf erstellt!)
Und nicht wie es überall in der Hilfe steht nur auf das letzte Control.
The control identifier (controlID) as returned by a GUICtrlCreate...() function, or -1 for the last created control.
Der Grund dafür ist, dass das -1 im GUICtrlSetOnEvent auf das falsche Control der falschen GUI zeigt (sollte eigentlich immer auf das letzte Control zeigen).
Verwenden wir aber nun statt dem -1 die Variable mit dem ID des Controls werden auch bei den neuen Items wieder neue erstellt obwohl die GUI von ArrayDisplay auftauchte.
Mit dem -1 klappt es nur wenn wir GUISwitch verwenden.
Btw: Das TreeView-Begin/EndUpdate ist nicht zwangsweise notwendig, allerdings erscheinen die [+] nicht sofort (visuell) wenn man es nicht drin hat.
C
Alles anzeigen#include <Array.au3> #include <GuiTreeView.au3> #include <TreeViewConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) $hGUI = GUICreate("TreeView-Bug", 242, 210, 192, 124) GUISetOnEvent($GUI_EVENT_CLOSE, _ExitApp, $hGUI) $hTV = GUICtrlCreateTreeView(8, 8, 225, 161) $hA = GUICtrlCreateTreeViewItem("A", $hTV) $hA1 = GUICtrlCreateTreeViewItem("A1", $hA) $hB = GUICtrlCreateTreeViewItem("B", $hTV) $hB1 = GUICtrlCreateTreeViewItem("B1", $hB) $hB11 = GUICtrlCreateTreeViewItem("B1.1", $hB1) $hC = GUICtrlCreateTreeViewItem("C", $hTV) ; ===== Der Teil dient nur dazu schnell den Controls die Events zuzuweisen ===== Local $aTmp[] = [$hA, $hA1, $hB, $hB1, $hB11, $hC] For $i = 0 To UBound($aTmp) - 1 GUICtrlSetOnEvent($aTmp[$i], _TreeViewItem_Click) Next ; ===== So muss nicht unter jedem Control ein GUICtrlSetOnEvent hin ===== _GUICtrlTreeView_Expand($hTV) ;MainGUI dient als Hauptprogramm $hMainGUI = GUICreate("Haupt GUI") GUISetState(@SW_SHOW, $hMainGUI) ;Nun wollen wir die Hauptoberfläche disablen, da diese nicht mehr klickbar sein soll. ;Denn es taucht eine neue GUI auf auf der wir Einträge aus der TV anklicken wollen. ;Dieser Bug tritt auch auf wenn wir kein @SW_DISABLE nehmen. Nochmal @SW_SHOW hat den selben Effekt. ;Beim Benutzen des GUISetStates geht der Verweis des letzten Controls verloren. GUISetState(@SW_SHOW, $hGUI) GUISetState(@SW_DISABLE, $hMainGUI) While Sleep(1000) WEnd Func _TreeViewItem_Click() ;Das Array Display soll als quick'n'dirty Methode dienen eine neue GUI zu erstellen. ;Da im _ArrayDisplay GUISetState unvermeidbar benutzt werden muss (um die GUI anzuzeigen) ;tritt der Bug auf. Local $a[0] _ArrayDisplay($a) _GUICtrlTreeView_BeginUpdate($hTV) ;Ersetzt man das -1 im GUICtrlSetOnEvent mit $hItem funktioniert es. ;Es funktioniert mit dem -1 nur wenn man GUISwitch($hGUI) verwendet. ;Dann wird wieder die richtige GUI ausgewählt und das Control erzeugt. $hItem = GUICtrlCreateTreeViewItem("Neu", @GUI_CtrlId) GUICtrlSetOnEvent(-1, _TreeViewItem_Click) _GUICtrlTreeView_EndUpdate($hTV) EndFunc Func _ExitApp() Exit EndFunc -
Welches Skript willst du denn anpassen? Wie sind die Geräte vernetzt? Sowas solltest du schon mitliefern.
Ansonsten kannst du PSEXEC nehmen und dort die benötigten Informationen (Dateiname, User/Passwortkennung) übergeben und es wird ausgeführt.
-
Versteh das Problem ehrlich gesagt nicht so ganz.
Um eine Liste und Pfade aller Dateien des Desktops zu bekommen benötigt man lediglich die Funktion _FileListToArray. Hier kann man bei Bedarf auch nach Dateien / Ordnern und bestimmten Dateiendungen wie "*.txt" filtern, oder aber man wertet das Array eben selbst aus wenn auch Dateien mit anderen Endungen verschoben werden sollen.
Um die Pfade für den eigenen Desktop / AllUser Desktop oder auch Desktop eines spezifischen Users zu ermitteln sind folgende Makros hilfreich:Das hatte ich bereits in der SB vorgeschlagen, aber es geht wohl um den Zugriff auf das Desktopcontrol.
Meiner Meinung nach kann man diesen Teil aber hervorragend über die entsprechenden Funktionen auslagern.
Wenn man nun auch noch das Datum vergleicht (oder die Größe) hat man die richtige Datei (bei verschiedenen Endungen aber dem gleichen Typen).