• Авторизация


Получение версии ActiveX из CAB-файла 28-12-2007 16:43 к комментариям - к полной версии - понравилось!


Иногда в WEB-проектах на .NET бывает неудобно хардкодить версии ActiveX в CODEBASE. Данный код можно использовать для получения версии ActiveX напрямую из CAB-файла. Работает как на 32-х битных так и на 64-х битных Windows-платформах.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
 
/// <summary>
/// SetupApi Wrapper class
/// Platform SDK: Setup API
/// </summary>
public sealed  class CabinetVersionProvider
{
    /// <summary>
    /// Получает версию из CAB-файла
    /// </summary>
    /// <param name="cabFilePath">Полный путь до CAB-файла</param>
    /// <returns>значение FileVersion из inf-файла CAB-а</returns>
    public static string GetVersion(string cabFilePath)
    {
        return getVersion(cabFilePath);
    }
 
    #region Тонкости реализации
    /// <summary>
    /// The FILE_IN_CABINET_INFO class provides information about a file found 
    /// in the cabinet.
    /// Platform SDK: Setup API 
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    private struct 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 String FullTargetName;
    }
 
    /// <summary>
    /// The FILEPATHS structure stores source and target path information. 
    /// Platform SDK: Setup API 
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    private struct FILEPATHS
    {
        public String Target;
        public String Source;
        public uint Win32Error;
        public uint Flags;
    }
 
    /// <summary>
    /// Platform SDK: Setup API
    /// </summary>
    private enum FILEOP : uint
    {
        FILEOP_ABORT = 0, // Abort cabinet processing.
        FILEOP_DOIT,    // Extract the current file.
        FILEOP_SKIP        // Skip the current file.
    }
 
    /// <summary>
    /// The FileCallback callback function is used by a number of the setup 
    /// functions. The PSP_FILE_CALLBACK type defines a pointer to this callback 
    /// function. FileCallback is a placeholder for the application-defined 
    /// function name.
    /// Platform SDK: Setup API
    /// </summary>
    private delegate uint PSP_FILE_CALLBACK(IntPtr context, 
                        uint notification, IntPtr param1, IntPtr param2);
 
 
    /// <summary>
    /// The file has been extracted from the cabinet.
    /// </summary>
    private const uint SPFILENOTIFY_FILEINCABINET = 0x00000011;    
    /// <summary>
    /// The current file is continued in the next cabinet.
    /// </summary>
    private const uint SPFILENOTIFY_FILEEXTRACTED = 0x00000013;
    private const uint NO_ERROR = 0;
 
    /// <summary>
    /// The SetupIterateCabinet function iterates through all the files in a 
    /// cabinet and sends a notification to a callback function for each 
    /// file found.
    /// Platform SDK: Setup API
    /// </summary>
    [DllImport("SetupApi.dll", CharSet = CharSet.Auto)]
    private static extern bool SetupIterateCabinet(string cabinetFile, 
                uint reserved, PSP_FILE_CALLBACK callBack, IntPtr context);
 
    [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
    private static extern uint GetLastError();
 
    private static readonly Dictionary<string,string> m_cache = 
                                            new Dictionary<string, string>();
 
    private static string getVersion(string cabFilePath)
    {
        lock(m_cache)
        {
            string value;
            if(!m_cache.TryGetValue(cabFilePath, out value))
            {
                value = new CabinetVersionProvider(cabFilePath).m_version;
                value = string.IsNullOrEmpty(value) ? null : value;                    
                m_cache.Add(cabFilePath, value);
            }
            return value;
        }
    }
 
    private CabinetVersionProvider(string cabFileName)
    {
        m_version = null;
        m_tempfile = null;
        if (!SetupIterateCabinet(cabFileName, 0, callBack, IntPtr.Zero))
            throw new Win32Exception((int)GetLastError());
        if (m_tempfile != null)
        {
            string fileContent = File.ReadAllText(m_tempfile);
            MatchCollection mc = m_re.Matches(fileContent);
            if(mc.Count>0)
                m_version = mc[0].Groups[1].Captures[0].Value.Trim();
            try
            {
                File.Delete(m_tempfile);
            }
            catch(Exception err)
            {
                Trace.WriteLine(err);
            }
        }
 
    }
 
    private string m_version;
    private string m_tempfile;
 
    private static readonly Regex m_re = 
            new Regex(@"^\s*FileVersion\s*=\s*([^\s]+)\s*$",
                    RegexOptions.IgnoreCase
                        |RegexOptions.CultureInvariant
                        |RegexOptions.Multiline);
 
    private uint callBack(IntPtr context, uint notification,IntPtr param1, 
                                                            IntPtr param2)
    {
        switch(notification)
        {
            case SPFILENOTIFY_FILEINCABINET:
                if (m_tempfile != null)
                    return (uint)FILEOP.FILEOP_SKIP;
                FILE_IN_CABINET_INFO fileInCabinetInfo = 
                        (FILE_IN_CABINET_INFO)Marshal.PtrToStructure(
                                                            param1, 
                                                            typeof(FILE_IN_CABINET_INFO));
                if (fileInCabinetInfo.NameInCabinet.ToLower().EndsWith(".inf"))
                {
                    fileInCabinetInfo.FullTargetName = (m_tempfile = Path.GetTempFileName());
                    Marshal.StructureToPtr(fileInCabinetInfo, param1, true);
                    return (uint)FILEOP.FILEOP_DOIT;
                }
                else
                    return (uint)FILEOP.FILEOP_SKIP;
            case SPFILENOTIFY_FILEEXTRACTED:
                FILEPATHS filePaths =
                    (FILEPATHS)Marshal.PtrToStructure(param1, typeof(FILEPATHS));
                return filePaths.Win32Error;                    
            default:
                return NO_ERROR;                    
        }
    }
    #endregion
}
вверх^ к полной версии понравилось! в evernote
Комментарии (4):
07-04-2008-06:54 удалить
Порно ролики
>>>>>ТУУУУУУТ<<<<<<<
porno-house .net (убрать пробел перед точкой, вставить в браузер, нажать Энтер)
УБЕРИТЕ ПРОБЕЛЫ ИЗ ССЫЛКИ -> МОЖНО ВСТАВЛЯТЬ В БРАУЗЕР И СМОТРЕТЬ ПОРНООООО
03-09-2008-23:44 удалить
прикол, что надо!
Интересно, а сможешь познакомиться с девушками?
Всегда даю лучший совет, вот и тебе скажу!
Вот ссылка на досуг.
девчата находятся он-лайн тут.
Тебе понравится.
Nagasaki7565 02-02-2009-05:29 удалить
Привет!
Спасибо за ваши записи,
В своём дневнике я раздаю инвайты (приглашения) в закрытый блог - Leprosorium, буду раз, если вы присоединитесь к нашему сообществу.

С уважением, Нагасаки
09-02-2009-01:13 удалить
Здравствуйте
Добро пожаловать в закрытый клуб интеллектуалов!


[показать]


Комментарии (4): вверх^

Вы сейчас не можете прокомментировать это сообщение.

Дневник Получение версии ActiveX из CAB-файла | dimzon541 - Поток не замутненного разумом сознания... | Лента друзей dimzon541 / Полная версия Добавить в друзья Страницы: раньше»