Ich habe nun verschiedene DLL's und Target-Test-EXE (um sicher zu sein, dass genau DER API-Aufruf auch vorhanden ist).
Da mir das Handling damit zu nervig wurde habe ich für Josh's Inject / Eject eine alternative Öberfläche gebastelt.
Es ist zwar nur ein bescheidener Beitrag, aber vielleicht kann es jemand gebrauchen.
Code: Alles auswählen
DisableDebugger
;- Variablen und Konstanten
Global Window_0, G_Target_Text, G_Target, G_Inject, G_Eject, G_DLL, G_EXE
Global Target.s ; Text der Titelzeile eines Fensters
Global Target_valid, Dll_valid
Global Dll_Url.s
Define Dll_Path.s = GetCurrentDirectory()
;Define msg .s
;-
Procedure.i CodeInject (WndName.s, DllName.s)
; kann unverändert übernommen werden
EndProcedure
Procedure.i CodeEject (WndName.s, DllName.s)
; kann unverändert übernommen werden
EndProcedure
Procedure.s GetTargetWindowTitle(hwnd)
Protected Length
Protected *Buffer
Length = GetWindowTextLength_(hwnd)+1
*Buffer = AllocateMemory(Length)
GetWindowText_(hwnd,*Buffer,Length)
ProcedureReturn PeekS(*Buffer)
EndProcedure
;-
Procedure G_TargetEvent(Event) ; später richtige Prüfung - Hotpatch möglich ?
If EventType() = #PB_EventType_Change
Target = GetGadgetText(G_Target)
If Target <> ""
Target_valid = #True
Else
Target_valid = #False
EndIf
Debug "G_Target Change"
EndIf
EndProcedure
Procedure G_ClearEvent(Event)
SetGadgetText(G_Target, "")
Target_valid = #False
DisableGadget(G_Inject, #True)
DisableGadget(G_Eject, #True)
EndProcedure
Procedure G_InjectEvent(Event)
CodeInject (Target.s, Dll_Url.s)
Debug "G_Inject Event"
EndProcedure
Procedure G_EjectEvent(Event)
CodeEject (Target.s, Dll_Url.s)
Debug "G_Eject Event"
EndProcedure
Procedure G_DLLEvent(Event) ; später richtige Prüfung - Hook-Dll oder nur Dll ?
If EventType() = #PB_EventType_LeftClick Or EventType() = #PB_EventType_RightClick
entry = GetGadgetState(G_DLL)
If entry <> -1
Dll_Url = GetGadgetText(G_DLL) + GetGadgetItemText(G_DLL, entry, 0)
Dll_valid = #True
Debug "G_DLL Click - " + Dll_Url
Else
Dll_valid = #False
Debug "G_DLL Click - " + "keine verwertbare Auswahl"
EndIf
EndIf
EndProcedure
Procedure G_EXEEvent(Event)
If EventType() = #PB_EventType_LeftClick Or EventType() = #PB_EventType_RightClick
entry = GetGadgetState(G_EXE)
If entry <> -1
EXE_Url.s = GetGadgetText(G_EXE) + GetGadgetItemText(G_EXE, entry, 0)
Injector.s = GetWindowTitle(Window_0)
i = 0
If RunProgram(EXE_Url)
Repeat
Delay(50)
i = i + 1
hwnd = GetForegroundWindow_()
Target = GetTargetWindowTitle(hwnd)
Until Target <> Injector Or i = 25
If i < 26
SetGadgetText(G_Target, GetTargetWindowTitle(hwnd))
Target_valid = #True
EndIf
EndIf
Debug "G_EXE Click - " + EXE_Url
Else
Debug "G_EXE Click - " + "keine verwertbare Auswahl"
Target_valid = #False
EndIf
EndIf
EndProcedure
;- Main
;Prüfen ob Programm nicht in Unicode compiliert
If #PB_Compiler_Unicode
MessageRequester ("Inject / Eject", "Das Programm darf nicht in Unicode compiliert werden", #MB_ICONERROR)
End
EndIf
Window_0 = OpenWindow(#PB_Any, 0, 0, 600, 600, "", #PB_Window_SystemMenu)
G_Target_Text = TextGadget(#PB_Any, 10, 10, 100, 20, "Target Title")
G_Target = StringGadget(#PB_Any, 10, 30, 555, 25, "")
G_Clear = ButtonGadget(#PB_Any, 565, 30, 25, 25, "X")
G_Inject = ButtonGadget(#PB_Any, 10, 65, 100, 25, "Inject")
G_Eject = ButtonGadget(#PB_Any, 490, 65, 100, 25, "Eject")
G_DLL = ExplorerListGadget(#PB_Any, 10, 100, 580, 240, Dll_Path + "*.dll", #PB_Explorer_AutoSort|#PB_Explorer_AlwaysShowSelection|#PB_Explorer_FullRowSelect)
G_EXE = ExplorerListGadget(#PB_Any, 10, 350, 580, 240, Dll_Path + "*.exe", #PB_Explorer_AutoSort|#PB_Explorer_AlwaysShowSelection|#PB_Explorer_FullRowSelect)
DisableGadget(G_Clear, #True)
DisableGadget(G_Inject, #True)
DisableGadget(G_Eject, #True)
SetGadgetItemAttribute(G_DLL, 0, #PB_Explorer_ColumnWidth, 259)
SetGadgetItemAttribute(G_EXE, 0, #PB_Explorer_ColumnWidth, 259)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case G_Target : G_TargetEvent(Event)
Case G_Clear : G_ClearEvent(Event)
Case G_Inject : G_InjectEvent(Event)
Case G_Eject : G_EjectEvent(Event)
Case G_DLL : G_DLLEvent(Event)
Case G_EXE : G_EXEEvent(Event)
EndSelect
If Target_valid
DisableGadget(G_Clear, #False)
If Dll_valid
DisableGadget(G_Inject, #False)
DisableGadget(G_Eject, #False)
Else
DisableGadget(G_Inject, #True)
DisableGadget(G_Eject, #True)
EndIf
Else
DisableGadget(G_Clear, #True)
EndIf
EndSelect
Until event = #PB_Event_CloseWindow
Danke an alle !
Im Idealfall liegt das kompilierte Test-Tool mit allen DLL's und Target-Test-EXE in einem Verzeichnis.
Die Target-Test-EXE muss übrigens nicht unbedingt darüber aufgerufen werden. Man kann den Fenstertitel auch direkt eingeben.
Beispiel für eine Target-Test-EXE um zu verdeutlichen, dass es oft mehrere API-Wege zum Ziel gibt :
Code: Alles auswählen
Import "User32.lib"
MessageBoxA(Window.l, Body$, Title$, Flags.l = 0)
MsgBox(Window.l, Body$, Title$, Flags.l) As "_MessageBoxA@16"
EndImport
If OpenWindow(0, 200, 200, 200, 100, "Test")
ButtonGadget(0, 10, 10, 180, 20, "MessageRequester")
ButtonGadget(1, 10, 40, 180, 20, "MessageBoxA")
ButtonGadget(2, 10, 70, 180, 20, "MsgBox")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 0 : MessageRequester ("Test-Message", "MessageRequesterText", #PB_MessageRequester_Ok)
Case 1 : MessageBoxA(0, "MessageBoxAText", "Test-Message")
Case 2 : MsgBox(0, "MsgBoxText", "Test-Message", 0)
EndSelect
EndSelect
Until event = #PB_Event_CloseWindow
EndIf
End