1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. HansJ54

Beiträge von HansJ54

  • Neuen Eintrag ins Clipboard feststellen

    • HansJ54
    • 7. Juli 2021 um 00:02

    Habe die Lösung gefunden: das GUI ist hier im Beispiel nur ein Dummy. Jede Veränderung im Clipboard führt zu einer Anzeige der letzten Änderung.

    C
    #include <GUIConstants.au3>
    #include <MsgBoxConstants.au3>
    
    Global $WM_CLIPUPDATE=0x031D
    $gui = GUICreate("Clip Hook",400,400,-1,-1)
    DLLCall("user32.dll","int","AddClipboardFormatListener","HWND",$gui)
    GUIRegisterMsg($WM_CLIPUPDATE,"OnClipBoardChange")
    While 1
        $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd
    Exit
    Func OnClipBoardChange()
        MsgBox($MB_TOPMOST,"Test",ClipGet(),1)
    EndFunc
    Alles anzeigen
  • Neuen Eintrag ins Clipboard feststellen

    • HansJ54
    • 6. Juli 2021 um 23:12

    Ich habe ein kurzes Script aus 2012 gefunden, aber verstehe nicht die Funktionsweise. Irgendwie hängt das an einer GUI. Ich brauche nur den String ClipGet() ohne das Fenster in meinem Programm.

    C
    #cs ----------------------------------------------------------------------------
    AutoIt Version: 3.3.6.1
    Author:         Zedna (Modified By Me)
    Script Function:
    Template AutoIt script.
    #ce ----------------------------------------------------------------------------
    ; Script Start - Add your code below here
    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    
    Global $origHWND,$lastCopied='',$WM_CLIPUPDATE=0x031D,$DefMsG='__•¯¯'
    $gui = GUICreate("Clip Hook",400,400,-1,-1,BitOR($WS_CAPTION,$WS_SYSMENU))
    Global $label=GUICtrlCreateLabel('Clipboard Contains',30,30,340,30)
    Global $label1=GUICtrlCreateEdit('Clipboard Contains',30,80,340,210)
    ; remember last clip viewer in queue and set our GUI as first in queue
    $origHWND = DLLCall("user32.dll","int","AddClipboardFormatListener","hwnd",$gui)
    $origHWND = $origHWND[0]
    GUIRegisterMsg($WM_CLIPUPDATE,"OnClipBoardChange")
    WinSetOnTop($gui,'',1)
    GUISetState()
    While 1
        $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd
    Exit
    Func OnClipBoardChange($hWnd, $Msg, $wParam, $lParam)
        ; do what you need when clipboard changes
        _write(ClipGet())
    EndFunc
    Func _write($data)
    If $data<>$lastCopied Then
      $lastCopied=$data
      Return GUICtrlSetData($label1,$data)
    Else
      Return $DefMsG
    EndIf
    EndFunc
    Alles anzeigen
  • Neuen Eintrag ins Clipboard feststellen

    • HansJ54
    • 6. Juli 2021 um 22:26

    Gibt es eine Möglichkeit über ein "event" festzustellen, ob ein neuer Eintrag ins Clipboard erfolgt ist oder muss ich das Clipboard mit ClipGet() pollen?

  • Wie kann ich alle laufenden Tasks "chrome.exe" beenden?

    • HansJ54
    • 5. Juli 2021 um 10:09

    Perfekt, danke - kann ich direkt so übernehmen.
    Ich hatte an etwas wie "Kill Process Tree" beim Process Explorer gedacht, aber der kann natürlich genau so sequentiell arbeiten wie Dein Script.

  • Wie kann ich alle laufenden Tasks "chrome.exe" beenden?

    • HansJ54
    • 4. Juli 2021 um 23:54

    Kann man mit einem Befehl sämtliche Unterprozesse eines Prozesses beenden ohne über deren einzelne Unter-PIDs zu laufen? Also mit PID 18612 den geckodriver, conhost und alle firefox.exe?

    pasted-from-clipboard.png

  • Makro zur Anzeige des aktuellen "Include" und der aktuellen Function

    • HansJ54
    • 7. Juni 2021 um 16:54

    Du hast Recht, durch das "Local" werden die Variablen ja im Prinzip schon gestackt. Und durch das "Local" kann man beide Werte platzsparend in nur eine Zeile schreiben. Das ging bei mir nicht, weil ich die Variablen außerhalb als "Global" deklariert hatte.

    Das "called from" hatte ich schon mal mit einer eigenen Function() implementiert, brauche ich aber zum Debuggen eigentlich nicht. Mit "Local" statt "Global" komme ich super hin. Danke!

  • Makro zur Anzeige des aktuellen "Include" und der aktuellen Function

    • HansJ54
    • 7. Juni 2021 um 16:09

    Du hast Recht. Ohne das "After" könnte man nach Beenden z.B. von verschachtelten Funktionen nicht wissen, wohin und ab wo man zurückgekommen ist. Wobei natürlich dann die Zeilennummern helfen könnten, wenn man nicht gerade zwischen 2 Includes hin- und her gesprungen ist.

    Allerdings auch schwierig, wenn es innerhalb einer Funktion an mehreren Stellen Returns gibt. Dazu müsste man die Werte dann in einen Stack schreiben. Mit jedem Function-Call was obendrauf und jedem Return wieder weg.

    Das wäre dann wohl ein "Feature Request" für AutoIt (mit wenig Chancen zur Verwirklichung) ;)

  • Makro zur Anzeige des aktuellen "Include" und der aktuellen Function

    • HansJ54
    • 7. Juni 2021 um 12:15

    Schade, aber danke - dann muss ich nicht weiter suchen.

    Als Workaround ist natürlich möglich, dass ich in jeder Function() stattdessen $sFuncName="xxx" und $sInclude="yyy" vorne deklariere.

    Um die Funktionen nicht zu sehr aufzublähen, ist es irgendwie möglich, 2 Befehle in eine Zeile zuschreiben?

    Oder anderer Workaround: Func _Umgebung($sFuncName, $sInclude) und dann in jeder Function die Function als erstes aufrufen.

    Oder noch eine Idee: bei irgendwelchen alten Programmiersprachen (Fortran, Cobol?), die ich mal vor vielen Jahren gelernt habe, konnte man irgendwelche Variablen für die Kompilierung definieren, die als erstes in einem Precompile einfach ersetzt wurden. Also oben $$Include="xxx" und unten im Programm wurden dann alle $$Include vor dem Compile durch "xxx" ersetzt.

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 5. Juni 2021 um 14:49
    Zitat von BugFix

    He He - das ist nicht auf meinem Mist gewachsen. :rofl:

    Eure Namen sind zum Verwechseln ähnlich - zumindest wenn es so warm ist wie jetzt :rofl:

    Gleich noch eine doofe Frage: der String, den ich mit StringSplit in das Array stecke, hat am Ende einmal einen leeren Eintrag und dann noch einen mit 1 Byte. Jetzt brauche ich mal eine Idee, wie ich den String vor dem Zerlegen in Hex Byte für Byte anzeigen kann um zu sehen, was da hinten dran hängt. Auf Anhieb nichts dazu gefunden, wie das geht.

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 5. Juni 2021 um 14:27
    Zitat von BugFix

    Quatsch, das ist so, als ob du Äpfel mit Birnen vergleichst... in Post #9 verwendest du in dem Run() den Befehl Find, in Post #14 machst du es ganz anders - ohne Find.

    Könnte man so verstehen, aber ich meinte "das Problem mit dem Suchstring" - im neuen Script also ohne Problem da ohne Find und funktioniert ja perfekt;)

    Zitat von Bitnugger

    Dasselbe wie bei dir: Hiermit werden alle Prozesse, die dem Suchmuster entsprechen, terminiert (gekillt).

    Kannte ich auch noch nicht, wieder was gelernt - merke ich mir für andere Einsätze, spart einiges an Code. Aber im Moment will ich den User noch fragen, ob er einverstanden ist mit dem Beenden seiner Fenster oder ob er sie lieber selbst schließt und das Programm wartet so lange.

    Falls es interessiert: wir nutzen den Webdriver und die UDF dazu von DANp und haben es noch nicht geschafft, eine erneute Verbindung mit einem noch laufenden Webdriver aufzunehmen, wenn der User das Programm vorher beendet hat. Und da wir immer genau dasselbe Profil benötigen, hängt die Geschichte beim Neustart, da ein neuer Chrome nicht auf das noch in Nutzung befindliche Profil zugreifen kann und stattdessen ein neues produziert. Bleibt nur Terminieren von altem Webdriver und allen Chromes oder Edges, die ihr Profil blockieren. Falls jemand eine brauchbare Beschreibung findet, wie man die Verbindung zu einem laufenden Webdriver wieder neu aufnehmen kann, großen Dank!

    Zitat von HansJ54 Und wmic path und wmic process sind gleich? Hä?

    Wie schon erwähnt, ich kannte den Befehl wmic bis vorgestern überhaupt noch nicht, erst durch Deine Info. Und ich habe außer auf der Seite von Apfelböck nirgendwo eine brauchbare Beschreibung gefunden. Daher der Gedanke "Process" beschäftigt sich mit den Prozessen (das war mein Ziel) und "Path" war für mich gedanklich ganz etwas anderes. Funktioniert aber scheinbar für meinen Zweck genau so gut.

    Auf jeden Fall danke für Eure Hilfe!

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 4. Juni 2021 um 21:24
    Zitat von Bitnugger

    Der Suchstring für Find muss in Quote stehen!

    $iPID = Run(@ComSpec & ' /c ' & 'WMIC path win32_process get Processid,Commandline |find "' & $iPIDSearch & '"')

    Den Suchstring hatte ich im Script in #14 weiter oben schon korrigiert, läuft ja einwandfrei jetzt. Aber was macht das "call terminate" bei Dir?

    Und wmic path und wmic process sind gleich?

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 4. Juni 2021 um 19:06
    Zitat von BugFix

    Die schnellste Lösung ist meist PowerShell, so auch hier. Und die Ausgabe ist komplett.

    Danke an beide! Jetzt habe ich endlich ein Beispiel, wie ich PowerShell in AutoIt nutzen kann, aber mit meinem Script hole ich mir schon die gesuchten PIDs in ein Array mit dem ich die betreffenden Prozesse beenden kann. Ich suche tatsächlich nicht chrome an sich, sondern die chromes, die ein bestimmtes Profil nutzen ($sSearch = "chrome_wd_profil"). Und wmic ist auch schnell (von wmic hatte ich noch nie etwas gehört) ;)

    Aber jetzt brauche ich noch einen Tipp, ob es eine AutoIt-Funktion gibt, die die letzten Elemente oder alle Elemente, die leer sind, aus einer Tabelle löscht oder ob man es nur in der Art wie mein _ArrayClear() machen kann.

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 4. Juni 2021 um 17:46

    Dank Deinem Tipp mit wmic habe ich eine eine Lösung gefunden, die das nicht mehr vollständig funktionierende _WinApi_GetProcessCommandline() umgeht. Funktioniert nach ersten Tests auch ohne Admin-Rechte und kann sicher für alle möglichen Zwecke umgestaltet werden.

    AutoIt
    #include <Array.au3>
    
    $sSearch = "chrome"
    Local $aPIDs = _GetPids($sSearch, "Commandline")
    _ArrayDisplay($aPIDs, 'GetPIDs @error=' & @error)
    
    Func _GetPids($sSearch, $sAlias = "CommandLine")  ; returns ein Array der Prozess-IDs, in deren "$sAlias" $sSearch vorkommt, @error = 1 wenn nichts gefunden. $sAlias: CommandLine, Description
        ; Infos zu WMIC auf der Seite https://xn--apfelbck-s4a.de/wmic-wmi-console/  (falls jemand eine brauchbare Erklärung der möglichen WMIC-Parameter sucht)
        $iPID = Run('wmic process where (' & $sAlias & ' like "%' & $sSearch & '%" and not description ="wmic.exe") get processid', '', @SW_MINIMIZE, $STDERR_MERGED)
        ProcessWaitClose($iPID)
        Local $aOutput = StringSplit(StdoutRead($iPID), @crlf, $STR_ENTIRESPLIT)
        _ArrayClear($aOutput)
        If StringInStr($aOutput[1], 'ProcessId') Then
            SetError(0)
            $aOutput[1] &= '(searched "' & $sSearch & '")'
        Else
            SetError(1)
            $aOutput[1] &= '            '
        EndIf
        Return $aOutput
    EndFunc
    
    Func _ArrayClear(ByRef $aArray)
        Local $i = $aArray[0]
        While $aArray[$i] <= "0"
            _ArrayDelete($aArray, $i)
            $i -= 1
        WEnd
        $aArray[0] = $i
    EndFunc
    Alles anzeigen

    Ausgabe:

    Um die aus unerfindlichen Gründen entstehenden leeren Einträge am Ende des Arrays zu entfernen, habe ich _ArrayClear() geschrieben. Da gibt es aber sicher eine bessere direkte Funktion in AutoIt? Wäre nett, wenn Du mein Script ein wenig optimieren könntest.

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 3. Juni 2021 um 21:42
    Zitat von Bitnugger

    Das sieht schon etwas anders aus...

    Das funktioniert tatsächlich, aber dauert und das Admin-Fenster ist nicht so gut bei den einfachen Usern. Wenn ich mich auf Chrome beschränke, geht es schneller aber das Admin-Problem bleibt.

    Code
            For $i = 1 To UBound($aList) -1
                If $aList[$i][0] = "chrome.exe" Then
                    $aList[$i][2] = _Proc($aList[$i][0])
                    If StringInStr($aList[$i][2],"Profile") Then ConsoleWrite('PID: ' & $aList[$i][1] & @TAB & $aList[$i][2] & @CRLF)
                EndIf
            Next

    Hast Du eine Idee, was bei meinem Run() falsch ist?

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 3. Juni 2021 um 20:49

    Nö, falscher Fehler. Mit $sOutput = StdoutRead($iPID) hat es nicht funktioniert und dann kam ein Test, den ich nicht vollständig zurückgenommen habe: im Run noch >c:\temp\process.txt eingefügt um zu sehen, ob das Run() überhaupt was produziert - die Datei war leer. Also ist das Run() schon nicht ok. Den Output würde ich ja vielleicht in die Variable bekommen, aber wenn nichts da ist?

    Daher: an den ""; liegt es nicht, sondern an meinem Unwissen insgesamt ;)

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 3. Juni 2021 um 20:07

    WMIC path win32_process get Processid,Commandline |find "22788" > c:\temp\proxess4.txt

    Der WMIC-Befehl funktioniert in CMD . Im Ergebnis kommen dabei allerdings 5 Zeilen raus, einmal die gesuchte Commandline und die PID, danach aber noch eine Leerzeile, eine Zeile in der das FIND und die PID stehen und weitere 2.

    pasted-from-clipboard.png

    Und mein kurzes Script funktioniert auch nicht - habe noch nie den Output eines Run()-Befehls weiterverarbeitet:

    Code
    $iPIDSearch = "22788"
    $sSearch    = "CHROME-WD-Profile"
    $iPID = Run(@ComSpec & ' /c ' & 'WMIC path win32_process get Processid,Commandline |find ' & $iPIDSearch)
    ProcessWaitClose($iPID)
    $sOutput = "";StdoutRead($iPID)
    ConsoleWrite('$sOutput = ' & $sOutput & @CRLF & '>Error code: ' & @error & @CRLF)
    If StringInStr($sOutput, $sSearch) > 0 Then
        ConsoleWrite('PID ' & $iPIDSearch & ' enthält String "' & $sSearch & @CRLF)
    Else
        ConsoleWrite('PID ' & $iPIDSearch & ' enthält String "' & $sSearch & '" nicht' & @CRLF)
    EndIf
    Alles anzeigen

    Optimal wäre natürlich die Rückgabe nur der zu $iPIDSearch gehörenden Commandline oder umgedreht, falls mehrfach vorkommend, Ausgabe aller PIDs, in deren Commandline $sSearch vorkommt in einem Array (noch komfortabler).

    Vielen Dank für die Unterstützung - und das am Feiertag!

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 3. Juni 2021 um 16:29

    Habe schon bei VBS nachgeschaut, soll damit einfach möglich sein und das könnte man ja dann von AutoIt aus aufrufen. Aber ich verstehe trotzdem nicht, wie es funktioniert.

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 3. Juni 2021 um 15:55

    Hast Du das bei Dir mal laufen lassen? Bekommst Du auch so viele Fehler?

    pasted-from-clipboard.png

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 3. Juni 2021 um 14:00

    Die Privilegien werden im Beispiel-Script doch gesetzt, oder sehe ich das falsch?

    Leider sind die Fehler 20 und 40 nicht dokumentiert - das sind die angezeigten Fehler bei leeren Zeilen. Die abgeschnittene Zeile hat Error = 0.

    Mit dem "undocumented" gebe ich Dir natürlich Recht. Aber da die Funktion ja teilweise noch funktioniert, könnte sich "Yashied" die Sache vielleicht noch mal anschauen?

  • _WinAPI_GetProcessCommandLine​() funktioniert scheinbar nicht mehr?

    • HansJ54
    • 3. Juni 2021 um 13:46

    Hat vor einiger Zeit funktioniert, aber heute liefert _WinAPI_GetProcessCommandLine() nur noch bei ganz wenigen Prozessen den Inhalt der Commandline obwohl laut ProcExplorer fast überall Werte stehen.

    Problem: wir starten die Browser immer mit eigenen Profilen und müssen gelegentlich genau und nur die Fenster schließen, die mit diesen Profilen gestartet wurden - die anderen Chromes dürfen weiterlaufen. In der ProcessCommandLine steht dieses Profil laut ProcExplorer - wenn genutzt und wenn gefunden könnte ich den Prozess beenden.

    Gibt es eine neue Funktion oder einen Workaround?

    Test mit dem Script aus der Hilfe: das Ergebnis von _WinAPI_GetProcessCommandLine() über die kompletten Prozesse - Ergebnis: seitenweise leer, nur bei ganz wenigen Prozessen wird die CommandLine angezeigt. Bei einigen auch nur ein Teil der Commandline. Bei den leeren Zeilen kommt Error = 20 oder 40.

    C
    #RequireAdmin
    
    #include <Array.au3>
    #include <WinAPIHObj.au3>
    #include <WinAPIProc.au3>
    
    Local $aAdjust, $aList = 0
    
    ; Enable "SeDebugPrivilege" privilege for obtain full access rights to another processes
    Local $hToken = _WinAPI_OpenProcessToken(BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY))
    
    _WinAPI_AdjustTokenPrivileges($hToken, $SE_DEBUG_NAME, $SE_PRIVILEGE_ENABLED, $aAdjust)
    
    ; Retrieve command-line arguments for all processes the system
    If Not (@error Or @extended) Then
        $aList = ProcessList()
        For $i = 1 To $aList[0][0]
            $aList[$i][1] = _WinAPI_GetProcessCommandLine($aList[$i][1])
        Next
    EndIf
    
    ; Enable SeDebugPrivilege privilege by default
    _WinAPI_AdjustTokenPrivileges($hToken, $aAdjust, 0, $aAdjust)
    _WinAPI_CloseHandle($hToken)
    
    _ArrayDisplay($aList, '_WinAPI_GetProcessCommandLine')
    Alles anzeigen

    pasted-from-clipboard.png

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™