★卢培培★ ── 欢迎光临卢培培(goodname008)的BLOG

人生真正的快乐,多在贫家茅舍,少在富室红楼。

卢培培ID:goodname008
78639次访问,排名1220好友0人,关注者0
goodname008的文章
原创 22 篇
翻译 0 篇
转载 5 篇
评论 286 篇
卢培培的公告


只有干不成事的人
没有干不成的事


代码下载说明:请将代码下载地址的链接复制到浏览器的地址栏,按下回车即可正常下载。

最近评论
jingang123gz:在C# 中怎么屏蔽WIN键啊?????
kennylyj:我在做类似的东西的时候遇到一个问题:
由于需要将一些16位的DOS程序的输出导出,因此使用了管道,但直接CreateProcess这些程序是不行的,必须通过ComSpec这个环境变量得到命令行程序的路径并把要运行的DOS程序的路径及相关参数作为命令行程序的参数才行,或者是先运行cmd/command,然后通过标准写端口写入要启动的程序的参数
而这样做却导致系统的虚拟机程序……
mycaibo:原来可以下载呀,我还自己写了一遍,不过说KBDLLHOOKSTRUCT没有定义,也不知道是为什么,谢谢哈
jarcyju:大哥下载不了呀,麻烦发一份给我,谢谢啦
zhuyc0808@gmail.com
wuzhongyi:我认为以上的方案不好,看样子你也是做开发的。先不考虑硬盘本身的分区特点及如何得到更快的访问速度,

现在如果c:\为系统盘,而也是你常用的。那样XP安装完以后要多大?2G左右吧,那么虚拟的内存又会占用1G多,你再装点软件什么的。VS2005+msdn即使你不装在C盘,照样撑死你。
文章分类
收藏
    相册
    其它图片
    文章用图
    A.我的软件
    1.注册表大师 v2.0
    2.窗口间谍
    3.图易贴 v1.1
    B.强烈推荐
    1.VB打造超酷个性化菜单[一]
    2.VB打造超酷个性化菜单[二]
    3.VB打造超酷个性化菜单[三]
    4.剖析VC++函数调用约定
    C.有脚印的地方
    CSDN--中国软件网
    微软中国社区
    微软中文新闻组
    D.开放源代码
    1.鼠标感应器
    2.VB自绘菜单类
    3.你想要钱吗?
    E.友情链接
    1. 凝尘
    2. 羽毛羽毛
    3. 泗水寻芳
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 将CMD的输入输出重定向到自己的进程收藏

    新一篇: 利用HTTP协议实现文件下载的多线程断点续传 | 旧一篇: 跨进程实现在Tree中快速定位节点

        前段时间,CSDN VB版的一个网友问了一个如何取得进程句柄的问题,后来贴子中又引出另一个问题:如何将CMD的输入输出重定向到自己的进程?由于楼主提前结了贴子,所以我另开了一个贴子对这个问题作出了回答,两个原贴均可以在CSDNVB版搜索到。现在我把代码记录在此,以飨更多的朋友。

        对于CMD窗口的输入输出重定向,我采用的是匿名管道。关于管道的相关技术和知识,可以参阅网上的其他相关文章或者MSDN,这里不在赘述。

        在窗体中放两个TextBoxtxtCommand用于输入命令;txtMessageMultiLine属性为TrueScrollBars属性为vbVertical,用于获得CMD窗口输出的内容。

     

    Option Explicit

     

    Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long

    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

    Private Declare Function CreatePipe Lib "kernel32" (phReadPipe As Long, phWritePipe As Long, lpPipeAttributes As Any, ByVal nSize As Long) As Long

    Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long

    Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long

    Private Declare Function SetHandleInformation Lib "kernel32" (ByVal hObject As Long, ByVal dwMask As Long, ByVal dwFlags As Long) As Long

    Private Declare Function SetNamedPipeHandleState Lib "kernel32" (ByVal hNamedPipe As Long, lpMode As Long, lpMaxCollectionCount As Long, lpCollectDataTimeout As Long) As Long

    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

     

    Private Type STARTUPINFO

        cb As Long

        lpReserved As String

        lpDesktop As String

        lpTitle As String

        dwX As Long

        dwY As Long

        dwXSize As Long

        dwYSize As Long

        dwXCountChars As Long

        dwYCountChars As Long

        dwFillAttribute As Long

        dwFlags As Long

        wShowWindow As Integer

        cbReserved2 As Integer

        lpReserved2 As Long

        hStdInput As Long

        hStdOutput As Long

        hStdError As Long

    End Type

     

    Private Type PROCESS_INFORMATION

        hProcess As Long

        hThread As Long

        dwProcessId As Long

        dwThreadId As Long

    End Type

     

    Private Const STARTF_USESTDHANDLES = &H100

    Private Const HANDLE_FLAG_INHERIT = 1

    Private Const DETACHED_PROCESS = &H8

    Private Const PIPE_NOWAIT = &H1

     

    Dim hReadPipe As Long

    Dim hWritePipe As Long

    Dim hChildReadPipe As Long

    Dim hChildWritePipe As Long

     

    Private Sub Form_Load()

        txtCommand.Text = ""

        txtMessage.Text = ""

        txtMessage.Locked = True

       

        ' 创建管道

        CreatePipe hReadPipe, hWritePipe, ByVal 0, ByVal 0

        CreatePipe hChildReadPipe, hChildWritePipe, ByVal 0, ByVal 0

        SetHandleInformation hWritePipe, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT

        SetHandleInformation hChildReadPipe, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT

        Dim dwMode As Long

        dwMode = PIPE_NOWAIT

        SetNamedPipeHandleState hReadPipe, dwMode, ByVal 0, ByVal 0

        

        ' 创建CMD进程

        Dim stProcessInfo As PROCESS_INFORMATION

        Dim stStartInfo As STARTUPINFO

        stStartInfo.cb = LenB(stStartInfo)

        stStartInfo.dwFlags = STARTF_USESTDHANDLES

        stStartInfo.hStdError = hWritePipe

        stStartInfo.hStdOutput = hWritePipe

        stStartInfo.hStdInput = hChildReadPipe

       

        Dim strExe As String

        strExe = "cmd"

        If False = CreateProcess(ByVal vbNullString, ByVal strExe, ByVal 0, ByVal 0, ByVal True, ByVal DETACHED_PROCESS, ByVal 0, ByVal vbNullString, stStartInfo, stProcessInfo) Then

            MsgBox "启动进程失败!"

            Exit Sub

        Else

            CloseHandle stProcessInfo.hThread

            CloseHandle stProcessInfo.hProcess

        End If

       

        ' 从管道中读出数据, 该数据通常为CMD的版本及版权信息

        ReadFromChildPipe

    End Sub

     

    Private Sub Form_Unload(Cancel As Integer)

        CloseHandle hReadPipe

        CloseHandle hWritePipe

        CloseHandle hChildReadPipe

        CloseHandle hChildWritePipe

    End Sub

     

    Private Sub txtCommand_KeyPress(KeyAscii As Integer)

        ' 按下回车时将命令写入管道

        If KeyAscii = vbKeyReturn Then

            Dim nWrite As Long

            Dim strBuffer As String

            strBuffer = txtCommand.Text & vbCrLf

            Dim bResult As Boolean

            bResult = WriteFile(ByVal hChildWritePipe, ByVal strBuffer, ByVal Len(strBuffer), nWrite, ByVal 0)

            If bResult = True Then

                ReadFromChildPipe

            Else

                MsgBox "写入失败."

            End If

            txtCommand.Text = ""

        End If

    End Sub

     

    Private Sub ReadFromChildPipe()

        ' 读取管道中所有可读取的数据并写入到txtMessage

        Dim nRead As Long

        Dim strBuffer As String

        Dim nBufferLen As Long

        nRead = -1

        Do While nRead <> 0

            nBufferLen = 65536

            strBuffer = String(nBufferLen, Chr(0))

            Sleep 30

            ReadFile hReadPipe, ByVal strBuffer, ByVal nBufferLen, nRead, ByVal 0

            If nRead <> 0 Then

                strBuffer = Left(strBuffer, nRead)

                txtMessage.Text = txtMessage.Text & strBuffer

                txtMessage.SelStart = Len(txtMessage.Text)

            End If

        Loop

    End Sub

     

     

         源代码下载地址:http://csdngoodname008.51.net/CMDRedirect.zip

     

    *-------------------------------------------*

    *  转载请通知作者并注明出处,CSDN欢迎您!   *

    *  作者:卢培培(goodname008              *

    *  邮箱:goodname008@163.com                *

    *  专栏:http://blog.csdn.net/goodname008   *

    *-------------------------------------------*

    发表于 @ 2005年10月30日 18:54:00|评论(loading...)|编辑

    新一篇: 利用HTTP协议实现文件下载的多线程断点续传 | 旧一篇: 跨进程实现在Tree中快速定位节点

    评论

    #coolfire.. 发表于2005-11-27 15:26:00  IP: 211.148.152.*
    謝謝了..
    經常在網上看到您的大作啊..
    #莫取网名 发表于2005-12-28 21:11:00  IP: 218.64.107.*
    你好,本人搞了一个程序。经inno setup 5打包后将安装程序发给未装VB的朋友那也可以正常使用。但是朋友重装了一次系统之后(在本机也一样),程序就不能运行了,说什么未注册的,我也知道是因为重装系统之后,那些控件都被解除注册了!而且我也会注册!

    我想要说的问题是:有没有一种方法,不在打包脚本中加入注册控件的代码而在form_load事件中加入注册代码。这种方法我也会,但想一下如果每次打开主程序时都要对控件注册一次,那岂不是会做很多无用功?我的意思是指:有没有什么方法可以在打开主程序时先检查一下该控件是否已经注册,如果没有注册的话,则注册,如果已经注册的话则不执行“注册控件的代码”?我在CSDN上发贴却没有人知道,麻烦大虾指点!

    问题链接网页:
    http://community.csdn.net/Expert/topic/4476/4476317.xml?temp=.9936945
    #yanfei 发表于2006-01-15 21:36:00  IP: 60.221.24.*
    Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" _
    (ByVal lpApplicationName As String, _
    ByVal lpCommandLine As String, _
    lpProcessAttributes As SECURITY_ATTRIBUTES, _
    lpThreadAttributes As SECURITY_ATTRIBUTES, _
    ByVal bInheritHandles As Long, _
    ByVal dwCreationFlags As Long, _
    lpEnvironment As Any, _
    ByVal lpCurrentDirectory As String, _
    lpStartupInfo As STARTUPINFO, _
    lpProcessInformation As PROCESS_INFORMATION) As Long
    Private Type STARTUPINFO
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
    End Type

    Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadId As Long
    End Type
    Private Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
    End Type

    Private Const NORMAL_PRIORITY_CLASS As Long = &H20&
    Private Const S
    #yanfei 发表于2006-01-15 20:38:00  IP: 60.221.24.*
    上面的代码用改动过的API(用VC的API),在WIN NT以上的版本中可运行成功,但在WIN98下会创建进程失败,可不可以不改变VB中提供的API,来使上述代码运行成功?
    #hh 发表于2006-01-15 20:40:00  IP: 60.221.24.*
    <script>document.alert("hello")</script>
    #goodname008 发表于2006-02-07 13:16:00  IP: 10.0.28.*
    我这里没有98。
    用GetLastError看是什么错误原因了吗?

    用这个
    CreateProcess(ByVal vbNullString, ByVal strExe, ByVal 0, ByVal 0, ByVal True, ByVal DETACHED_PROCESS, ByVal 0, ByVal vbNullString, stStartInfo, stProcessInfo)

    字符串要ByVal,VB的字符串是指针的指针,而win32 API中用的是C风格的字符串,就是个char的指针,所以在VB中要传值,而不是传址,即使用ByVal。
    #kennylyj 发表于2008-04-06 16:52:47  IP: 219.136.204.*
    我在做类似的东西的时候遇到一个问题:
    由于需要将一些16位的DOS程序的输出导出,因此使用了管道,但直接CreateProcess这些程序是不行的,必须通过ComSpec这个环境变量得到命令行程序的路径并把要运行的DOS程序的路径及相关参数作为命令行程序的参数才行,或者是先运行cmd/command,然后通过标准写端口写入要启动的程序的参数
    而这样做却导致系统的虚拟机程序高负荷运行(ntvdm.exe占用CPU达100%)。
    不知道大家有没有好的方法避免?
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 卢培培