Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


RUVATA кстати там автор поста и спрашивает, зачем вам Win32 вариант. Ответ прост, в своё время был не обнаружен в .NET 1.0 и началось.

CreatePipe как раз и создаёт перед запуском среду для перенаправления потока, вызванного по CreateProcess. Останется только считать его посредством ReadFile
Возможно есть чисто .NET решения, однако при наличии WIN32 тратится на поиски может и не рационально.

Вот пример использования всех трёх функций воедино.

Код: Выделить весь код
    Public Structure SECURITY_ATTRIBUTES
        Public nLength As Integer
        Public lpSecurityDescriptor As Integer
        Public bInheritHandle As Integer
    End Structure

    Declare Function CreatePipe Lib "kernel32.dll" ( _
        ByRef phReadPipe As Integer, _
        ByRef phWritePipe As Integer, _
        ByRef lpPipeAttributes As SECURITY_ATTRIBUTES, _
        ByVal nSize As Integer) As Integer

    Public Structure STARTUPINFO
        Public cb As Integer
        Public lpReserved As Integer
        Public lpDesktop As Integer
        Public lpTitle As Integer
        Public dwX As Integer
        Public dwY As Integer
        Public dwXSize As Integer
        Public dwYSize As Integer
        Public dwXCountChars As Integer
        Public dwYCountChars As Integer
        Public dwFillAttribute As Integer
        Public dwFlags As Integer
        Public wShowWindow As Short
        Public cbReserved2 As Short
        Public lpReserved2 As Integer
        Public hStdInput As Integer
        Public hStdOutput As Integer
        Public hStdError As Integer
    End Structure

    Const STARTF_USESTDHANDLES As Integer = &H100
    Const STARTF_USESHOWWINDOW As Integer = &H1
    Const SW_HIDE As Integer = 0

    Public Structure PROCESS_INFORMATION
        Public hProcess As Integer
        Public hThread As Integer
        Public dwProcessId As Integer
        Public dwThreadId As Integer
    End Structure

    Declare Function CreateProcess Lib "kernel32.dll" Alias "CreateProcessA" ( _
        ByVal lpApplicationName As String, _
        ByVal lpCommandLine As String, _
        ByRef lpProcessAttributes As SECURITY_ATTRIBUTES, _
        ByRef lpThreadAttributes As SECURITY_ATTRIBUTES, _
        ByVal bInheritHandles As Integer, _
        ByVal dwCreationFlags As Integer, _
        ByRef lpEnvironment As Integer, _
        ByVal lpCurrentDriectory As String, _
        ByRef lpStartupInfo As STARTUPINFO, _
        ByRef lpProcessInformation As PROCESS_INFORMATION) As Integer

    Const NORMAL_PRIORITY_CLASS As Integer = &H20

    Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Integer) As Integer

    Const MAX_PATH As Integer = 260

    Public Structure OVERLAPPED
        Public ternal As Integer
        Public ternalHigh As Integer
        Public offset As Integer
        Public OffsetHigh As Integer
        Public hEvent As Integer
    End Structure

    Declare Function ReadFile Lib "kernel32.dll" ( _
        ByVal hFile As Integer, _
        ByVal lpBuffer As System.Text.StringBuilder, _
        ByVal nNumberOfBytesToRead As Integer, _
        ByRef lpNumberOfBytesRead As Integer, _
        ByRef lpOverlapped As OVERLAPPED) As Boolean

    Shared Function CmdAnswer2Buff(ByRef Command As String) As String
        Dim hReadPipe As IntPtr = Nothing
        Dim hWritePipe As IntPtr = Nothing

        Dim sa As SECURITY_ATTRIBUTES
        sa.nLength = System.Runtime.InteropServices.Marshal.SizeOf(sa)
        sa.lpSecurityDescriptor = Nothing
        sa.bInheritHandle = True

        If CreatePipe(hReadPipe, hWritePipe, sa, 0) = 0 Then
            MsgBox("Вызов функции CreatePipe() не прошёл успешно.", MsgBoxStyle.Critical, "Ошибка.")
            Return Nothing
        End If

        Dim cif As STARTUPINFO = New STARTUPINFO()
        cif.cb = System.Runtime.InteropServices.Marshal.SizeOf(cif)
        cif.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
        cif.wShowWindow = SW_HIDE
        cif.hStdOutput = hWritePipe
        cif.hStdError = hWritePipe
        Dim pi As PROCESS_INFORMATION = New PROCESS_INFORMATION()

        If CreateProcess(Nothing, Command, Nothing, Nothing, True, NORMAL_PRIORITY_CLASS, Nothing, Nothing, cif, pi) = 0 Then
            MsgBox("Путь или команда не верна", MsgBoxStyle.Critical, Command)
            Return Nothing
        End If

        CloseHandle(hWritePipe)
        CloseHandle(pi.hProcess)
        CloseHandle(pi.hThread)

        Dim ret As Boolean = True
        Dim BufferA As System.Text.StringBuilder = New System.Text.StringBuilder(MAX_PATH)

        Dim NumberOfBytesRead As Integer
        Dim Buffer As String = Nothing
        Do
            ret = ReadFile(hReadPipe, BufferA, MAX_PATH - 1, NumberOfBytesRead, Nothing)
            If NumberOfBytesRead > 0 Then Buffer = Buffer & BufferA.ToString
        Loop While ret

        CloseHandle(hReadPipe)
        Return Buffer
    End Function
Использовать так Console.WriteLine(CmdAnswer2Buff("7z /?"))
Это сообщение посчитали полезным следующие участники:

Отправлено: 15:10, 25-08-2010 | #8