ControlSend zeigt keine Wirkung

12/01/2013 17:31 erudite#1
Hey.

Wo liegt der Fehler?

Danke im Voraus! :handsdown:
PHP Code:
    ;Author


#include "KDMemory.au3"
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Pointer.au3>
#Include <GuiListView.au3>
#include <crypt.au3>
#Include <Timers.au3>

#Region ### START Koda GUI section ### Form=
$Form1 GUICreate("Form1"326133192164)
$Button GUICtrlCreateButton("On"128569717)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###


Dim $handles 0
Const $processName "TClient.exe"



While 1
        $msg 
GUIGetMsg()
        If 
$msg == -3 Then Exit ; $GUI_EVENT_CLOSE

        $processId 
ProcessExists($processName)
        If 
$processId == 0 Then
        
If IsArray($handlesThen
            _KDMemory_CloseHandles
($handles)
            
$handles 0
        
EndIf
        
ContinueLoop
        
EndIf

        If 
$handles == 0 Then
        $handles 
_KDMemory_OpenProcess($processId)
        If @
error Then
            
If MsgBox(52"Error""Can't open " $processName "! @error: " & @error & @CRLF "Continue?") == 6 Then
                $handles 
0
                ContinueLoop
            
Else
                Exit
            EndIf
        EndIf
        EndIf


        If  
$msg $Button Then

                ControlSend 
("4Story_GSP","","","i")

        EndIf



    
WEnd 
12/01/2013 18:40 KDeluxe#2
Lass mich raten: Einfach alles zusammen kopiert?
GUI Events solltest du zu Beginn der While-Schleife abarbeiten (siehe Bedingung für "Exit").

Wofür ein Handle zum Lesen und Schreiben erstellen, wenn du es nicht machst? Mehr als ein ControlSend() machst du nicht, dafür brauchst du meine KDMemory.au3 UDF nicht. Da die offiziellen Server einen (schlechten) "Hackshield" verwenden kannst du die Control Befehle nicht verwenden. Den Speicher lesen und schreiben kannst du auch nicht ohne weiteres.

Es ist eigentlich nichts wirklich falsch, dass der Befehl nicht funktioniert liegt schlichtweg am Spiel.
12/01/2013 19:27 erudite#3
Quote:
Originally Posted by KDeluxe View Post
Lass mich raten: Einfach alles zusammen kopiert?


Wofür ein Handle zum Lesen und Schreiben erstellen, wenn du es nicht machst? Mehr als ein ControlSend() machst du nicht, dafür brauchst du meine KDMemory.au3 UDF nicht. Da die offiziellen Server einen (schlechten) "Hackshield" verwenden kannst du die Control Befehle nicht verwenden. Den Speicher lesen und schreiben kannst du auch nicht ohne weiteres.

Es ist eigentlich nichts wirklich falsch, dass der Befehl nicht funktioniert liegt schlichtweg am Spiel.
1. Ja ich habe den oberen Teil kopiert. Wieso auch nicht? (Er funktionierte bis jetzt immer, da er von dir geschrieben ist. :D )
2. Ich habe das Handle eingebaut, weil ich noch mehr einbauen will, wofür ich es brauche.
3. Es kann nicht am HS liegen, da das Spiel, wofür ich das Programm schreibe, kein HS hat.

Fazit: Grundsätzlich erkennst du keine Fehler bis auf die Tatsache, dass man GUI Events zu Beginn der While-Schleife setzen sollte.
MHM :S woran könnte es dann liegen?

Danke :)
12/01/2013 19:39 alpines#4
Konntest du bisher überhaupt ein Resultat erreichen?
Ansonsten kannst du es mit einem simplen Send (zuerst) versuchen und dann, sofern es nicht geht, _SendMessage.
12/01/2013 19:51 erudite#5
Quote:
Originally Posted by alpines View Post
Konntest du bisher überhaupt ein Resultat erreichen?
Ansonsten kannst du es mit einem simplen Send (zuerst) versuchen und dann, sofern es nicht geht, _SendMessage.
Also eigentlich soll das Programm ja das Inventar mit "i" öffnen.
Man kann das auch via Memory Write machen, allerdings wollte ich es einmal so ausprobieren.

Jedoch öffnet sich das Inventar nicht.

Aber ich werde deine Vorschläge mal ausprobieren. :) Danke
12/01/2013 19:56 alpines#6
Die MemoryWrite Variante wäre meiner Meinung nach sicherer, da du nachprüfen kannst ob es sich wirklich geöffnet hat und du nicht per PixelSearch danach suchen musst.
12/01/2013 20:00 erudite#7
Quote:
Originally Posted by alpines View Post
Die MemoryWrite Variante wäre meiner Meinung nach sicherer, da du nachprüfen kannst ob es sich wirklich geöffnet hat und du nicht per PixelSearch danach suchen musst.
Ja, das Inventar ist in diesem Falle nur ein Beispiel.

Ich will eigentlich nur mein Wissen etwas erweitern und ein wenig herumprobieren und dabei ist mir eben die Frage gekommen, wie ich bestimmte Befehle "simulieren" kann.
12/01/2013 22:29 KDeluxe#8
Das sollte man meiner Meinung nach immer mit dem Speicher lösen (kommt natürlich auf die Anwendung drauf an). Ich kann mich auch irren, aber ControlSend() dürfte allgemein nicht funktionieren. PostMessage funktioniert allerdings, das weiß ich noch, da ich jemandem dabei geholfen habe.
Bei 4Story hast du es noch sehr einfach, sämtliche Fenster im Spiel lassen sich über "0" ausblenden und "1" einblenden.

Mit meinem Beispiel möchte ich dir ebenfalls den einfachen Aufbau der Pointer von 4Story verdeutlichen:

Falls du das ganze dennoch mit PostMessage probieren möchtest kannst du dafür [Only registered and activated users can see links. Click Here To Register...] verwenden.
12/01/2013 23:26 Logtetsch#9
Ich würde es ebenfalls über die RAM machen.
Sowie du ControlSend benutzt, kann es zu schwerwigenden Fehlern führen. Stell dir vor du hast mehrere Fenster offen, welche alle den gleichen Fensternamen ("4Story_GSP") besitzen. Da ich nicht weiß, wie ProcessExists mit Prozessen umgeht, die es mehrmals gibt, solltest du vorab prüfen, ob 4Story nur einmal läuft. Eventuell gibt es sogar schon Bibliotheken für AutoIt, die die Funktion createtoolhelp32snapshot implementiert haben und genaueres über aktive Prozesse sagen können.
12/02/2013 03:04 KDeluxe#10
[Only registered and activated users can see links. Click Here To Register...] verwende ich in meiner KDMemory UDF um die Module eines Prozesses durchzugehen. Das wäre auch einfacher gegangen, allerdings wollte ich ausschließlich Funktionen der Kernel32.dll verwenden. Meine Basis könnte man theoretisch ganz einfach ändern.
Verwendet man ausschließlich den RAM kann es einem egal sein, wie viele Fenster den selben Namen verwenden. Möchte man eine Kombination aus RAM und "Fenster" muss man dem Fenster einen Prozess zuordnen können. Das kann man mittels WinList() und WinGetProcess() (unbedingt das Window Handle (HWND) übergeben) lösen.