一直挺关心最终幻想14,前些日子开始封闭测试了,很多朋友也陆陆续续地拿到了测试资格。
但是封测的客户端安装包只装了个引导程序,其它东西都是要通过BT协议来下载的,而安装以后第一次更新的时候要下载的内容有3.35GB之大,很多人用官方的下载器要下载数天才行——而往往下载完成以后,又有新的版本了,又得重新下载。
要想跳出这个死循环,就得在启动补丁更新程序之前在上面做点手脚——无独有偶,一些精通Visual Basic 6的人也发现在Visual Basic 6编译、生成可执行文件的过程中也可以做点手脚来达到一些特殊目的,有的人甚至专门为这种情况写了一个辅助工具。
我没有想把东西弄得太复杂,对于更新最终幻想14来说,只要放一个程序在中间,然后把参数转交给真正的ffxivupdater.exe就可以了,所以我就用Visual Basic 6随便写了个东西用;但我一时兴起就试了一下替换LINK.EXE,然后发现不作额外处理调用真正的LINK.EXE的时候会有一个黑乎乎的控制台窗口一闪即逝。
考虑到以后用在其它地方的可能,我决定把它稍微完善一下,增加了传递窗体启动参数、重定向标准IO管道的能力。
原理比较简单,所以不再详细解释了。完整的代码如下:
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
Const STARTF_USESHOWWINDOW = &H1
Const STARTF_USESTDHANDLES = &H100&
Private Declare Sub GetStartupInfo Lib "kernel32" Alias "GetStartupInfoW" (lpStartupInfo As STARTUPINFO)
Private Declare Function CreateProcess Lib "kernel32 " Alias "CreateProcessW" (ByVal p1 As Long, ByVal lpCommandLine As Long, _
ByVal p3 As Long, ByVal p4 As Long, ByVal bInheritHandles As Long, ByVal p6 As Long, ByVal p7 As Long, _
ByVal p8 As Long, 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 Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const STD_INPUT_HANDLE = -10&
Private Const STD_OUTPUT_HANDLE = -11&
Private Const STD_ERROR_HANDLE = -12&
Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
Dim mySI As STARTUPINFO
Private Sub cmdRun_Click()
Dim cmd As String, si As STARTUPINFO, pi As PROCESS_INFORMATION
cmd = txtCmd.Text
si.cb = Len(si)
si.dwFlags = (STARTF_USESHOWWINDOW And mySI.dwFlags) Or STARTF_USESTDHANDLES
si.wShowWindow = mySI.wShowWindow
si.hStdError = GetStdHandle(STD_ERROR_HANDLE)
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE)
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE)
'si.hStdError = GetStdHandle(STD_OUTPUT_HANDLE)
If CreateProcess(0, StrPtr(cmd), 0, 0, _
1, 0, 0, 0, si, pi) Then
Me.Hide
DoEvents
WaitForSingleObject pi.hProcess, -1
CloseHandle pi.hProcess
CloseHandle pi.hThread
Unload Me
Else
MsgBox "无法启动目标程序,请检查启动命令是否正确。"
End If
End Sub
Function GetTarget() As String
On Error Resume Next
Dim line As String
Open App.Path & "\" & App.EXEName & ".cmd" For Input As #1
Line Input #1, line
Close #1
If "" = line Then
line = App.Path & "\" & App.EXEName & ".ex_"
Else
If InStr(1, line, "\") = 0 Then line = App.Path & "\" & line
End If
If """" <> Left$(line, 1) Then line = """" & line & """"
GetTarget = line
End Function
Private Sub Form_Load()
GetStartupInfo mySI
Me.Caption = GetTarget
txtCmd = Me.Caption & " " & Command$
End Sub
Private Sub Form_Resize()
On Error Resume Next
txtCmd.Width = Me.ScaleWidth
txtCmd.Height = Me.ScaleHeight - picBottom.Height
End Sub
你也可以直接下载编译好的可执行文件(打包为zip格式):http://files.cnblogs.com/NanaLich/HoDown.zip
使用方法很简单:
把希望暂停启动或者在其参数上做手脚的可执行文件的扩展名改为“.EX_”,然后把本程序放在那个路径下面改成原来那个可执行文件的名称。
另外,我不知道谁会希望用到这样的功能:也可以创建一个主文件名相同、但扩展名为“.cmd”的文件,在其中写入希望最终调用的可执行文件的名称(路径可以省略)。