[Module] PROCESS (Windows only!)

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

[Module] PROCESS (Windows only!)

Beitrag von Mijikai »

[Module] PROCESS

Eine Alternative zu PureBasics Process Bibliothek die unter Umständen mal Probleme macht.
(Wie z.B. mit FFMPEG: http://www.purebasic.fr/german/viewtopi ... =3&t=31202)

Verbesserungsvorschläge, Codes & neue Features sind gern gesehen :)

Geplant:
- Daten an den Prozess übergeben / PipeWrite()
- Einen String and den Prozess übergeben / PipeWriteString()
- Beenden des Prozesses / Kill()

Code:

Code: Alles auswählen


DeclareModule PROCESS
  Declare.i Create(File.s,Command.s,*Parameter = #Null,NoWindow.i = #False)
  Declare.i Handle(*Process)
  Declare.i Id(*Process)
  Declare.i Exit(*Process)
  Declare.i Output(*Process)
  Declare.i PipeRead(*Process,*Buffer,BufferSize.i,*BytesRead)
  Declare.i PipeReadBuffer(*Process)
  Declare.s PipeReadString(*Process)
  Declare.i Size(*Buffer)
  Declare.i Free(*Buffer)
  Declare.s File(*Process)
  Declare.s Command(*Process)
  Declare.i Parameter(*Process)
  Declare.i ExitCode(*Process)
  Declare.i Close(*Process)
EndDeclareModule

Module PROCESS
  
  EnableExplicit
  
  ;Module PROCESS
  ;Version: draft 2
  ;PureBasic v.5.62 
  ;Tested on Windows 7 x64
  
  Structure PROCESS_STRUCT
    File.s
    Command.s
    PipeRead.i
    PipeWrite.i
    Security.SECURITY_ATTRIBUTES
    Startup.STARTUPINFO
    Info.PROCESS_INFORMATION
    BytesAvailable.i
    *Parameter
  EndStructure
  
  Procedure.i Create(File.s,Command.s,*Parameter = #Null,NoWindow.i = #False)
    Protected *Process.PROCESS_STRUCT
    *Process = AllocateStructure(PROCESS_STRUCT)
    If *Process  
      With *Process
        \Security\bInheritHandle = #True
        If CreatePipe_(@\PipeRead,@\PipeWrite,@\Security,#Null)
          \Startup\cb = SizeOf(STARTUPINFO)
          \Startup\dwFlags = #STARTF_USESTDHANDLES
          \Startup\hStdInput = \PipeRead
          \Startup\hStdOutput = \PipeWrite
          \Startup\hStdError = \PipeWrite
          \File = File
          \Command = Command
          \Parameter = *Parameter
          If NoWindow
            NoWindow = #CREATE_NO_WINDOW
          EndIf
          If CreateProcess_(File,Command,@\Security,@\Security,#True,NoWindow,#Null,#Null,@\Startup,@\Info)
            ProcedureReturn *Process          
          EndIf
          CloseHandle_(\PipeRead)
          CloseHandle_(\PipeWrite)
        EndIf
      EndWith
      FreeStructure(*Process)
    EndIf 
  EndProcedure
  
  Procedure.i Handle(*Process.PROCESS_STRUCT)
    With *Process
      ProcedureReturn \Info\hProcess
    EndWith  
  EndProcedure
  
  Procedure.i Id(*Process.PROCESS_STRUCT)
    With *Process
      ProcedureReturn \Info\dwProcessId
    EndWith  
  EndProcedure
  
  Procedure.i Exit(*Process.PROCESS_STRUCT)
    With *Process
      ProcedureReturn Bool(WaitForSingleObject_(\Info\hProcess,#Null) <> #WAIT_TIMEOUT)
    EndWith  
  EndProcedure
  
  Procedure.i Output(*Process.PROCESS_STRUCT)
    With *Process
      If PeekNamedPipe_(\PipeRead,#Null,#Null,#Null,@\BytesAvailable,#Null)
        ProcedureReturn \BytesAvailable
      Else
        \BytesAvailable = #Null
      EndIf
    EndWith
  EndProcedure
  
  Procedure.i PipeRead(*Process.PROCESS_STRUCT,*Buffer,BufferSize.i,*BytesRead.Integer)
    With *Process
      If \BytesAvailable
        If BufferSize > \BytesAvailable
          BufferSize = \BytesAvailable
        EndIf
        If ReadFile_(\PipeRead,*Buffer,BufferSize,*BytesRead,#Null)
          \BytesAvailable - *BytesRead\i
          ProcedureReturn #True
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  Procedure.i PipeReadBuffer(*Process.PROCESS_STRUCT)
    Protected *Buffer
    Protected *Alloc
    Protected BufferSize.i
    With *Process
      If \BytesAvailable > #Null
        *Buffer = AllocateMemory(\BytesAvailable)
        If *Buffer
          If ReadFile_(\PipeRead,*Buffer,\BytesAvailable,@BufferSize,#Null)
            If BufferSize > #Null
              If BufferSize < \BytesAvailable
                *Alloc = ReAllocateMemory(*Buffer,BufferSize)
                If *Alloc
                  \BytesAvailable - BufferSize
                  ProcedureReturn *Alloc
                EndIf
              Else
                \BytesAvailable = #Null
                ProcedureReturn *Buffer
              EndIf
            EndIf
          EndIf
          FreeMemory(*Buffer)
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  Procedure.s PipeReadString(*Process.PROCESS_STRUCT)
    Protected *Buffer
    Protected BufferSize.i
    Protected Result.s
    With *Process
      If \BytesAvailable > #Null
        *Buffer = AllocateMemory(\BytesAvailable)
        If *Buffer
          If ReadFile_(\PipeRead,*Buffer,\BytesAvailable,@BufferSize,#Null)
            If BufferSize
              \BytesAvailable - BufferSize
              Result = PeekS(*Buffer,BufferSize,#PB_Ascii)
            EndIf
          EndIf 
          FreeMemory(*Buffer)
        EndIf 
      EndIf
    EndWith
    ProcedureReturn Result
  EndProcedure
  
  Procedure.i Size(*Buffer)
    ProcedureReturn MemorySize(*Buffer)
  EndProcedure
  
  Procedure.i Free(*Buffer)
    FreeMemory(*Buffer)
  EndProcedure
  
  Procedure.s File(*Process.PROCESS_STRUCT)
    With *Process
      ProcedureReturn \File
    EndWith
  EndProcedure
  
  Procedure.s Command(*Process.PROCESS_STRUCT)
    With *Process
      ProcedureReturn \Command
    EndWith
  EndProcedure
  
  Procedure.i Parameter(*Process.PROCESS_STRUCT)
    With *Process
      ProcedureReturn \Parameter
    EndWith
  EndProcedure
  
  Procedure.i ExitCode(*Process.PROCESS_STRUCT)
    Protected Code.i
    With *Process
      WaitForSingleObject_(\Info\hProcess,#INFINITE)
      GetExitCodeProcess_(\Info\hProcess,@Code)
      ProcedureReturn Code
    EndWith
  EndProcedure
  
  Procedure.i Close(*Process.PROCESS_STRUCT)
    With *Process
      CloseHandle_(\Info\hProcess)
      CloseHandle_(\Info\hThread)
      CloseHandle_(\PipeRead)
      CloseHandle_(\PipeWrite)
    EndWith
    FreeStructure(*Process)
  EndProcedure
    
EndModule

EnableExplicit

Global Handle.i
Global *Buffer
Global *BufferSize
Global *TestBuffer
Global TestReadBytes.i

Procedure.s FFMPEG(Video.s,Audio.s,File.s)
  Video = " -i " + #DQUOTE$ + Video + #DQUOTE$
  Video + " -i " + #DQUOTE$ + Audio + #DQUOTE$
  Video + " -vcodec h264 " + #DQUOTE$ + File + #DQUOTE$
  ProcedureReturn Video
EndProcedure

;DeleteFile("test.mp4")

*TestBuffer = AllocateMemory(1024)
If *TestBuffer
  Handle = PROCESS::Create("ffmpeg.exe",FFMPEG("test.webm","test.weba","test.mp4"),#Null,#True)
  If Handle
    Repeat
      If PROCESS::Output(Handle)
        Debug PROCESS::PipeReadString(Handle)
;         ;*Buffer = PROCESS::PipeReadBuffer(Handle)
;         ;If *Buffer
;         ; Debug PROCESS::Size(*Buffer)
;         ; PROCESS::Free(*Buffer)
;         ;EndIf
;         Debug PROCESS::PipeRead(Handle,*TestBuffer,1024,@TestReadBytes)
      EndIf
      
    Until PROCESS::Exit(Handle)
    Debug PROCESS::ExitCode(Handle)
    PROCESS::Close(Handle)
  EndIf
  FreeMemory(*TestBuffer)
EndIf

Repeat:Delay(100):ForEver
End
__________________________________________________
Domain angepasst und SID entfernt
11.12.2018
RSBasic
Zuletzt geändert von Mijikai am 10.12.2018 21:17, insgesamt 1-mal geändert.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: [Module] PROCESS (Windows only!)

Beitrag von ccode_new »

Code: Alles auswählen

With *Process
    ProcedureReturn \Info\dwProcessId
Wend
Was fällt dir z.B. hier auf ?
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: [Module] PROCESS (Windows only!)

Beitrag von Mijikai »

ccode_new hat geschrieben:

Code: Alles auswählen

With *Process
    ProcedureReturn \Info\dwProcessId
Wend
Was fällt dir z.B. hier auf ?
Danke, habe es gefixt.
Antworten