Seite 1 von 1

Dateiname eines mittels RunProgram gestrateten Programs?

Verfasst: 02.10.2013 14:03
von _JON_
Hallo, ich kann diesen Code benutzten um den Programmpfad von einer ProcessID zu erhalten

Code: Alles auswählen

Prototype pGetModuleFileNameEx_(hProcess.i, hModule.i, lpFilename.i, nSize.l)

If OpenLibrary(0, "psapi.dll")
  Global GetModuleFileNameEx_.pGetModuleFileNameEx_ = GetFunction(0, "GetModuleFileNameExW")
EndIf

If Not GetModuleFileNameEx_ : End : EndIf

Procedure.s FormatMessage(ErrorNumber.l)
  Protected *Buffer, len.l, result.s
  len = FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER|#FORMAT_MESSAGE_FROM_SYSTEM,0,ErrorNumber,0,@*Buffer,0,0)
  If len
    result = PeekS(*Buffer, len - 2)
    LocalFree_(*Buffer)
    ProcedureReturn result
  Else
    ProcedureReturn "Errorcode: " + Hex(ErrorNumber)
  EndIf
EndProcedure

Procedure.s GetProcessnameByPID(lPID.l)
  Protected hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, lPID)
  If hProcess
    Debug "Process Handle: " + Str(hProcess)
    Protected szPath.s = Space(4096)
    If GetModuleFileNameEx_(hProcess, 0, @szPath, 4096)
      Debug "ModuleFileName: " + szPath
    Else
      Debug "FileName Error: " + FormatMessage(GetLastError_())
    EndIf
    CloseHandle_(hProcess)      
    ProcedureReturn szPath
  Else
    Debug "OpenProcess Error" + FormatMessage(GetLastError_())
  EndIf
EndProcedure

Debug GetProcessnameByPID(500) ;PID eines Processes ermittelt mit Process Explorer XP
Wenn ich aber das Programm mittel RunProgram() und den Flag #PB_Program_Open starte geht das nicht mehr

Code: Alles auswählen

Prototype pGetModuleFileNameEx_(hProcess.i, hModule.i, lpFilename.i, nSize.l)

If OpenLibrary(0, "psapi.dll")
  Global GetModuleFileNameEx_.pGetModuleFileNameEx_ = GetFunction(0, "GetModuleFileNameExW")
EndIf

If Not GetModuleFileNameEx_ : End : EndIf

Procedure.s FormatMessage(ErrorNumber.l)
  Protected *Buffer, len.l, result.s
  len = FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER|#FORMAT_MESSAGE_FROM_SYSTEM,0,ErrorNumber,0,@*Buffer,0,0)
  If len
    result = PeekS(*Buffer, len - 2)
    LocalFree_(*Buffer)
    ProcedureReturn result
  Else
    ProcedureReturn "Errorcode: " + Hex(ErrorNumber)
  EndIf
EndProcedure

Procedure.s GetProcessnameByPID(lPID.l)
  Protected hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, lPID)
  If hProcess
    Debug "Process Handle: " + Str(hProcess)
    Protected szPath.s = Space(4096)
    If GetModuleFileNameEx_(hProcess, 0, @szPath, 4096)
      Debug "ModuleFileName: " + szPath
    Else
      Debug "FileName Error: " + FormatMessage(GetLastError_())
    EndIf
    CloseHandle_(hProcess)      
    ProcedureReturn szPath
  Else
    Debug "OpenProcess Error" + FormatMessage(GetLastError_())
  EndIf
EndProcedure


Program = RunProgram("cmd.exe", "/k echo hallo world", "", #PB_Program_Open)
If IsProgram(Program)
  Debug "ProcessID     : " + Str(ProgramID(Program))
  GetProcessnameByPID(ProgramID(Program))
  CloseProgram(Program)
EndIf
Weiß jemand warum das so ist?

Re: Dateiname eines mittels RunProgram gestrateten Programs?

Verfasst: 02.10.2013 14:21
von RSBasic
@_JON_
Da du nicht wartest, bis die von dir gewünschten Anwendung vollständig gestartet wurde, kann deine Prozedur nicht darauf zugreifen, weil es noch beim Initialisieren ist.
Wenn du nach RunProgram() ein Delay() einfügst, dann hast du das Problem nicht mehr.

\\Edit:
Also etwa so:

Code: Alles auswählen

EnableExplicit

Define Program

Procedure.s GetProcessPathByPID(PID)
  Protected.MODULEENTRY32 Entry
  
  Entry\dwSize = SizeOf(MODULEENTRY32)
  If Module32First_(CreateToolhelp32Snapshot_(#TH32CS_SNAPMODULE, PID), Entry)
    ProcedureReturn PeekS(@Entry\szExePath)
  EndIf
EndProcedure

Program = RunProgram("cmd.exe", "/k echo hallo world", "", #PB_Program_Open)
Delay(100)
If IsProgram(Program)
  Debug GetFilePart(GetProcessPathByPID(ProgramID(Program)))
  
  CloseProgram(Program)
EndIf

Re: Dateiname eines mittels RunProgram gestrateten Programs?

Verfasst: 02.10.2013 14:49
von _JON_
Danke RSBasic :allright:

Ich bin aber auch wieder ein Trottel, das sofort nach IsProgram(Program) abzufragen.