После длительного перерыва, снова сел за VB6. Появилось желание доделать старый проект.
Существует библиотека WIMGAPI.DLL для работы с wim-файлами. (создание и развертывание образа ОС Windows)
Чтобы применить(развернуть, распаковать) wim-образ, нужно вызвать функцию WIMApplyImage. Процесс применения может длится несколько минут, и чтобы программа не зависла при выполнении этой функции, предварительно нужно зарегистрировать CallBack, в котором можно вызвать DoEvents, посмотреть прогресс, и другие данные.
Проблема в том что callback вызывается (по видимому) из другого потока, и в IDE происходит крах. В скомпилированном виде почти всегда работает работает без падения программы.
Если не использовать CallBack, то функция WIMApplyImage всегда выполняется нормально, но при этом проект зависает до тех пор пока функция выполнится.
К сожалению моих знаний пока не хватает чтобы придумать как правильно вызвать функцию WIMApplyImage, чтобы проект не зависал, и CallBack корректно (без падений IDE) отрабатывал.
Пока есть только одна идея: каким то образом запускать WIMApplyImage и CallBack в отдельном потоке (возможно не корректно выразился). Про создание потоков уже достаточно много почитал на разных ресурсах, и пока в голове нет четкого представления как это реализовать.
Вот собственно я и обращаюсь за помощью.
Код который составил согласно официальной документации.
- Код: Выделить всё
Option Explicit
Public Const WIM_MSG_SUCCESS As Long = &H0
Public Const WIM_MSG_PROGRESS As Long = 38008
Public Const WIM_MSG_ABORT_IMAGE As Long = &HFFFFFFFF
Public Const WIM_GENERIC_READ As Long = &H80000000
Public Const WIM_OPEN_EXISTING As Long = &H3
Public Const WIM_COMPRESS_NONE As Byte = 0
Public Const WIM_FLAG_NO_RP_FIX As Long = &H100
Public Const WIM_FLAG_VERIFY As Long = &H2
Public Declare Function WIMCloseHandle Lib "WIMGAPI.DLL" (ByVal hObject As Long) As Boolean
Public Declare Function WIMCreateFile Lib "WIMGAPI.DLL" ( _
ByVal lpszWimPath As Long, _
ByVal dwDesiredAccess As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal dwCompressionType As Long, _
ByRef CreationResult As Long) As Long
Public Declare Function WIMGetImageInformation Lib "WIMGAPI.DLL" ( _
ByVal hImage As Long, _
ByRef ppvImageInfo As Long, _
ByRef pcbImageInfo As Long) As Long
Public Declare Function WIMSetTemporaryPath Lib "WIMGAPI.DLL" ( _
ByVal hWim As Long, _
ByVal lpszPath As Long) As Boolean
Public Declare Function WIMLoadImage Lib "WIMGAPI.DLL" ( _
ByVal hWim As Long, _
ByVal dwImageIndex As Long) As Long
Public Declare Function WIMApplyImage Lib "WIMGAPI.DLL" ( _
ByVal hImage As Long, _
ByVal lpszPath As Long, _
ByVal dzApplyFlags As Long) As Boolean
Public Declare Function WIMRegisterMessageCallback Lib "WIMGAPI.DLL" ( _
ByVal hWim As Long, _
ByVal fpMessageProc As Long, _
ByVal pvUserData As Long) As Long
Public Declare Function WIMUnregisterMessageCallback Lib "WIMGAPI.DLL" ( _
ByVal hWim As Long, _
ByVal fpMessageProc As Long) As Boolean
Public hWim As Long
Public hImage As Long
Public AplyCancel As Boolean
Public bIsInIDE As Boolean
Public nTime As Long
Public Sub TestWIMGAPI2()
Dim wimFilePath As String
wimFilePath = "D:\test\install.wim"
Dim wimFileTMPPath As String
wimFileTMPPath = "D:\test\tmp"
Dim strApplyPath As String
strApplyPath = "D:\test\OS"
Dim status As Boolean
Dim MyStr As String
Dim LInfo As Long
Dim PInfo As Long
Dim retCreate As Long
Dim nRet As Long
hWim = WIMCreateFile( _
ByVal StrPtr(wimFilePath), _
WIM_GENERIC_READ, _
WIM_OPEN_EXISTING, _
0, _
WIM_COMPRESS_NONE, _
ByVal VarPtr(retCreate))
nRet = 0
nRet = WIMGetImageInformation(ByVal hWim, ByVal VarPtr(PInfo), ByVal VarPtr(LInfo))
Debug.Print "WIMGetImageInformation: " & nRet
nRet = 0
nRet = WIMSetTemporaryPath(hWim, ByVal StrPtr(wimFileTMPPath))
Debug.Print "WIMSetTemporaryPath: " & nRet
hImage = WIMLoadImage(hWim, 1)
nRet = 0
nRet = WIMRegisterMessageCallback(hWim, AddressOf WIMMessageCallback, 0)
Debug.Print "RegisterMessageCallback: " & nRet
AplyCancel = False
Dim nFlag As Long
nFlag = 0
nFlag = WIM_FLAG_VERIFY Or WIM_FLAG_NO_RP_FIX
Debug.Print "ApplyImage: " & WIMApplyImage(hImage, ByVal StrPtr(strApplyPath), nFlag)
nRet = 0
nRet = WIMUnregisterMessageCallback(hWim, AddressOf WIMMessageCallback)
Debug.Print "WIMUnregisterMessageCallback: " & nRet
WIMCloseHandle (hImage)
WIMCloseHandle (hWim)
End Sub
Public Function WIMMessageCallback(ByVal dwMessageId As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal pvUserData As Long) As Long
Select Case dwMessageId
Case WIM_MSG_PROGRESS
Debug.Print "WIM_MSG_PROGRESS: " & wParam & " / " & lParam
Case Else
Debug.Print dwMessageId & " / " & wParam & " / " & lParam
End Select
WIMMessageCallback = WIM_MSG_SUCCESS
If AplyCancel = True Then WIMMessageCallback = WIM_MSG_ABORT_IMAGE
DoEvents
End Function