powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / А в .Net есть встроенная поддержка для работы с CAB-архивами?
13 сообщений из 13, страница 1 из 1
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38974807
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Скажем так, технологией работы через API я владею:

SetupIterateCabinet function

Creating a Cabinet Callback Routine

В самом .Net "родной" обертки нету?

P.S. При отсутствии более элегантных вариантов придется переписывать VB6 ->.Net, коды как бы не хилые.
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38974808
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38975454
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,

Ну, на "родной класс" это конечно не тянет, т.е. нету.
В принципе через API посмотрю выдеру то что мне надо.
Собственно извлечение заданного файла из заданного CAB-архива в заданное место делается системной утилитой extrac32.exe, например:
Код: vbnet
1.
extrac32.exe /e /y /l "C:\WINDOWS\System32\spool\DRIVERS\W32X86\" "H:\I386\sp2.cab" stdnames.gpd

(это стандартный прием)

Но в своей задаче я перерываю разные известные места на компе типа DriverCachePath, ServicePackSourcePath, SetupPromptForDisk (включая CAB архивы) с целью найти наиболее свежую версию требуемого файла стандартного драйвера, и утилиты извлечения как бы недостаточно, т.е. надо определить наличие и дату файла с заданным именем в CAB до его извлечения. Но там самый гимор даже не сам CAB а рекурсивный поиск файлов.
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38975780
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Ну, на "родной класс" это конечно не тянет, т.е. нету.Нужны шашечки или ехать?
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38975784
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КДмитрий77Ну, на "родной класс" это конечно не тянет, т.е. нету.Нужны шашечки или ехать?
Ехать но без подобных прицепов.
А вариантов в общем случае 2: либо .Net-класс, либо API раз нет такого класса.
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38975830
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Ехать но без подобных прицепов.И чем не устраивает готовая проверенная библиотека от Microsoft?

Дмитрий77А вариантов в общем случае 2: либо .Net-класс, либо API раз нет такого класса.В случае с POP3, помнится, был вариант №3.
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38975839
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAВ случае с POP3, помнится, был вариант №3.
В смысле? Я там все через .Net сделал (вариант #1). А если и скоммуниздил чей-то проект, то полностью переварил и пережевал код, так что чужой библиотекой (скомпилированной) считай не воспользовался.
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38975928
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77skyANAВ случае с POP3, помнится, был вариант №3.
В смысле? Я там все через .Net сделал (вариант #1). А если и скоммуниздил чей-то проект, то полностью переварил и пережевал код, так что чужой библиотекой (скомпилированной) считай не воспользовался.Дак это и есть вариант №3.

Самостоятельно Вы бы сколько времени с API разбирались и писали собственный код?
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38975933
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще глупо ожидать "в самом .Net "родной" обертки для работы с CAB-архивами". Особенно учитывая современные тенденции.
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38976006
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAВообще глупо ожидать "в самом .Net "родной" обертки для работы с CAB-архивами". Особенно учитывая современные тенденции.CAB архивы это уже как ARJ =)
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38976068
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesskyANAВообще глупо ожидать "в самом .Net "родной" обертки для работы с CAB-архивами". Особенно учитывая современные тенденции.CAB архивы это уже как ARJ =)Ну ну...

Cabinet (file format) Cabinet (or CAB ) is an archive file format for Microsoft Windows
Open-source ARJ ARJ is available for more than 10 platforms .
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38976269
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANARoman Mejtesпропущено...
CAB архивы это уже как ARJ =)Ну ну...

Cabinet (file format) Cabinet (or CAB ) is an archive file format for Microsoft Windows
Open-source ARJ ARJ is available for more than 10 platforms .
Я в том плане, что это динозавры :)
...
Рейтинг: 0 / 0
А в .Net есть встроенная поддержка для работы с CAB-архивами?
    #38977911
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAСамостоятельно Вы бы сколько времени с API разбирались и писали собственный код?
Что касается POP3/IMAP то думаю долго.
Потому что я никогда этого раньше не делал.
В принципе вряд ли это сильно сложно, но там есть один подводный камень, а именно SSL, что в .Net делается относительно просто путем оборачивания всего в SSLStream а вот в API хрен знает, не разбирался, да и вряд ли надо.

Что касается CAB, то здесь ситуация иная, у меня все что мне нужно было УЖЕ сделано через API в VB6.
Повозиться чуть пришлось, но это заняло разумное время,
глядел в свои же коды, а также вот в этот чужой проект на ту же тему:
Iterate and Extract Cabinet File
(все таки в .Net какие-то приемы делаются чуть по-другому, поэтому пришлось чуть попыхтеть)

В итоге получился вот такой класс (+пример кода перебирающий все файлы в архиве):
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
  <StructLayout(LayoutKind.Sequential)>
  Public Structure FindFileInfo
    Dim FileName As String
    Dim DateTime As Date
    Dim Size As Integer
    Dim Path As String
  End Structure

  Public FileInfo As FindFileInfo

  Public WithEvents cab As cCabFile

  Private Sub ButtonCabInfo_Click(sender As Object, e As EventArgs) Handles ButtonCabInfo.Click
    cab = New cCabFile
    cab.CabName = "DRIVER.cab"
    cab.GetInfo()
    Debug.Print("end")
  End Sub

  Private Sub cab_FileFound(FileName As String, DateTime As Date, Size As Integer, Path As String) Handles cab.FileFound
    FileInfo.FileName = FileName
    FileInfo.DateTime = DateTime
    FileInfo.Size = Size
    FileInfo.Path = Path
    Debug.Print("FileName=" & FileInfo.FileName & ";Path=" & "DRIVER.cab" & ";DateTime=" & FileInfo.DateTime & ";")
  End Sub



Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.
732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
Imports System.Runtime.InteropServices

Public Class cCabFile
  Private Const MAX_PATH = 260

  Private mstrFileToExtract As String
  Private mstrOutputPath As String
  Private mstrOutputFile As String
  Private mlngCount As Integer

  ' Cab file to work with.
  Public CabName As String

  ' ==================================
  ' Events raised by this class.
  ' ==================================

  Public Event FileFound( _
          ByVal FileName As String, _
          ByVal DateTime As Date, _
          ByVal Size As Integer, _
          ByVal Path As String)

  Public Event BeforeExtract( _
          ByVal FileName As String, _
          ByRef Cancel As Boolean)

  Public Event AfterExtract( _
          ByVal FileName As String)

  ' ==========================================
  ' Name of the class, for error messages, and
  ' a base for user-defined error values (of
  ' which there aren't many, in this class).
  ' ==========================================

  Private Const conClass As String = "CabFile"
  Private Const conErrBase = vbObjectError + 1956

  Public Enum Errors
    errNoCabFile = conErrBase + 0
  End Enum

  Private Const conErrNoCabFile = _
   "You must set the CabName property before " & _
   "taking any action on the CabFile object."

  Private Const conErrUnknown = "Unknown error."

  ' ==================================
  ' <XMLTags>
  ' ==================================

  Private Const conXMLFile = "FILE"
  Private Const conXMLName = "NAME"
  Private Const conXMLDate = "DATE"
  Private Const conXMLSize = "SIZE"
  Private Const conXMLFullName = "FULLNAME"
  Private Const conXMLPath = "PATH"
  Private Const conXMLTop = "CABFILE"
  Private Const conXMLCabFile = "CABFILENAME"
  Private Const conXMLFileCount = "FILECOUNT"

  ' ==================================
  ' </XMLTags>
  ' ==================================

  ' Output XML string. See the GetXML method.
  Private mstrXML As String

  ' Notification messages, handled in the callback
  ' procedure. This class doesn't handle them all.

  Private Const SPFILENOTIFY_FILEINCABINET = &H11
  Private Const SPFILENOTIFY_NEEDNEWCABINET = &H12
  Private Const SPFILENOTIFY_FILEEXTRACTED = &H13

  ' Instructions sent out of the callback procedure.
  ' Tells Windows what to do next.

  Private Enum FILEOP
    FILEOP_ABORT = 0 ' Abort cabinet processing.
    FILEOP_DOIT = 1 ' Extract the current file.
    FILEOP_SKIP = 2 ' Skip the current file.
  End Enum

  ' Local enum, indicating what action to
  ' take on each pass through the callback
  ' procedure.

  Private Enum SetupIterateCabinetActions
    sicCount
    sicReport
    sicExtract
    sicGetXML
  End Enum

  ' ==================================
  ' API Declarations
  ' ==================================

  Private Const NO_ERROR = 0

  <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
  Private Structure FILE_IN_CABINET_INFO
    Dim NameInCabinet As String
    Dim FileSize As Integer
    Dim Win32Error As Integer
    Dim DosDate As Short
    Dim DosTime As Short
    Dim DosAttribs As Short
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> Dim FullTargetName As String
  End Structure

  <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
  Private Structure FILEPATHS
    Dim Target As String
    Dim Source As String
    Dim Win32Error As Integer
    Dim Flags As Integer
  End Structure

  Private Declare Unicode Function SetupIterateCabinet Lib "setupapi.dll" _
   Alias "SetupIterateCabinetW" (ByVal CabinetFile As String, _
   ByVal Reserved As Integer, ByVal MsgHandler As PSP_FILE_CALLBACK, _
   ByVal Context As Integer) As Boolean

  Private Delegate Function PSP_FILE_CALLBACK(ByVal Context As Integer, _
   ByVal Notification As Integer, ByVal Param1 As IntPtr, _
   ByVal Param2 As IntPtr) As Integer

  Public Function GetInfo(Optional ByVal FileToInvestigate As String = vbNullString) As Boolean
    Dim lngReturn As Integer

    ' Iterate through all the files in the cab file,
    ' raising the FileFound event for each found file.
    ' If you specify a value for FileToInvestigate,
    ' the event will only occur zero or one times.

    On Error GoTo HandleErrors

    If Strings.Len(CabName) = 0 Then
      Err.Raise(Errors.errNoCabFile, _
       conClass, fGetError(Errors.errNoCabFile))
    Else
      'Call SetCabFile(Me)
      mstrFileToExtract = FileToInvestigate

      lngReturn = SetupIterateCabinet(CabName, 0, _
       New PSP_FILE_CALLBACK(AddressOf CabinetCallback), SetupIterateCabinetActions.sicReport)
      If lngReturn = 0 Then
        '
        ' If the return value is 0, the
        ' call to SetupIterateCabinet failed.
        ' Raise the error back to the caller,
        ' and convert the error to appropriate
        ' text, if possible. fErrToText doesn't
        ' catch all possible errors, but gets
        ' many of them.
        '
        Err.Raise(Err.LastDllError, _
         conClass, fErrToText(Err.LastDllError))
      End If
    End If

    GetInfo = (lngReturn <> 0)

ExitHere:
    Exit Function

HandleErrors:
    Err.Raise(Err.Number, _
     conClass & ".GetInfo", Err.Description)
    Resume ExitHere
  End Function

  Friend Function CabinetCallback(ByVal Context As Integer, _
   ByVal Notification As Integer, ByVal Param1 As IntPtr, _
   ByVal Param2 As IntPtr) As Integer

    CabinetCallback = NO_ERROR 'затычка (чтоб всегда возвращала значение), не уверен что это правильно

    ' Callback procedure for SetupIterateCabinet. This procedure
    ' is called by a corresponding procedure in a standard module.

    On Error GoTo HandleErrors

    '
    ' Handle the callback for the CAB file.
    '
    Select Case Notification
      Case SPFILENOTIFY_NEEDNEWCABINET
        ' Not handled here.
        CabinetCallback = NO_ERROR

      Case SPFILENOTIFY_FILEEXTRACTED

        ' Copy the bytes passed into a FILEPATHS structure.
        ' Although this procedure gets a parameter of
        ' type FileCabinetInfo, you want to cast it as a
        ' FILEPATHS structure. The LSET statement does that
        ' for you. You can also use the CopyMemory API function,
        ' but this is simpler.

        Dim fp As FILEPATHS = DirectCast(Marshal.PtrToStructure(Param1, GetType(FILEPATHS)), FILEPATHS)

        If fp.Win32Error = NO_ERROR Then
          RaiseEvent AfterExtract(fp.Target)
        End If
        CabinetCallback = fp.Win32Error

      Case SPFILENOTIFY_FILEINCABINET
        Select Case Context
          Case SetupIterateCabinetActions.sicCount
            '
            ' Counting? Increment the private counter
            ' variable each time, and tell Windows
            ' to skip further processing for the file.
            '
            mlngCount = mlngCount + 1
            CabinetCallback = FILEOP.FILEOP_SKIP

          Case SetupIterateCabinetActions.sicReport
            CabinetCallback = fHandleReport(Param1)

          Case SetupIterateCabinetActions.sicGetXML
            CabinetCallback = fHandleXML(Param1)

          Case SetupIterateCabinetActions.sicExtract
            CabinetCallback = fHandleExtract(Param1)
        End Select
    End Select

NormalExit:
    Exit Function

HandleErrors:
    Err.Raise(Err.Number, conClass & ".CabCallBack", Err.Description)
    Resume NormalExit
  End Function

  Private Function fHandleReport(ByVal fici As IntPtr) As Integer
    Dim foAction As FILEOP
    Dim blnDoIt As Boolean
    Dim strFile As String = ""
    Dim ft As FILETIME
    Dim dtm As Date
    Dim strPath As String = ""
    Dim strFull As String

    ' Assume you want to keep processing.

    foAction = FILEOP.FILEOP_SKIP

    ' Assume you don't want to process the
    ' current file.

    blnDoIt = False

    ' Get the file name passed to this callback function.

    Dim fileInCabinetInfo As FILE_IN_CABINET_INFO = _
     DirectCast(Marshal.PtrToStructure(fici, GetType(FILE_IN_CABINET_INFO)), FILE_IN_CABINET_INFO)
    strFull = fileInCabinetInfo.NameInCabinet
    Call fSplitFile(strFull, strPath, strFile)

    ' If you haven't specified a file to investigate,
    ' investigate them all.

    If Strings.Len(mstrFileToExtract) = 0 Then
      blnDoIt = True
    Else

      ' Otherwise, check to see if this is the file you
      ' want extracted.

      If StrComp(strFull, mstrFileToExtract, vbTextCompare) = 0 Then

        ' If you found a match for the one file
        ' you're interested in, abort processing afterwards.

        foAction = FILEOP.FILEOP_ABORT
        blnDoIt = True
      End If
    End If

    If blnDoIt Then

      ' Retrieve the file date information.

      With fileInCabinetInfo
        Call DosDateTimeToFileTime(.DosDate, .DosTime, ft)
        dtm = fFileTimeToVBATime(ft, False)
      End With


      RaiseEvent FileFound(strFile, dtm, fileInCabinetInfo.FileSize, strPath)
    End If
    fHandleReport = CInt(foAction)
  End Function

  Private Function fHandleXML(ByVal fici As IntPtr) As Integer
    Dim foAction As FILEOP
    Dim blnCancel As Boolean
    Dim blnDoIt As Boolean
    Dim strFile As String = ""
    Dim ft As FILETIME
    Dim dtm As Date
    Dim strPath As String = ""
    Dim strFull As String

    On Error GoTo HandleErrors

    ' Assume you want to keep processing.

    foAction = FILEOP.FILEOP_SKIP

    ' Assume you don't want to process the
    ' current file.

    blnDoIt = False

    ' Get the file name passed to this callback function.

    Dim fileInCabinetInfo As FILE_IN_CABINET_INFO = _
     DirectCast(Marshal.PtrToStructure(fici, GetType(FILE_IN_CABINET_INFO)), FILE_IN_CABINET_INFO)
    strFull = fileInCabinetInfo.NameInCabinet
    Call fSplitFile(strFull, strPath, strFile)

    ' If you haven't specified a file to investigate,
    ' investigate them all.

    If Strings.Len(mstrFileToExtract) = 0 Then
      blnDoIt = True
    Else

      ' Otherwise, check to see if this is the file you
      ' want extracted.

      If StrComp(strFile, mstrFileToExtract, vbTextCompare) = 0 Then

        ' If you found a match for the one file
        ' you're interested in, abort processing
        ' afterwards.

        foAction = FILEOP.FILEOP_ABORT
        blnDoIt = True
      End If
    End If
    If blnDoIt Then

      ' Retrieve the file date information.

      With fileInCabinetInfo
        Call DosDateTimeToFileTime(.DosDate, .DosTime, ft)
        dtm = fFileTimeToVBATime(ft, False)
      End With
      mstrXML = mstrXML & _
       fBuildXMLElement( _
       fBuildXMLElement(strFull, conXMLFullName) & _
       fBuildXMLElement(strFile, conXMLName) & _
       fBuildXMLElement(CStr(dtm), conXMLDate) & _
       fBuildXMLElement(CStr(fileInCabinetInfo.FileSize), conXMLSize) & _
       fBuildXMLElement(strPath, conXMLPath), conXMLFile) & vbCrLf
    End If
    fHandleXML = CLng(foAction)

NormalExit:
    Exit Function

HandleErrors:
    Err.Raise(Err.Number, Err.Source, Err.Description)
    Resume NormalExit
  End Function

  Private Function fHandleExtract(ByVal fici As IntPtr) As Integer
    Dim foAction As FILEOP
    Dim blnCancel As Boolean
    Dim blnDoIt As Boolean
    Dim strFile As String
    Dim strPath As String = ""
    Dim strFull As String

    On Error GoTo HandleErrors

    ' Assume you want to keep processing without
    ' extracting the file.

    foAction = FILEOP.FILEOP_SKIP

    ' Assume you don't want to process the
    ' current file at all.

    blnDoIt = False

    ' Get the file that's been found in the CAB file.

    Dim fileInCabinetInfo As FILE_IN_CABINET_INFO = _
     DirectCast(Marshal.PtrToStructure(fici, GetType(FILE_IN_CABINET_INFO)), FILE_IN_CABINET_INFO)
    strFile = fileInCabinetInfo.NameInCabinet

    ' If you haven't specified a file to extract,
    ' extract them all.

    If Strings.Len(mstrFileToExtract) = 0 Then
      blnDoIt = True
    Else

      ' Otherwise, check to see if this is the file you
      ' want extracted.

      If StrComp(strFile, mstrFileToExtract, _
       vbTextCompare) = 0 Then

        ' If you found a match for the one file
        ' you're interested in, abort processing
        ' afterwards.

        blnDoIt = True
      End If
    End If

    If blnDoIt Then
      RaiseEvent BeforeExtract(strFile, blnCancel)
      If Not blnCancel Then
        strFull = fCalcOutputFile(strFile)
        Call fSplitFile(strFull, strPath, strFile)

        ' Better make sure the path exists
        ' before attempting to create the file.

        If fMakePath(strPath) Then
          strFull = fileInCabinetInfo.FullTargetName
          foAction = FILEOP.FILEOP_DOIT
        End If
      End If
    End If
    fHandleExtract = CLng(foAction)

NormalExit:
    Exit Function

HandleErrors:
    Err.Raise(Err.Number, Err.Source, Err.Description)
    Resume NormalExit
  End Function

  Private Function fErrToText(ByVal lngErr As Integer) As String
    Dim strOut As String

    ' Given a Windows error number, convert to text.
    ' Only handles the most common errors.
    Select Case lngErr
      Case 2
        strOut = "The system cannot find the file specified."
      Case 3
        strOut = "The system cannot find the path specified."
      Case 4
        strOut = "The system cannot open the file."
      Case 5
        strOut = "Access is denied."
      Case 8
        strOut = "Not enough storage is available to process this command."
      Case 13
        strOut = "Invalid data."
      Case 14
        strOut = "Not enough storage is available to complete this operation."
      Case 15
        strOut = "The system cannot find the drive specified."
      Case 19
        strOut = "The media is write protected."
      Case 20
        strOut = "The system cannot find the device specified."
      Case 21
        strOut = "The device is not ready."
      Case 23
        strOut = "Data error (cyclic redundancy check)."
      Case 25
        strOut = "The drive cannot locate a specific area or track on the disk."
      Case 26
        strOut = "The specified disk or diskette cannot be accessed."
      Case 27
        strOut = "The drive cannot find the sector requested."
      Case 29
        strOut = "The system cannot write to the specified device."
      Case 30
        strOut = "The system cannot read from the specified device."
      Case 31
        strOut = "A device attached to the system is not functioning."
      Case 32
        strOut = "The process cannot access the file because it is being used by another process."
      Case 33
        strOut = "The process cannot access the file because another process has locked a portion of the file."
      Case 39
        strOut = "The disk is full."
      Case 82
        strOut = "The directory or file cannot be created."
      Case 111
        strOut = "The file name is too long."
      Case 112
        strOut = "There is not enough space on the disk."
      Case 123
        strOut = "The filename, directory name, or volume label syntax is incorrect."
      Case Else
        strOut = "Unknown error."
    End Select
    fErrToText = strOut
  End Function

  Private Function fGetError(ByVal lngErr As Integer) As String
    Dim strOut As String
    '
    ' Return an error message for an internal error.
    ' Add more to this SELECT CASE, if you need more.
    '
    Select Case lngErr
      Case Errors.errNoCabFile
        strOut = conErrNoCabFile
      Case Else
        strOut = conErrUnknown
    End Select
    fGetError = strOut
  End Function

  Private Function fBuildXMLElement(ByVal strValue As String, _
   ByVal strTag As String, Optional ByVal strAttributeName As String = vbNullString, _
   Optional ByVal strAttributeValue As String = vbNullString) As String

    Dim strOut As String

    ' Given a piece of text ("HELLO", for example) and a tag
    ' ("VALUE", for example), return a valid XML element:
    ' <VALUE>Hello</VALUE>

    ' You can optionally specify a single attribute value.

    strOut = "<" & strTag

    If Strings.Len(strAttributeName) > 0 Then
      strOut = strOut & " " & strAttributeName & " = '" & strAttributeValue & "'"
    End If
    strOut = strOut & ">" & strValue & "</" & strTag & ">"

    fBuildXMLElement = strOut
  End Function

  Private Function fFixPath(ByVal strPath As String) As String

    ' Append a trailing "\" to a path, if necessary.

    If Strings.Right(strPath, 1) = "\" Then
      fFixPath = strPath
    Else
      fFixPath = strPath & "\"
    End If
  End Function

  Private Sub fSplitFile(ByVal strFull As String, ByRef strPath As String, _
   ByRef strFile As String)

    Dim lngPos As Integer

    ' Given a full path, parse it and return
    ' the path and file name.

    lngPos = InStrRev(strFull, "\")
    If lngPos > 0 Then
      strPath = Strings.Left(strFull, lngPos)
      strFile = Mid(strFull, lngPos + 1)
    Else
      strPath = vbNullString
      strFile = strFull
    End If
  End Sub

  Private Function fCalcOutputFile(ByVal strFileFound As String) As String
    Dim strPath As String
    Dim strFile As String

    ' strFile is the name of the file, found in the CAB file.
    ' Given the values of mstrFileToExtract, mstrOutputPath,
    ' mstrOutputFile, return the full path of the output file.
    ' If mstrFileToExtract is empty, then disregard mstrOutputFile,
    ' because you'll be extracting all the files.

    ' Calculate the output path. Either use mstrOutputPath if it
    ' exists, or the CAB file's path if it doesn't.

    If Strings.Len(mstrOutputPath) > 0 Then
      strPath = mstrOutputPath
    Else
      strPath = fGetPath(CabName)
    End If

    ' Calculate the output file name. If mstrOutputFile exists,
    ' use it. If not, use the original name of the file.

    If Strings.Len(mstrOutputFile) > 0 Then
      strFile = mstrOutputFile
    Else
      strFile = strFileFound
    End If

    fCalcOutputFile = fFixPath(strPath) & strFile
  End Function

  Private Function fGetPath(ByVal strFile As String) As String
    Dim lngPos As Integer

    ' Given a file name with a path, pull off the path part.

    lngPos = InStrRev(strFile, "\")
    If lngPos > 0 Then
      fGetPath = Strings.Left(strFile, lngPos)
    Else
      fGetPath = ""
    End If
  End Function

  Public Function fMakePath(ByVal strPath As String) As Boolean
    Dim strItems() As String
    Dim strTemp As String = ""
    Dim lngUB As Integer
    Dim lngLB As Integer
    Dim i As Integer
    Dim lngStop As Integer

    ' Create the folders in the path that was passed in.

    If Strings.Len(strPath) = 0 Then
      fMakePath = False
      GoTo NormalExit
    End If

    On Error Resume Next

    ' Attempt to create the path.
    ' If this returns no error or error 75,
    ' you're done. Otherwise, do the work.

    ' Get right of trailing "\", if it's there.

    If Strings.Right(strPath, 1) = "\" Then
      strPath = Strings.Left(strPath, Strings.Len(strPath) - 1)
    End If

    MkDir(strPath)

    Select Case Err.Number
      Case 76
        ' Path doesn't exist.
      Case 75
        ' Path exists already, get out.
        fMakePath = True
        GoTo NormalExit
      Case 0
        ' Folder created successfully.
        fMakePath = True
        GoTo NormalExit
      Case Else
        ' This shouldn't happen.
        fMakePath = False
        GoTo NormalExit
    End Select

    ' Create an array full of all the items
    ' in the path, delimited with "\".

    strItems = Split(strPath, "\")

    ' Store away the lower and upper bounds.

    lngLB = LBound(strItems)
    lngUB = UBound(strItems)

    ' You've already determined that you cannot
    ' create the path, given all the items. That is,
    ' if the path is C:\a\b\c\d\e, you know that
    ' you cannot create the path with the "e" on there.
    ' Therefore, this loop works its way backwards, looking for
    ' the longest path that either exists, or that you
    ' can create, without error.

    ' Once you've found or created a path, the rest of
    ' the code works the other direction--adds on the
    ' path items, creating folders, until you get them
    ' all created, or trigger a run-time error.

    ' You're going to loop from the next-to-last item
    ' back to the start, attempting to create
    ' or locate the path.

    lngStop = lngUB
    For lngStop = lngUB - 1 To lngLB Step -1
      Err.Clear()
      strTemp = vbNullString
      ' Build up the path to be tested.
      For i = lngLB To lngStop
        strTemp = strTemp & "\" & strItems(i)
      Next i
      ' Remove the leading "\".
      If Strings.Len(strTemp) > 1 Then
        strTemp = Mid(strTemp, 2)
      End If

      ' Attempt to create the folder.
      ' This could succeed (error 0),
      ' fail because the folder exists (error 75),
      ' or fail because some parent folder
      ' doesn't exist (error 76). If you get
      ' error 0 or 75, you're done.

      MkDir(strTemp)
      Select Case Err.Number
        Case 0, 75
          ' Path created or it exists.
          Exit For
        Case 76 ' Path wasn't found.
        Case Else
          fMakePath = False
          GoTo NormalExit
      End Select
    Next lngStop

    ' Starting where you left off when working
    ' backwards, attempt to create the folders
    ' working downwards. At any point, if you get
    ' an error, you're done.

    For i = lngStop + 1 To lngUB
      Err.Clear()
      strTemp = strTemp & "\" & strItems(i)
      MkDir(strTemp)
      If Err.Number <> 0 Then

        ' You can't create the path. Return False.

        fMakePath = False
        GoTo NormalExit
      End If
    Next i
    fMakePath = True

NormalExit:
    Exit Function
  End Function

End Class



Что касается простыни класса, то я его не дописал, т.к. мне нужно только GetInfo(), а извлекаю я через extrac32.exe -так больше нравится. Но часть кода для extract() что касается коллбэка таки-есть, не хотелось сильно уродовать старый код, ну и не стал местами переделывать на IO.Path/IO.File -оставил манипуляции с путями в старом виде.

Roman MejtesCAB архивы это уже как ARJ =)
...
Я в том плане, что это динозавры :)
В чем-то я с тобой согласен. Хотя их никто не отменял.

У меня это используется для поиска стандартных файлов драйвера принтера.

Причем сложная процедура используется только на XP/2003
Последовательный поиск нужных файлов в папках:
DriverCachePath\i386 либо DriverCachePath\amd64
ServicePackSourcePath\i386 либо ServicePackSourcePath\amd64
SystemInstallPath\i386 либо SystemInstallPath\amd64
SetupDiskPrompt (на установочном диске windows)
Причем файлы с заданным именем ищутся как в явном виде, так и в CAB-архивах
Выбирается самый новый по дате файл из имеющихся на компе.

На Vista-Win 8.1 эта процедура нафиг не нужна, ибо необходимые файлы всегда есть в папке
DriverDirectory\3
А папки типа ServicePackSourcePath и SystemInstallPath на этих системах вообще отсутствуют, по крайней мере в реестре нет ключей, которые им соответствуют

Да в общем-то и на XP если это SP3 с обновлениями поиск в CAB-ах не нужен, правильные самые свежие файлы лежат не в них.

Но тем не менее я решил не портить идеологию старого кода и переписать его по честному.
Ну, вроде все сделал, работает как должно.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / А в .Net есть встроенная поддержка для работы с CAB-архивами?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]