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 Declare Function WaitForSingleObject Lib "kernel32" (ByVal _ hHandle As Long, ByVal dwMilliseconds As Long) As Long Private Declare Function CreateProcessA Lib "kernel32" (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 lpCurrentDirectory 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 GetExitCodeProcess Lib "kernel32" _ (ByVal hProcess As Long, lpExitCode As Long) As Long Private Const NORMAL_PRIORITY_CLASS = &H20& Private Const INFINITE = -1& Public Function ExecCmd(cmdline$) Dim proc As PROCESS_INFORMATION Dim start As STARTUPINFO ' Initialize the STARTUPINFO structure: start.cb = Len(start) ' Start the shelled application: ret& = CreateProcessA(vbNullString, cmdline$, 0&, 0&, 1&, _ NORMAL_PRIORITY_CLASS, 0&, vbNullString, start, proc) ' Wait for the shelled application to finish: ret& = WaitForSingleObject(proc.hProcess, INFINITE) Call GetExitCodeProcess(proc.hProcess, ret&) Call CloseHandle(proc.hThread) Call CloseHandle(proc.hProcess) ExecCmd = ret& End Function Sub Form_Click() Dim retval As Long retval = ExecCmd("setup.exe") MsgBox "Setup Process Finished, Exit Code " & retval retval = ExecCmd("Pro.exe") MsgBox "Pro Process Finished, Exit Code " & retval End Sub HOWTO: 32-Bit App Can Determine When a Shelled Process Ends http://support.microsoft.com/support/kb/articles/Q129/7/96.asp?LN=EN-US&SD=gn&FR=0&qry=WaitForSingleObject&rnk=1&src=DHCS_MSPSS_gn_SRCH&SPR=VBB
'先用 Notepad 和 Calc 测试 Sub Form_Click() Dim retval As Long retval = ExecCmd("notepad.exe") MsgBox "notepad Process Finished, Exit Code " & retval retval = ExecCmd("calc.exe") MsgBox "calc Process Finished, Exit Code " & retval End Sub
你可以打开: ..\VB98\Wizards\PDWizard\Setup1\SETUP1.VBP 注意 StartProcess SyncShell 等几个函数的代码!在 VB IDE 调试 SETUP1.VBP 参阅: HOWTO: Run Setup1.vbp in the Design Environment http://support.microsoft.com/support/kb/articles/Q189/7/38.asp
放弃 Shell 改用 WScript.Shell:'引用 Windows Script Host Object Model Private Sub Command1_Click() Dim x As New IWshRuntimeLibrary.IWshShell_Class Me.Enabled = False x.Run x.ExpandEnvironmentStrings("%WinDir%") & "\notepad.exe", , True Me.Enabled = True VBA.MsgBox "执行完毕" End Sub
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 Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
hHandle As Long, ByVal dwMilliseconds As Long) As Long Private Declare Function CreateProcessA Lib "kernel32" (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 lpCurrentDirectory 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 GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, lpExitCode As Long) As Long Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const INFINITE = -1& Public Function ExecCmd(cmdline$)
Dim proc As PROCESS_INFORMATION
Dim start As STARTUPINFO ' Initialize the STARTUPINFO structure:
start.cb = Len(start) ' Start the shelled application:
ret& = CreateProcessA(vbNullString, cmdline$, 0&, 0&, 1&, _
NORMAL_PRIORITY_CLASS, 0&, vbNullString, start, proc) ' Wait for the shelled application to finish:
ret& = WaitForSingleObject(proc.hProcess, INFINITE)
Call GetExitCodeProcess(proc.hProcess, ret&)
Call CloseHandle(proc.hThread)
Call CloseHandle(proc.hProcess)
ExecCmd = ret&
End Function Sub Form_Click()
Dim retval As Long
retval = ExecCmd("setup.exe")
MsgBox "Setup Process Finished, Exit Code " & retval
retval = ExecCmd("Pro.exe")
MsgBox "Pro Process Finished, Exit Code " & retval End Sub HOWTO: 32-Bit App Can Determine When a Shelled Process Ends
http://support.microsoft.com/support/kb/articles/Q129/7/96.asp?LN=EN-US&SD=gn&FR=0&qry=WaitForSingleObject&rnk=1&src=DHCS_MSPSS_gn_SRCH&SPR=VBB
Sub Form_Click()
Dim retval As Long
retval = ExecCmd("notepad.exe")
MsgBox "notepad Process Finished, Exit Code " & retval
retval = ExecCmd("calc.exe")
MsgBox "calc Process Finished, Exit Code " & retval End Sub
兄弟们,我还是劝大家再累一下。学学那个InstallSheild!学完后就可高枕无忧了,何乐而不为呢?再说,据我个人经验也看,VB自带的打包东东老要出现莫名的问题,差劲。
本人只是提个建议,并非强叫大家学......长痛不如短痛啊!要走正规化的道路。
提醒:setup.exe运行完成后会重启计算机。你想做木马吗? :)
VB可用资源文件(这个没法给你代码)。只要用VB的资源编辑器添加那两个东西进去,然后取组名"binary",然后用LoadResData("SETUP","binary")得到数据,然后用put写到硬盘里
执行之不幸的是,loadresdata只能读64K大的东西:(
因此你只好用API函数LoadResource
先用FindResource(0,name,type)得到HRSRC ,然后LoadResource得到HGLOBAL
最后LockResource得到那个资源的指针。然后的工作有点技巧了,你先开个 buf(3200) as byte
然后用未公开的API函数 RtlMoveMemory一段一段的把资源考进去,再一段一段的存到硬盘里去。……还有个"简单"的办法,用API函数 CreateFile打开文件,然后WriteFile一次就能写入了。
然后下一步先把pro.exe做个快捷方式到启动组里……太复杂了,需要DLL支持;不如用注册表函数regopenkeyex/regsetvalueex设置注册表的hkey_currentuser\software\micro...\windows\runonce\...
反正是添加一项进去,指向pro.exe
然后你就可以放心的去执行setup.exe了好复杂是吧?不做怎么学东西呢。别老当菜鸟了,自己做吧。
我写的方法肯定没错。我编VB有7年了 ^_^
Driver:\FilePath\Pro.exe
命令
..\VB98\Wizards\PDWizard\Setup1\SETUP1.VBP
注意
StartProcess
SyncShell
等几个函数的代码!在 VB IDE 调试 SETUP1.VBP 参阅:
HOWTO: Run Setup1.vbp in the Design Environment
http://support.microsoft.com/support/kb/articles/Q189/7/38.asp
我的方法肯定没错。写注册表要在运行setup.exe前做,然后就可以shell "setup.exe"
以后的事情windows就会自动调用并删除注册表相应的项了(runonce么)。
如果放到run里也可以,加上参数执行你自己的程序,比如if command="-o" then shell "pro.exe"
autoexec.bat可不能用,win2k/me都不用这个东西了,而且还是dos下的……
Private Sub Command1_Click()
Dim x As New IWshRuntimeLibrary.IWshShell_Class
Me.Enabled = False
x.Run x.ExpandEnvironmentStrings("%WinDir%") & "\notepad.exe", , True
Me.Enabled = True
VBA.MsgBox "执行完毕"
End Sub