Dateiname eines mittels RunProgram gestrateten Programs?

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
_JON_
Beiträge: 389
Registriert: 30.03.2010 15:24

Dateiname eines mittels RunProgram gestrateten Programs?

Beitrag 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?
PureBasic 5.46 LTS (Windows x86/x64) | windows 10 x64 Oktober failure
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Dateiname eines mittels RunProgram gestrateten Programs?

Beitrag 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
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
_JON_
Beiträge: 389
Registriert: 30.03.2010 15:24

Re: Dateiname eines mittels RunProgram gestrateten Programs?

Beitrag von _JON_ »

Danke RSBasic :allright:

Ich bin aber auch wieder ein Trottel, das sofort nach IsProgram(Program) abzufragen.
PureBasic 5.46 LTS (Windows x86/x64) | windows 10 x64 Oktober failure
Antworten