Parameter eines laufenden AHK-Scripts abrufen

Post a reply


In an effort to prevent automatic submissions, we require that you complete the following challenge.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :| :mrgreen: :geek: :ugeek: :arrow: :angel: :clap: :crazy: :eh: :lolno: :problem: :shh: :shifty: :sick: :silent: :think: :thumbup: :thumbdown: :salute: :wave: :wtf: :yawn: :facepalm: :bravo: :dance: :beard: :morebeard: :xmas: :HeHe: :trollface: :cookie: :rainbow: :monkeysee: :monkeysay: :happybday: :headwall: :offtopic: :superhappy: :terms: :beer:
View more smilies

BBCode is ON
[img] is OFF
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: Parameter eines laufenden AHK-Scripts abrufen

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by just me » 02 Mar 2018, 05:55

Na ja, Du könntest Dir die Ticketnummer auch aus einem Textfeld des GUI holen, irgendwo wird sie ja im Fenster stehen.

Für den Fall, dass das Ermitteln der laufenden B.ahk Skripte noch annähernd wie oben abläuft, hätte ich auch noch einen Vorschlag:

Code: Select all

CheckTicketNumber(TicketNumber) {
   For Process In ComObjGet("winmgmts:").ExecQuery("Select CommandLine from Win32_Process where Name = 'AutoHotkey.exe'")
      If InStr(Process.CommandLine, TicketNumber) ; oder ähnlich
         Return True
   Return False
}
Edit: "Select CommandLine ...

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by Jovannb » 02 Mar 2018, 05:15

Hi,

An die B.AHK übergebe ich (von der A.AHK aus) einen (Commandline-) Parameter aus "#-#" und der Ticketnummer somit "#-#20180302110703104" (Datum-Uhrzeit-Millisekunden). Die Ticketnummer kommt dabei aus der Datenbank und werden beim Speichern der zu übermittelten Message dorthin vom Message-Sender-AHK geschrieben.

Ich habe mittlerweile in A.AHK eine Funktion die alle Commandlines aller laufenden B.AHK's holt.
Dann werden in der A.AHK die Commandlines (der B.AHK's die laufen) durchsucht ob darin der (eindeutige) String "#-#20180302110703104" vorkommt.
Wenn nein, wird eine neue B.AHK mit dieser Ticketnummer gestartet, wenn ja, dann wird keine neue B.AHK gestartet, da die relevante Message (zu diesem Ticket) eh schon am Schirm angezeigt wird.

Somit kann ich
-- eindeutig in A.AHK rausfinden was bereits wie läuft (für welches Ticket es schon eine bereits laufende Messaging B.AHK gibt)
-- der B.AHK die Ticketnummer übergeben, braucht die um das Bestätigen der angezeigten Message mit SQL in die Messaging-Datenbank zurückzuschreiben

Da ich in den GUI-Titeln der B.AHK auch was anderes anzeigen will, wie die Ticketnummer (z.B. Absender, Eingangsuhrzeit oder sonst was) ist mir die Lösung mit den PID's und dann dem Raussuchen der Commandline dazu per WMI lieber, ich bin flexibler.

J.B.

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by BoBo » 02 Mar 2018, 05:00

Supi! Danke für die Lösung :thumbup: Yo, das war mir bewußt. :)

PS. wer sich erstmals an SQL versuchen möchte (der datenbankabfragesprache welche in obiger funktion benutzt wird) dem sei eines der lernportale
wie :arrow: Udemy oder :arrow: Skillshare empfohlen. Gibts einiges für lau! Wer sich schulungsvideotechnisch selbstverwirklichen möchte kann diese dort ebenfalls veröffentlichen.

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by just me » 02 Mar 2018, 03:46

Moin,

ich hätte da noch eine alternative Idee. Wenn Du die als Parameter übergebene 'Ticketnummer' im Fenstertitel der "B"-Fenster unterbringst und der einen eindeutigen Begriff wie z.B. 'Ticket - ' voranstellst, kannst Du Dir eine Liste aller vorhandenen "B"-Fenster mit z.B.

Code: Select all

SetTitleMatchMode, 1 ; oder was Du brauchst
WinGet, IdList, List, Ticket - ahk_class AutoHotkeyGUI
einlesen. Dann kannst Du Dir in einer einfachen Schleife die Fenstertitel holen und abgleichen.

@BoBo:
Wenn Du die Abfrage auf eine PID begrenzt, kann die Antwort immer nur maximal einen Prozess liefern:

Code: Select all

#NoEnv
Process, Exist
PID := ErrorLevel
Global objWMIService := ComObjGet("winmgmts:")
MsgBox % pGet(PID, "CommandLine")

pGet(PID, item) {
   For Process In objWMIService.ExecQuery("SELECT " . item . " FROM Win32_Process where ProcessID = " . PID)
      Return Process[item]
}

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by BoBo » 02 Mar 2018, 03:22

Mal eine Frage ...

F12::MsgBox % pGet(PID,"CommandLine")

pGet(PID,item) {
...
colItems := objWMIService.ExecQuery("SELECT " . item . " FROM Win32_Process where ProcessID = " . PID)._NewEnum ; das funzt
...
Return objItem.%item% ; funzt nicht. In keiner mir bekannten schreibweise ...
}
Wie läßt sich der gesuchte parameter beim funktionsaufruf als string übergeben, und anschließend als variablenbezeichner zur ausgabe verwenden? :?:

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by Jovannb » 01 Mar 2018, 12:13

Hi,

das mit den CHR(39) stimmt, ich habe mir (SQL sei Dank) aber angewöhnt, die div. Strings immer so nachzubilden wie sie "nativ" laufen, den Umweg über die zusätzliche Variable "wmi_request" nehme ich gerne.

Der "inner Index" funktioniert aber dann nicht mehr, wenn du mehr wie einen Parameter (in dem Fall nur "Commandline" im SQL-Statement) abfrägst, dann hat nämlich die While-Schleife einen eigenen A_INDEX, wenns nur ein Parameter ist, dann ist es egal.

J.B.

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by BoBo » 01 Mar 2018, 12:04

@JB
ich denke das du a) die "outer_index"-variable auch gegen A_Index austauschen könntest, und b) hat bei mir problemlos auch diese variante funktioniert ...

Code: Select all

colItems := objWMIService.ExecQuery("SELECT CommandLine FROM Win32_Process where ProcessID = " . PID)._NewEnum
... heisst, ohne die chr(39)
8-)

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by Jovannb » 01 Mar 2018, 10:40

Hi,

und hier noch der Script, wie man an alle Commandlines aller laufenden AHK-Scripts rankommt:

Code: Select all

#SingleInstance force
buffer:=object()

DetectHiddenWindows, On
WinGet, AHK, List, ahk_class AutoHotkey	; hol die Liste aller laufenden AHK-Prozesse
outer_index:=1

Loop, %ahk%								; in einer Schleife durchlaufen
{
	WinGet, PID, PID, % "ahk_id " AHK%outer_index%		; die PID der AHK-Prozesse holen
	
	objWMIService := ComObjGet("winmgmts:\\.\root\cimv2")
	wmi_request:="Select CommandLine FROM Win32_Process where ProcessID=" chr(39) pid chr(39)		; chr(39) = '
	colItems := objWMIService.ExecQuery(wmi_request)._NewEnum		; für diese PID die Kommandozeile mit WMI holen
	
	While colItems[objItem]
	{
	   buffer[outer_index] := objItem.Commandline					; Array mit allen Kommandozeilen aller laufenden AHK-Scripts
   }
   outer_index++
}

; ergibt eine Objekt/ein Array wie folgt:
;
; buffer[1] = ""C:\Program Files\AutoHotkey\AutoHotkey.exe" "V:\XXXXXx_progr\office_helper.ahk" "
; ....
; buffer[y] ...
return
J.B.

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by Jovannb » 01 Mar 2018, 10:37

Hi,

wir haben ein internes Messaging System, da kriegt User A eine Message X, kurz danach kriegt er eine Messagy Y, die sieht er aber erst, wenn er X abgearbeitet (bestätigt) hat. Das ist eigentlich Mist.

Genau darum gehts, mit AHK kann er bliebig viele Messages (Prozesse) kriegen und die abarbeiten wir er will, die GUI's der Prozesse/Instanzen laufen als modale Fenster. Der User kann das jetzt bearbeiten wir er will. Solange er eine Message nicht als bearbeitet bestätigt hat, kommt die immer wieder - auch wenn er den PC aus/ein schaltet, denn der A-Task checkt die Datenbank auf unerledigte Messages und bringt die (immer nur 1 x am Schirm - drum muss ich ja checken ob diese eine Message bereits angezeigt wird) mit einem eigenen Prozess B auf den Schirm.

Das Problem das ich noch habe ist, dass (unter Windows 10) jetzt Instanz/Prozess B am Taskbar (Bildschirm mitte unten) sichtbar ist, aber da bin ich dran.
Den Rest habe ich jetzt schon recht gut im Griff u.a danke euch, merci

J.B.

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by BoBo » 01 Mar 2018, 10:13

just me wrote:Du könntest Dir das Leben einfacher machen, wenn Du die "B"-Instanz kompilierst. Zumindest dann liefert die Run-Anweisung auch die PID.
Run, Ziel , Arbeitsverz, Max|Min|Hide|UseErrorLevel, AusgabeVarPID
Es spricht aber auch nichts gegen WMI.
Daran hätte ich auch gedacht, zumal ihm die msgID zum aufruf von"B" ja bereits bekannt ist.
Was sich mir bis gerade eben verschloßen hat - wie zeitgleich mehrere instanzen von b.ahk laufen sollen!? Nun, kaum das mann nach jahren mal bei SingleInstance, Force vorbeischaut, schon fällt einem der 'OFF'-parameter auf :crazy:

Zum obigen WMI aufruf habe ich hier noch etwas gepostet: https://autohotkey.com/boards/viewtopic ... 82#p203482

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by just me » 01 Mar 2018, 09:39

Du könntest Dir das Leben einfacher machen, wenn Du die "B"-Instanz kompilierst. Zumindest dann liefert die Run-Anweisung auch die PID.
Run, Ziel , Arbeitsverz, Max|Min|Hide|UseErrorLevel, AusgabeVarPID
Es spricht aber auch nichts gegen WMI.

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by Jovannb » 01 Mar 2018, 09:29

Hi Just me,

a) stimmt, das ging mit dem Speichern der PID, nur wenn ich die B.AHK Instanz starte mit

Code: Select all

run, gui_client.ahk %zeitle% %ypos% %xpos%
dann habe ich die aktuelle PID (der damit gestarteten B-Instanz) nicht und da ja bereits mehrere B-Instanzen laufen, ist das dann auch wieder recht tricky.
Einen Trick um beim "run-Start" die PID zurückzukriegen kenne ich nicht.

Aber ich bin jetzt einen Schritt weiter:

-- WMI mit dem Aufruf "Select CommandLine, ProcessId FROM Win32_Process" liefert das zurück:
CommandLine : "C:\Program Files\AutoHotkey\AutoHotkey.exe" "C:\Program Files\AutoHotkey\scripts\Messenger_Notes\gui_client.ahk" "01. 03. 2018 / 15:18:13" 201 1100

Dabei ist gui_client.ahk die B-Instanz und "01. 03. 2018 / 15:18:13" der gesuchte Parameter1.

Jetzt kann ich über den Namen des Skripts die relevanten (sprich die B-Instanzen) raussuchen, dann den Parameter1 checken und voila, wieder einen Schritt weiter.

Danke für eure Inputs.

J.B.

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by just me » 01 Mar 2018, 09:23

Wenn "A" durchläuft, wozu brauchst Du dann eine INI? Du kannst doch den "Parameter1" in einem Array speichern und mit der PID der "B"-Instanz verknüpfen. "A" kann dann per Timer regelmäßig prüfen, ob noch ein Prozess mit der PID läuft. Wenn nicht, wird der Eintrag aus dem Array entfernt.

Wie startest Du die "B"-Instanzen?

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by Jovannb » 01 Mar 2018, 09:06

Hi

wenn A den Startparameter1 jeder B-Instanz speichert (INI-File), dann kann

-- die B-Instanz planmässig geschlossen werden und dann im Speicher sagen, dass Sie "zu" ist .. passt, alles cosy

-- die B-Instanz aber abstürzen, der Task gekillt wird oder was auch immer, dann steht im Speicher (der INI) immer noch drin, dass eine B-Instanz mit XYZ als Parameter läuft, was dann gar nicht stimmt

Drum, "sauber" kriege ich das nur hin, wenn es die A.AHK schafft alle laufenden B.AHK's quasi zu Fragen, hat eine von euch schon den Parameter "0815", wenn nein dann starte eine B-Instanz mit dem Parameter "0815", wenn ja, dann tu nichts, läuft ja eh schon.

Ich hab schon probiert den Titel (die B-Instanzen haben ja alle Gui's mit einem Titel) auszulesen, dazu finde ich aber auch keinen Weg. Da man aber den Pfad aller laufenden B-Instanzen recht einfach lesen kann, denke ich, dass es eine Weg gibt, auch die Startparameter einer jeden B-Instanz auszulesen.

J.B.

Re: Parameter eines laufenden AHK-Scripts abrufen

Post by just me » 01 Mar 2018, 08:56

Moin,

so richtig verstehe ich das Problem nicht. App A startet App B (ggf. mehrfach) mit Parametern, vermutlich per Run-Anweisung. Dann weiß doch App A jederzeit, mit welchen Parametern sie Instanzen von App B gestartet hat. Übersehe ich da etwas?

Parameter eines laufenden AHK-Scripts abrufen

Post by Jovannb » 01 Mar 2018, 08:35

Hi,

die AHK-App (A) läuft im Loop und liest eine Datenbank (SQL, MSACCESS) aus, je nach DB-Status nimmt die (A) einen Parameter aus der DB (u.a. die Message-ID) und ruft die AHK-APP (B) mit dem Parameter1 (der Message ID) auf.

Um nun zu vermeiden, dass diesel Message-ID mehrfach dargestellt wird, sprich dass die (B) mehrfach mit dem gleichen Parameter1 aufgerufen wird, soll die (A) vor dem Auruf von (B) prüfen ob bereits eine Instanz der (B) läuft, die mit demselben Parameter1 läuft, wie der der grad zum Aufruf vorgesehen ist.

Aus Stabilitätstgründen will ich das nicht in irgendwelche Files oder die Registry schreiben, denn wenn mal ein Task abschmiert oder geschlossen wird, ist das ganze System im Eimer, instabil, unklar.
Ich will in (A) alle PID's der laufenden Instanzen von (B) holen - das geht bereits - und dann den Parameter1 einer jeden Instanz auslesen... genau daran happerts..

Wer kann mir da weiterhelfen ??

J.B.

Top