Seite 1 von 1

ProcessID - geht nur bei einthreadigen Anwendungen ¿?

Verfasst: 15.05.2013 17:37
von bobobo
folgender Code funktioniert wunderbar ..
Aber ersetze ich notepad.exe (oder ein anderes einthreadiges Programm wie calc und was sonst alles so
gerne als Demo genommen wird) durch Excel.exe oder Windword.exe oder Firefox.exe dann scheitert
ProgramID(..), das dann immer -1 zurückgibt und damit die Ermittlung des Processhandles scheitert.

Kann man das ProcessHandle immer korrekt ermitteln ?

Code: Alles auswählen

Procedure SetPriority(ProgramID.l, PriorityLevel.l)
  Protected ProcessHandle.l

  ProcessHandle = OpenProcess_(#PROCESS_DUP_HANDLE + #PROCESS_SET_INFORMATION, #True, ProgramID)
  If ProcessHandle
    SetPriorityClass_(ProcessHandle, PriorityLevel)
    CloseHandle_(ProcessHandle)
  EndIf
EndProcedure

Result = RunProgram("Notepad.exe", "", "", #PB_Program_Open)

If Result
  Debug Result
  Debug ProgramID(Result)
  SetPriority(ProgramID(Result), #IDLE_PRIORITY_CLASS)     ; niedrige Prioritätsstufe
  MessageRequester("","")
  KillProgram(Result)
  CloseProgram(Result)
EndIf

Re: ProcessID - geht nur bei einthreadigen Anwendungen ¿?

Verfasst: 15.05.2013 19:57
von NicTheQuick
Von vielen Programmen laufen schon Prozesse im Hintergrund, denen dann nur noch gesagt wird, dass sie in neues Fenster öffnen sollen. Kurz darauf wird der eigentlich gestartete Prozess wieder beendet. Deswegen findest du dann keine Prozess-ID mehr.

Re: ProcessID - geht nur bei einthreadigen Anwendungen ¿?

Verfasst: 15.05.2013 19:59
von bobobo
Und wie finde ich die dann ?

Re: ProcessID - geht nur bei einthreadigen Anwendungen ¿?

Verfasst: 15.05.2013 20:47
von RSBasic

Code: Alles auswählen

EnableExplicit

Define ProcessID

#kExit_Code_Error=1
#kExit_Code_Success=0

Procedure SetPriority(ProgramID.l, PriorityLevel.l)
  Protected ProcessHandle.l

  ProcessHandle = OpenProcess_(#PROCESS_DUP_HANDLE | #PROCESS_SET_INFORMATION, #True, ProgramID)
  If ProcessHandle
    SetPriorityClass_(ProcessHandle, PriorityLevel)
    CloseHandle_(ProcessHandle)
  EndIf
EndProcedure

Procedure GetProcessId_(hProcess)
  Static *pGetProcessId
 
  If Not *pGetProcessId
    *pGetProcessId=GetProcAddress_(GetModuleHandle_("kernel32.dll"),"GetProcessId")
  EndIf
 
  If Not *pGetProcessId
    ProcedureReturn 0
  EndIf
 
  ProcedureReturn CallFunctionFast(*pGetProcessId,hProcess)
EndProcedure

Procedure RunProgram_(ProgramName.s, Parameter.s="", WorkingDirectory.s="", Visible=#SW_SHOW)
  Protected ShellExInfo.SHELLEXECUTEINFO
 
  ShellExInfo\cbSize=SizeOf(ShellExInfo)
  ShellExInfo\fMask=#SEE_MASK_NOCLOSEPROCESS
  ShellExInfo\lpVerb=@"Open"
  ShellExInfo\lpFile=@ProgramName.s
  ShellExInfo\lpParameters=@Parameter.s
  ShellExInfo\lpDirectory=@WorkingDirectory.s
  ShellExInfo\nShow=Visible
 
  ShellExecuteEx_(@ShellExInfo)
 
  ProcedureReturn GetProcessId_(ShellExInfo\hProcess)
EndProcedure

ProcessID = RunProgram_("winword.exe")
Debug ProcessID
If ProcessID
  SetPriority(ProcessID, #IDLE_PRIORITY_CLASS)
EndIf

Re: ProcessID - geht nur bei einthreadigen Anwendungen ¿?

Verfasst: 15.05.2013 21:11
von ts-soft

Code: Alles auswählen

#PROCESS_DUP_HANDLE + #PROCESS_SET_INFORMATION
ist in diesem Falle zwar dasselbe wie:

Code: Alles auswählen

#PROCESS_DUP_HANDLE | #PROCESS_SET_INFORMATION
aber ... :wink:

Re: ProcessID - geht nur bei einthreadigen Anwendungen ¿?

Verfasst: 15.05.2013 21:14
von RSBasic
Habs angepasst. Danke Thomas. :D

Re: ProcessID - geht nur bei einthreadigen Anwendungen ¿?

Verfasst: 16.05.2013 16:32
von bobobo
sehr schön :allright: .. aber nur mit ohne Unicode (was nicht so wild ist)

Re: ProcessID - geht nur bei einthreadigen Anwendungen ¿?

Verfasst: 16.05.2013 16:52
von ts-soft
bobobo hat geschrieben:sehr schön :allright: .. aber nur mit ohne Unicode (was nicht so wild ist)

Code: Alles auswählen

EnableExplicit

Define ProcessID

#kExit_Code_Error=1
#kExit_Code_Success=0

Procedure SetPriority(ProgramID.l, PriorityLevel.l)
  Protected ProcessHandle.l

  ProcessHandle = OpenProcess_(#PROCESS_DUP_HANDLE | #PROCESS_SET_INFORMATION, #True, ProgramID)
  If ProcessHandle
    SetPriorityClass_(ProcessHandle, PriorityLevel)
    CloseHandle_(ProcessHandle)
  EndIf
EndProcedure

Procedure GetProcessId_(hProcess)
  Static *pGetProcessId
  Protected *func = AllocateMemory(13)
  PokeS(*func, "GetProcessId", -1, #PB_Ascii)
  If Not *pGetProcessId
    *pGetProcessId=GetProcAddress_(GetModuleHandle_("kernel32.dll"),*func)
  EndIf
 
  If Not *pGetProcessId
    ProcedureReturn 0
  EndIf
  FreeMemory(*func)
  ProcedureReturn CallFunctionFast(*pGetProcessId,hProcess)
EndProcedure

Procedure RunProgram_(ProgramName.s, Parameter.s="", WorkingDirectory.s="", Visible=#SW_SHOW)
  Protected ShellExInfo.SHELLEXECUTEINFO
 
  ShellExInfo\cbSize=SizeOf(ShellExInfo)
  ShellExInfo\fMask=#SEE_MASK_NOCLOSEPROCESS
  ShellExInfo\lpVerb=@"Open"
  ShellExInfo\lpFile=@ProgramName.s
  ShellExInfo\lpParameters=@Parameter.s
  ShellExInfo\lpDirectory=@WorkingDirectory.s
  ShellExInfo\nShow=Visible
 
  ShellExecuteEx_(@ShellExInfo)
 
  ProcedureReturn GetProcessId_(ShellExInfo\hProcess)
EndProcedure

ProcessID = RunProgram_("textmaker.exe")
Debug ProcessID
If ProcessID
  SetPriority(ProcessID, #IDLE_PRIORITY_CLASS)
EndIf 
Ohne / Mit Unicode :mrgreen: