当前位置:编程学习 > VB >>

vb程序中打开另一个程序的问题

这个问题大家可能认为很简单。
我用
ExecuteFile 
ShellExecute
WinExec
shell 三个函数都打不开,用这三个函数可以打开一些小程序(在CMD窗口下可以打开的程序),但是打不开大的(在CMD窗口打不开的程序)。
用CreateProcess()可能可以打开,不过参数太多了。太麻烦。会的说下。
我只要打一个程序,并正常显示出来就行了。知道的给我写个VB代码。。  --------------------编程问答-------------------- 俺有个示例代码,不过在公司的机器上,不急的话明天早晨给你。
--------------------编程问答--------------------  不急。是不是用CreateProcess函数??? --------------------编程问答-------------------- 什么程序用shell等打不开? --------------------编程问答-------------------- 以下是我写的一段测试代码,希望能给你帮忙。
Private Const CREATE_NEW_CONSOLE = &H10 '控制台程序
Private Const NORMAL_PRIORITY_CLASS = &H20 '一般优先级
Private Declare Sub GetStartupInfo Lib "kernel32" Alias "GetStartupInfoA" (lpStartupInfo As STARTUPINFO)
Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByVal lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Private Type STARTUPINFO
        cb As Long
        lpReserved As Long
        lpDesktop As Long
        lpTitle As Long
        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

Sub main()
    Dim stStartUp As STARTUPINFO
    Dim stProcInfo As PROCESS_INFORMATION
    
    stStartUp.cb = Len(STARTUPINFO)
    GetStartupInfo stStartUp
    CreateProcess vbNullString, "D:\WINDOWS\SYSTEM32\NOTEPAD.EXE", 0&, 0&, 0&, NORMAL_PRIORITY_CLASS, 0&, vbNullString, stStartUp, stProcInfo
End Sub
--------------------编程问答-------------------- 先过来看看!原来还有打不开的比较大的调用程序! --------------------编程问答-------------------- 看看 --------------------编程问答-------------------- Const INFINITE = &HFFFF
Const STARTF_USESHOWWINDOW = &H1
Private Enum enSW
    SW_HIDE = 0
    SW_NORMAL = 1
    SW_MAXIMIZE = 3
    SW_MINIMIZE = 6
End Enum
Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadId As Long
End Type
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 Byte
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type
Private Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
End Type
Private Enum enPriority_Class
    NORMAL_PRIORITY_CLASS = &H20
    IDLE_PRIORITY_CLASS = &H40
    HIGH_PRIORITY_CLASS = &H80
End Enum
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 lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Sub Command1_Click()
   On Error GoTo errhandler
   With CommonDialog1
      .DialogTitle = "请选择一个文件"
      .CancelError = True
      .Filter = "EXEC-Files (*.exe)|*.exe|All files (*.*)|*.*"
      .ShowOpen
   End With
   SuperShell CommonDialog1.FileName, Left$(CommonDialog1.FileName, Len(CommonDialog1.FileName) - Len(CommonDialog1.FileTitle)), 0, SW_NORMAL, HIGH_PRIORITY_CLASS
errhandler:
   If Err > 0 Then Exit Sub
End Sub

Private Function SuperShell(ByVal App As String, ByVal WorkDir As String, dwMilliseconds As Long, ByVal start_size As enSW, ByVal Priority_Class As enPriority_Class) As Boolean
   Dim pclass As Long
   Dim sinfo As STARTUPINFO
   Dim pinfo As PROCESS_INFORMATION
   Dim sec1 As SECURITY_ATTRIBUTES
   Dim sec2 As SECURITY_ATTRIBUTES
   sec1.nLength = Len(sec1)
   sec2.nLength = Len(sec2)
   sinfo.cb = Len(sinfo)
   sinfo.dwFlags = STARTF_USESHOWWINDOW
   sinfo.wShowWindow = start_size
   pclass = Priority_Class
   If CreateProcess(vbNullString, App, sec1, sec2, False, pclass, 0&, WorkDir, sinfo, pinfo) Then
       WaitForSingleObject pinfo.hProcess, dwMilliseconds
       SuperShell = True
   Else
       SuperShell = False
   End If
End Function

--------------------编程问答-------------------- "在CMD窗口打不开的程序"

这句我看了三遍,还是没明白你说的是什么样的程序.

除非这程序根本就不能执行,否则一定是可以打开的吧......

你这又不是初始目录的问题.

有点糊涂,还是帮顶吧. --------------------编程问答-------------------- ;这是一个用CreateProcess API创建一个进程,并将设置新进程窗口的示例

Option Explicit

      Private Type PROCESS_INFORMATION
         hProcess As Long
         hThread As Long
         dwProcessId As Long
         dwThreadId As Long
      End Type

      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 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 OpenProcess Lib "kernel32.dll" _
         (ByVal dwAccess As Long, _
         ByVal fInherit As Integer, _
         ByVal hObject As Long) As Long

      Private Declare Function TerminateProcess Lib "kernel32" _
         (ByVal hProcess As Long, _
         ByVal uExitCode As Long) As Long

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

      Const SYNCHRONIZE = 1048576
      Const NORMAL_PRIORITY_CLASS = &H20&
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long




Private Sub Command1_Click()
         Dim pInfo As PROCESS_INFORMATION
         Dim sInfo As STARTUPINFO
         Dim sNull As String
         Dim lSuccess As Long
         Dim lRetValue As Long
         

         sInfo.cb = Len(sInfo)
         lSuccess = CreateProcess(sNull, _
                                 "c:\windows\system32\notepad.exe", _
                                 ByVal 0&, _
                                 ByVal 0&, _
                                 1&, _
                                 NORMAL_PRIORITY_CLASS, _
                                 ByVal 0&, _
                                 sNull, _
                                 sInfo, _
                                 pInfo)
        
        Dim s As Double
        s = Timer
        Do
            DoEvents
            'Debug.Print pInfo.dwProcessId; pInfo.dwThreadId;
        Loop While Timer - s < 0.4
        
        start = 0
                                 
        EnumThreadWindows pInfo.dwThreadId, AddressOf EnumThreadWndProc, 0
        
        'Debug.Print h
        'Debug.Print Hex$(thehwnd)
        
        SetWindowPos thehwnd, 0, 0, 0, 400, 100, 0
                                 
        'pinfo.

         'MsgBox "Calculator has been launched!"

         'lRetValue = TerminateProcess(pInfo.hProcess, 0&)
         'lRetValue = CloseHandle(pInfo.hThread)
         'lRetValue = CloseHandle(pInfo.hProcess)

         'MsgBox "Calculator has terminated!"
End Sub



;模块中

Option Explicit
'In a module
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Public Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId As Long, ByVal lpfn As Long, ByVal lParam As Long) As Long
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
'variable used to list all the classnames
Public sClasses As String
Public start As Long
Public thehwnd As Long


Public Function EnumThreadWndProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
    Dim Ret As Long, sText As String
    
    If start = 0 Then
        thehwnd = hWnd
    End If
    start = start + 1
    'create a string-buffer
    sText = Space(255)
    'get the classname of the window handle
    Ret = GetClassName(hWnd, sText, 255)
    'cut off the unnecessary part of Chr$(0)'s
    sText = Left$(sText, Ret)
    'add this classname to the list of classnames
    sClasses = sClasses + sText + vbCrLf
    'continue the enumeration
    EnumThreadWndProc = 1
End Function
--------------------编程问答--------------------  Dim Doub As Double
            Doub = Shell(程序路径+名字, vbNormalFocus) --------------------编程问答-------------------- 唉。还是不行。
cmd窗口。指系统命令:cmd
有些程序可以用这三个函数打开,有些就打不开。
我试过,打计算器,记事本之类的没问题。
我要打开的是:武林外传的客户端,用上面三个函数打出错。提示:
“无法创建gamesave目录,游戏无法运行!
请确保硬盘有足够的剩余空间再运行本游戏!”

大家说这是什么问题,
这个程序在CMD窗口下也可以打开,昨天我输入的全路径不行,要转换到游戏目录下,在运行就能打开了。
--------------------编程问答-------------------- 现在我先建个批处理文件,在批处理文件中打开游戏程序,在VB中调用SHELL打开这个批处理文件。。这样能凑合着用。
--------------------编程问答-------------------- 你这跟本不是 cmd 或 shell 打不开文件的问题, exe 那有打不开的道理 ? 这是你的代码路径设置访问出错的问题,而不是 cmd shell....等的错. --------------------编程问答-------------------- 亦或是缺少运行参数 --------------------编程问答--------------------
引用 8 楼 myjian 的回复:
"在CMD窗口打不开的程序" 

这句我看了三遍,还是没明白你说的是什么样的程序. 

除非这程序根本就不能执行,否则一定是可以打开的吧...... 

你这又不是初始目录的问题. 

有点糊涂,还是帮顶吧.


引用 11 楼 m9832008 的回复:
唉。还是不行。 
cmd窗口。指系统命令:cmd 
有些程序可以用这三个函数打开,有些就打不开。 
我试过,打计算器,记事本之类的没问题。 
我要打开的是:武林外传的客户端,用上面三个函数打出错。提示: 
“无法创建gamesave目录,游戏无法运行! 
请确保硬盘有足够的剩余空间再运行本游戏!” 

大家说这是什么问题, 
这个程序在CMD窗口下也可以打开,昨天我输入的全路径不行,要转换到游戏目录下,在运行就能打开了。 


我汗!!!!!!!!!!!!!!!!!

你这根本就是程序初始目录的问题嘛!!!!!

问问题前说清楚点好不????

运行程序时传入初始目录就可以了!!!

倒塌~~~~~~~~~~ --------------------编程问答-------------------- path 环境有问题 ,你调用和appPath就变成了父进程的path,然后他就找不到北了,createProcess的时候记得设置程序的起始目录到程序目录下 --------------------编程问答-------------------- 谢谢各位:
我用“三春三月忆三巴”写的代码。
不过问题还是:barenx 说的清楚。
我太菜,大家不要笑话。。。。。。。。 --------------------编程问答-------------------- 老马来讲讲初始目录的知识吧。 --------------------编程问答-------------------- 没玩过这个游戏,请楼主查看一下执行文件的扩展名,如果是.EXE,则可以将我上面回复的示例代码中的有关语句修改如下:
CreateProcess vbNullString, "D:\WINDOWS\SYSTEM32\NOTEPAD.EXE", 0&, 0&, 0&, NORMAL_PRIORITY_CLASS, 0&, "D:\WINDOWS\SYSTEM", stStartUp, stProcInfo
即加上程序的当前路径。
如果是.BAT,则需要指向新的环境变量块。
请楼主看看扩展名究竟是什么。 --------------------编程问答-------------------- 有点难度哦
补充:VB ,  API
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,