2011-05-23 22 views
5

Bir CAB dosyasının içeriğini ayıklamak için kod yazmayı deniyorum, ancak SetupIterateCabinet rutinini kullanırken sorun yaşıyorum.SetupIterateCabinet ile C# nasıl kullanılır #

geri aramasında SPFILENOTIFY_FILEINCABINET olayı işlerken sorun gelir Ancak burada http://msdn.microsoft.com/en-us/library/aa377404(v=vs.85).aspx

doktor bu

private const uint SPFILENOTIFY_CABINETINFO = 0x00000010; 
    private const uint SPFILENOTIFY_FILEINCABINET = 0x00000011; 
    private const uint SPFILENOTIFY_NEEDNEWCABINET = 0x00000012; 
    private const uint SPFILENOTIFY_FILEEXTRACTED = 0x00000013; 
    private const uint SPFILENOTIFY_FILEOPDELAYED = 0x00000014; 
    private const uint NO_ERROR = 0; 

    private const uint FILEOP_ABORT = 0; 
    private const uint FILEOP_DOIT=      1; 
    private const uint FILEOP_SKIP=      2; 
    private const uint FILEOP_NEWPATH=     4; 

    static void Main(string[] args) 
    { 
     SetupIterateCabinet("c:\\SomeCab.cab", 0, new PSP_FILE_CALLBACK(CallBack), 0); 


     Console.ReadKey(); 
    } 

    [DllImport("SetupApi.dll", CharSet = CharSet.Auto)] 
    public static extern bool SetupIterateCabinet(string cabinetFile, 
         uint reserved, PSP_FILE_CALLBACK callBack, uint context); 

    public delegate uint PSP_FILE_CALLBACK(uint context, uint notification, 
              IntPtr param1, IntPtr param2); 

    private static uint CallBack(uint context, uint notification, IntPtr param1, 
         IntPtr param2) 
    { 
     uint rtnValue = NO_ERROR; 
     switch (notification) 
     { 
      case SPFILENOTIFY_FILEINCABINET: 
       rtnValue = OnFileFound(context, notification, param1, param2); 
       break; 
      case SPFILENOTIFY_FILEEXTRACTED: 
       rtnValue = OnFileExtractComplete(param1); 
       break; 
      case SPFILENOTIFY_NEEDNEWCABINET: 
       rtnValue = NO_ERROR; 
       break; 
     } 
     return rtnValue; 
    } 

    private static uint OnFileExtractComplete(IntPtr param1) 
    { 
     Console.WriteLine("Complete"); 
     return FILEOP_DOIT; 
    } 


    [StructLayout(LayoutKind.Sequential)] 
    struct _FILE_IN_CABINET_INFO { 
     IntPtr NameInCabinet; 
     int FileSize; 
     int Win32Error; 
     int DosDate; 
     int DosTime; 
     int DosAttribs; 
     StringBuilder FullTargetName; 
    }; 

    static private uint OnFileFound(uint context, uint notification, IntPtr param1, IntPtr param2) 
    { 
     _FILE_IN_CABINET_INFO fc = new _FILE_IN_CABINET_INFO() ; 
     Marshal.PtrToStructure(param1, fc); 

     return 1; 
    } 

gibi düzgün alabilirsiniz bakın. Dokümantasyona göre, bu, bir dosyadır, dosya ayıklamak istediğimin adını koymak zorundayım. Yapının neye benzemesi gerektiğini bulmakta zorlanıyorum ve belki de param bir yapıya nasıl dönüştürülür? .

cevap

0

Geri arama işlevinizin döndürme değerleriyle ilgili bir sorun olduğunu düşünüyorum. SPFILENOTIFY_FILECABINET üzerinde, FILEOP_DOIT değerini iade etmelisiniz. Dönmeden önce, FILE_IN_CABINTE_INFO dosyasında dosya adı ayarlamalısınız. Lütfen daha sonra kod örneği ekleyebilirim http://www.codeproject.com/Articles/7165/Iterate-and-Extract-Cabinet-File Bazı kod örneklerini ekleyebilirim. GTG şimdi

DÜZENLEME: Aşağıdaki

Kod örneği. Denemedim ama işe yarayacağına inanıyorum. Yapıyı kodunuza benzer şekilde tutmaya çalıştım. Bu nasıl FILE_IN_CABINET_INFO sınıfını ve doğru değerleri tanımlamak için ayarlanabilir göstereceğiz ve geri aramasında döndü gerektiğini

public delegate uint PSP_FILE_CALLBACK(uint context, uint notification, IntPtr param1, IntPtr param2); 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    public class FILE_IN_CABINET_INFO { 
     public String NameInCabinet; 
     public uint FileSize; 
     public uint Win32Error; 
     public ushort DosDate; 
     public ushort DosTime; 
     public ushort DosAttribs; 

     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
     public System.String FullTargetName; 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    public class FILEPATHS { 
     public String Target; 
     public String Source; 
     public uint Win32Error; 
     public uint Flags; 
    } 


    public const uint SPFILENOTIFY_FILEINCABINET = 0x00000011; // The file has been extracted from the cabinet. 
    public const uint SPFILENOTIFY_NEEDNEWCABINET = 0x00000012; // file is encountered in the cabinet. 
    public const uint SPFILENOTIFY_FILEEXTRACTED = 0x00000013; // The current file is continued in the next cabinet. 

    public const uint NO_ERROR = 0; 

    public const uint FILEOP_ABORT = 0; // Abort cabinet processing. 
    public const uint FILEOP_DOIT = 1; // Extract the current file. 
    public const uint FILEOP_SKIP = 2; // Skip the current file. 

    [DllImport("SetupApi.dll", CharSet = CharSet.Auto)] 
    public static extern bool SetupIterateCabinet(string cabinetFile, uint reserved, PSP_FILE_CALLBACK callBack, uint context); 

    [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] 
    public static extern uint GetLastError(); 

    static void Main(string[] args) { 
     IterateCabinet(@"c:\SomeCab.cab"); 
    } 

    public static void IterateCabinet(string filePath) { 
     PSP_FILE_CALLBACK callback = new PSP_FILE_CALLBACK(CallBack); 

     if (!SetupIterateCabinet(filePath, 0, callback, 0)) 
      throw new Win32Exception((int)GetLastError()); 
    } 

    static uint CallBack(uint context, uint notification, IntPtr param1, IntPtr param2) { 
     if (notification == SPFILENOTIFY_FILEINCABINET) 
      return OnFileFound(context, notification, param1, param2); 
     else if (notification == SPFILENOTIFY_FILEEXTRACTED) 
      return OnFileExtractComplete(param1); 
     else if (notification == SPFILENOTIFY_NEEDNEWCABINET) 
      return NO_ERROR; 
     return NO_ERROR; 
    } 

    static uint OnFileFound(uint context, uint notification, IntPtr param1, IntPtr param2) { 
     FILE_IN_CABINET_INFO fileInCabinetInfo = (FILE_IN_CABINET_INFO)Marshal.PtrToStructure(param1, typeof(FILE_IN_CABINET_INFO)); 
     fileInCabinetInfo.FullTargetName = fileInCabinetInfo.NameInCabinet; // extract to current directory 
     return FILEOP_DOIT; 
    } 

    static uint OnFileExtractComplete(IntPtr param1) { 
     FILEPATHS filePaths = (FILEPATHS)Marshal.PtrToStructure(param1, typeof(FILEPATHS)); 

     if (filePaths.Win32Error == NO_ERROR) 
      Console.WriteLine("File {0} extracted to {1} " + filePaths.Source, filePaths.Target); 
     else 
      Console.WriteLine("Errors occurred while extracting cab File {0} to {1} ", filePaths.Source, filePaths.Target); 

     return filePaths.Win32Error; 
    } 
İlgili konular