⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.zc

📁 实现树形结构
💻 ZC
字号:
//[c]
//[of]:license
//[c]    Code Browser - a folding text editor for programmers
//[c]    Copyright (C) 2003-07 Marc Kerbiquet
//[c]
//[c]    This program is free software; you can redistribute it and/or modify
//[c]    it under the terms of the GNU General Public License as published by
//[c]    the Free Software Foundation; either version 2 of the License, or
//[c]    (at your option) any later version.
//[c]
//[c]    This program is distributed in the hope that it will be useful,
//[c]    but WITHOUT ANY WARRANTY; without even the implied warranty of
//[c]    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//[c]    GNU General Public License for more details.
//[c]
//[c]    You should have received a copy of the GNU General Public License
//[c]    along with this program; if not, write to the Free Software
//[c]    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//[cf]
//[of]:imports
//[c]
import "base/types"
import "base/memory-allocator"
import "text/string"
import "text/string-buffer"
//[c]
import "win32/windows"
//[cf]
//[of]:structures
//[c]
public struct process

	public ok : bool
	public exit code : int

	private proc info : PROCESS_INFORMATION
	private stdin : HANDLE
	private stdout : HANDLE
	private stderr : HANDLE

	private process stdin : HANDLE
	private process stdout : HANDLE
	private process stderr : HANDLE

end
//[cf]
//[c]
//[of]:instance creation
//[of]:create process (command, directory, show window, single output)
//[c]
public func create process (
		command line: string, 
		current directory: string,
		show window: bool,
		single output: bool)

	// allocate memory for structure
	def m = allocate memory (sizeof local process) : process
	
	// initialize structure
	ok (m) = false
	exit code (m) = 0
	stdin (m) = nil
	stdout (m) = nil
	stderr (m) = nil
	process stdin (m) = nil
	process stdout (m) = nil
	process stderr (m) = nil
	hProcess (proc info (m)) = nil
	hThread (proc info (m)) = nil

	// create the process and start it
	start (m, 
		command line, 
		current directory, 
		show window,
		single output)

	// return description object
	return m

end
//[c]
//[c]Sub-Functions:
//[of]:start (m, command, directory, show window, single output)
//[c]
private func start (
		m: process, 
		command line: string, 
		current directory: string,
		show window: bool,
		single output: bool)

	// Create redirection pipes
	def pipe : [1] HANDLE
	def stdin : [1] HANDLE
	def stdout : [1] HANDLE
	def stderr : [1] HANDLE
	
	// Create stdin redirection
	def success = create pipe (stdin, pipe)
	if success == 0
		return
	end
	stdin (m) = pipe []
	process stdin (m) = stdin []

	// Create stdout redirection
	success = create pipe (pipe, stdout)
	if success == 0
		return
	end
	stdout (m) = pipe []
	process stdout (m) = stdout []

	// Create stderr redirection
	if single output
		// stderr uses the same stream as stdout
		stderr (m) = nil
		process stderr (m) = nil
		stderr [] = stdout []
	else
		success = create pipe (pipe, stderr)
		if success == 0
			return
		end
		stderr (m) = pipe []
		process stderr (m) = stderr []
	end

	// Initialize the startup info structure
	def si : STARTUPINFOA
	cb (si) = sizeof STARTUPINFOA
	dwFlags (si) = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW
	hStdInput (si) = stdin []
	hStdOutput (si) = stdout []
	hStdError (si) = stderr []
	lpReserved (si) = nil
	lpDesktop (si) = nil
	lpTitle (si) = nil
	dwX (si) = 0
	dwY (si) = 0
	dwXSize (si) = 0
	dwYSize (si) = 0
	dwXCountChars (si) = 0
	dwYCountChars (si) = 0
	dwFillAttribute (si) = 0
	wShowWindow (si) = (show window -> SW_SHOW : word, SW_HIDE : word)
	cbReserved2 (si) = 0:w
	lpReserved2 (si) = nil

	// empty directory means same as parent process
	if is empty (current directory)
		current directory = nil
	end

	success = CreateProcessA (
		nil, 
		command line,
		nil,	// process security
		nil,	// thread security
		TRUE,
		CREATE_NEW_PROCESS_GROUP,
		nil,
		current directory,
		si,
		proc info (m))

	if success == 0
		return
	end
	
	ok (m) = true

end
//[c]
//[c]Sub-functions:
//[of]:create pipe (read pipe, write pipe)
//[c]Creates a pipe without security attributes and with a default size
//[c]
private func create pipe (read pipe: LPHANDLE, write pipe: LPHANDLE)

	def sa : SECURITY_ATTRIBUTES
	nLength (sa) = sizeof SECURITY_ATTRIBUTES
	bInheritHandle (sa) = TRUE
	lpSecurityDescriptor (sa) = nil
	
	return CreatePipe (read pipe, write pipe, sa, 4096)

end
//[cf]
//[cf]
//[cf]
//[of]:delete (m)
//[c]
public func delete (m: process)

	if is nil (m)
		return
	end

	def handle = stdin (m)
	if not nil (handle)
		CloseHandle (handle)
	end

	handle = stdout (m)
	if not nil (handle)
		CloseHandle (handle)
	end

	handle = stderr (m)
	if not nil (handle)
		CloseHandle (handle)
	end

	handle = process stdin (m)
	if not nil (handle)
		CloseHandle (handle)
	end

	handle = process stdout (m)
	if not nil (handle)
		CloseHandle (handle)
	end

	handle = process stderr (m)
	if not nil (handle)
		CloseHandle (handle)
	end

	handle = hProcess (proc info (m))
	if not nil (handle)
		CloseHandle (handle)
	end

	handle = hThread (proc info (m))
	if not nil (handle)
		CloseHandle (handle)
	end

	free memory (m)

end
//[cf]
//[cf]
//[of]:actions
//[of]:stop (m)
//[c]
public func stop (m: process)

	TerminateProcess (hProcess (proc info (m)), -1)

end
//[cf]
//[cf]
//[of]:accessing
//[of]:read stdout (m, stream)
//[c]
public func read stdout (m: process, stream: string buffer)

	read pipe (m, stdout (m), stream)

end
//[cf]
//[of]:read stderr (m, stream)
//[c]
public func read stderr (m: process, stream: string buffer)

	read pipe (m, stderr (m), stream)

end
//[cf]
//[cf]
//[of]:testing
//[of]:is running (m)
//[c]Checks the status of the process
//[c]
//[c]	This method must be invoked periodically to
//[c]	detect the termination of the process.
//[c]
//[c]	Return Values
//[c]	The function returns true if the process is sill running.
//[c]
public func is running (m: process)

	// get exit code
	def exit code : [1] dword
	if GetExitCodeProcess (hProcess (proc info (m)), exit code) == 0
		return true
	end

	// still active ?
	if exit code [] == STILL_ACTIVE
		return true
	end

	exit code (m) = exit code [] : int

	return false
	
end
//[cf]
//[cf]
//[c]
//[of]:private
//[c]
//[of]:read pipe (process, handle, string buffer)
//[c]Appends data to the string buffer with chars from a named pipe
//[c]
private func read pipe (m: process, handle: HANDLE, stream: string buffer)

	equ buffer size = 4096
	def buffer : [buffer size] char
	
	repeat
	
		// check if the pipe is empty or not
		def available : [1] dword
		if PeekNamedPipe (handle, nil, 0, nil, available, nil) == 0
			break
		end
		
		// no byte available
		if available [] == 0
			break
		end

		// read bytes
		def read : [1] dword
		ReadFile (handle, buffer, buffer size, read, nil)
		
		// append them to the stream
		append (stream, buffer, read [])
	end

end
//[cf]
//[cf]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -