Формат файлов VDF

Для тех, кто хочет сделать мир лучше.
Сообщение
Автор
Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#1 Сообщение 24.08.2011, 21:26

Имеется 2 разновидности данных файлов: текстовые и бинарные. Бинарные в свою очередь подразделяются на 2 подтипа. Во всех файлах для записи текстовой информации используется кодировка ANSI.
Текстовые

Имеют древовидную структуру следующего характера:

Код: Выделить всё

"корневой_узел"
{
   "потомок_1"
   {
      "параметр" "значение"
      "параметр" "значение"
      "параметр" "значение"
      ;....
   }
   "потомок_2"
   {
      "потомок_2_1"
         {
            ;....
         }
   }
}
Количество уровней вложенности может быть практически любым (естественно, в пределах разумного).
Бинарные

На данный момент известно 2 файла данного типа: appinfo.vdf и packageinfo.vdf, а так же все файлы в каталоге "appcache\stats". Оба файла отличаются только заголовком, структура же у обоих файлов схожа.
Заголовок

Первая часть заголовка у обоих файлов идентична, поэтому она вынесена в отдельную структуру (по ней можно судить о типе файла):

Код: Выделить всё

  TVDFHeader = record
    Sign: uint32;
    Version: uint32;
  end;
Поля:
  • Sign - является идентификатором типа файла и может принимать следующие значения:
    1. $06564424 - "$DVx06" - appinfo.vdf;]
    2. $06565525 - "%UVx06" - packageinfo.vdf;
  • Version - предположительно, версия файла. Всегда имеет значение 0x00000001.

packageinfo.vdf имеет дополнительный заголовок:

Код: Выделить всё

  TVDFPKGHeader = packed record
    unk1: uint32;
    Hash: array[0..19] of byte;
    unk2: uint16;
  end;
и содержит следующие поля:
  • unk1 - всегда имеет значение 0x00000000;
  • Hash - предположительно, хеш (чего - не спрашивайте, пока не знаю, так как до этого файла пока не дошел на практике);
  • unk2 - всегда имеет значение 0x0000.

Тело файла

В общем случае имеется один корневой узел с потомками (как и для текстового формата). Каждый узел предваряется 1 ьайтом, указывающим тип узла:

Код: Выделить всё

	// Data type
	enum types_t
	{
		TYPE_NONE = 0,
		TYPE_STRING,
		TYPE_INT,
		TYPE_FLOAT,
		TYPE_PTR,
		TYPE_WSTRING,
		TYPE_COLOR,
		TYPE_UINT64,
		TYPE_NUMTYPES, 
	};
Первый (TYPE_NONE) означает, что у данного узла имеются потомки и он имеет только имя, а последний (TYPE_NUMTYPES = \x08) обозначает конец перечисления потомков текущего узла.
Узел описывается классом TVDFNode:
TVDFNode, TNodeData

Код: Выделить всё

  ENodeType =
    (TYPE_NONE     = 0,
     TYPE_STRING   = 1,
     TYPE_INT      = 2,
     TYPE_FLOAT    = 3,
     TYPE_PTR      = 4,
     TYPE_WSTRING  = 5,
     TYPE_COLOR    = 6,
     TYPE_UINT64   = 7,
     TYPE_NUMTYPES = 8);

  TNodeData = record
    case integer of
      0: (AsString: ShortString);
      1: (AsInt: integer);
      2: (AsFloat: single);
      3: (AsPointer: Pointer);
      4: (AsWideString: ShortString);
      5: (AsColor: integer);
      //6: (AsUINT64: uint64);
  end;

  TVDFNode = class
    private
      fChildrensCount: integer;
      fChildrens: array of TVDFNode;

      fName: AnsiString;
      fType: ENodeType;
      fDataSize: integer;
      fData: TNodeData;

      function GetChildrenByIdx(Idx: integer): TVDFNode;
      function GetChildrenByName(Name: AnsiString): TVDFNode;
      procedure SetData(NewData: AnsiString);
    public
      constructor Create();
      destructor Destroy(); override;

      function LoadFromStreamAsBinary(Stream: TStream): boolean;
      procedure SaveToStreamAsBinary(Stream: TStream);
      procedure LoadFromFileAsText(FileName: string);
      procedure SaveToStreamAsText(Stream: TStream);

      property ChildrensCount: integer read fChildrensCount;
      property ChildrenByIdx[Idx: integer]: TVDFNode read GetChildrenByIdx;
      property Children[Name: AnsiString]: TVDFNode read GetChildrenByName; default;
      procedure AddChildren(NewChild: TVDFNode);

      property Name: AnsiString read fName write fName;
      property Type_: ENodeType read fType;
      property DataSize: integer read fDataSize;

      property DataAsString: ShortString read fData.AsString;
      property DataAsInt: integer read fData.AsInt;
      property DataAsFloat: single read fData.AsFloat;
      property DataAsPointer: Pointer read fData.AsPointer;
      property DataAsWideString: ShortString read fData.AsWideString;
  end;
Процедура считывания подобного дерева имеет следующий вид (все строковые данные представляют собой NULL-terminated строку):
TVDFNode.LoadFromStreamAsBinary

Код: Выделить всё

function TVDFNode.LoadFromStreamAsBinary(Stream: TStream): boolean;
var
  i: integer;
  float: single;
  //i64: uint64;
begin
  result:=false;
  Stream.Read(fType, 1);
  if (fType = TYPE_NUMTYPES) then
    Exit;
  fName:=Stream.ReadStrZ();
  case byte(fType) of
    NODE_TYPE_NONE:
      while true do
      begin
        inc(fChildrensCount);
        SetLength(fChildrens, fChildrensCount);
        fChildrens[fChildrensCount-1]:=TVDFNode.Create();
        if (not fChildrens[fChildrensCount-1].LoadFromStreamAsBinary(Stream)) then
        begin
          dec(fChildrensCount);
          fChildrens[fChildrensCount].Free;
          SetLength(fChildrens, fChildrensCount);
          break;
        end;
      end;
    NODE_TYPE_STRING:
      self.fData.AsString:=pAnsiChar(Stream.ReadStrZ());
    NODE_TYPE_INT{, NODE_TYPE_PTR, NODE_TYPE_COLOR}:
      begin
        Stream.Read(i, 4);
        self.fData.AsInt:=i;
      end;
    NODE_TYPE_FLOAT:
      begin
        Stream.Read(float, 4);
        self.fData.AsFloat:=float;
      end;
    NODE_TYPE_WSTRING:
      begin
        Writeln('WideString!');
      end;
   { NODE_TYPE_UINT64:
      begin
        Stream.Read(i64, 4);
        fData.AsUINT64:=i64;
      end;  }
      else Writeln(byte(fType));
  end;

  result:=true;
end;
appcache\appinfo.vdf

Поскольку в appinfo.vdf хранится информация о приложениях (а так же некоторая информация о файлах кэша), то он имеет вид последовательного набора записей, каждая их которых представляет собой древовидную структуру с заголовком. Каждая запись имеет следующий заголовок:

Код: Выделить всё

  TVDFAppHeader = record
    AppID: uint32;
    DataSize: uint32;
  end;
Поля:
  • AppID - из названия понятно, что является Application ID;
  • DataSize - хранит размер области данных данной записи.
Далее следует информация о записи:

Код: Выделить всё

  TVDFAppInfo = record
    AppType: uint32;
    unk2: uint32;
    LastChangeNumber: uint32;
  end;
Поля:
  • AppType - определяет тип записи:
    1. 0x00000000 - файл кэша;
    2. 0x00000002 - приложение
  • unk2 - неизвестно;
  • LastChangeNumber - вероятно, определяет, в какой модификации файла данная запись была изменена в последний раз (я так и не разобрался, откуда брать текущую версию :( ).
Каждый узел древовидной структуры имеет мини-заголовок (число типа uint16), определяющий тип узла. На данный момент известны следующие типы:
  1. 0x0002 - информация о приложении;
  2. 0x0003 - дополнительные сведения (у файлов кэша содержит только одну запись - "cddbfingerprint");
  3. 0x0004 - информация о запуске (сигнатуры файлов для их проверки перед запуском или после загрузки/распаковки, параметры запуска приложения под различными ОС);
  4. 0x0006 - сведения для установки (замена InstallScript.vdf в папке игры; содержит записи реестра и список приложений с параметрами запуска, необходимые для установки игры);
  5. 0x0007 - список файлов кэша;
  6. 0x000a - некоторая служебная информация (известно о следующих полях - "savefiles", "testonly", "quota", "maxnumfiles", "appidRedirect", "ignoreexternalfiles", "hidecloudui");
  7. 0x000e - значения для использования в MacOS
Каждый тип записи имеет свои наборы полей (данный момент пока не рассматривается, поскольку сам еще только начал типизировать их все).
После заголовка следует древовидный набор записей, описанный выше.
appcache\packageinfo.vdf

У packageinfo.vdf тело начинается с записи "appids" (хранит какие-то значения - 4-х байтовые числа - для всех файлов кэша). Все записи в данном файле имеют описанную выше древовидную структуру.
appcache\stats\*.bin

Все файлы в данном каталоге не содержат никаких заголовков и являются типичными VDF-файлами бинарного типа.
UserGameStats_[UserID]_[AppID].bin - содержат записи пользователя по его достижениям для конкретного приложения.
UserGameStatsSchema_[AppID].bin - содержат описание достижений для приложения (название достижения на различных языках, имя иконки для отображения).
Добавлено спустя 2 минуты 14 секунд:
Статья на данный момент описывает только общие положение и будет дополняться и исправляться по мере дальнейшего изучения формата файлов (которое длится менее 8-и часов :crazy: ).
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Аватара пользователя
[email protected]!c_V()1D
Разработчик
Разработчик
Сообщения: 2635
Зарегистрирован: 06.12.2007
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

#2 Сообщение 26.08.2011, 16:27

andreil
Можно же KeyValues.cpp(~.h) в Source SDK поисследовать было - там всё достаточно просто.

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#3 Сообщение 26.08.2011, 17:42

[email protected]!c_V()1D
А я все сам :) Спасибо за подсказку, гляну. Сейчас считывание разбиваю на два этапа для упрощения читабельности кода, когда закончу - выложу программу для мини-теста (поскольку у разных пользователей могут быть различные по содержимому файлы, то надо определить, какие еще поля не попали в определение - а они, блин, описаны текстом, а не кодами :( ).

PS: Там описано считывание только текстового VDF-файла ;) А у бинарного и назначение другое - это же замена CDR'у.
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#4 Сообщение 29.08.2011, 00:08

andreil, кстати, насчет того. что все сам.
По поводу pak формата, ты бы глянул бы код Quake

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#5 Сообщение 30.08.2011, 10:02

Fire666
Обязательно гляну.

А тем временем статья дополнена более внятным описанием древовидной структуры данных в бинарных файлах (отдельная благодарность [email protected]!c_V()1D'у - все-таки в файле KeyValues.h позаимствовал перечисление типов узлов), а так же обновил описание файлов appinfo.vdf и appcache.vdf, добавил описание файлов "appcache\stats\*.bin".
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#6 Сообщение 01.09.2011, 15:48

Наконец смог войти в сеть :D
Выкладываю для ознакомления программу для просмотра содержимого некоторых файлов Steam'а. При запуске просит указать путь к его папке. На данный момент отображает:
  1. Достижения, сохраненные локально (необходимо ввести UserID и AppId - оба можно узнать из имени файлов в "<Steam>\appcache\stats");
  2. Информацию о приобретенных приложениях (packageinfo.vdf);
  3. Информацию о доступных приложениях (appinfo.vdf; на данный момент реализовано частично, поскольку уточняются варианты полей с данными).
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#7 Сообщение 04.09.2011, 23:40

Написал небольшую программу для поверхностной (пока) проверки списка полей в appinfo.vdf. Желающим помочь просьба: положить в каталог с этим файлом и запустить. Консольный вывод необходимо перенаправить в файл ("reader.exe >>.\out.txt"). Если в выводе будет строчка, содержащая "Unknown field name: bla-bla" (за исключением "Football Manager 2011" и "Football Manager 2011 Demo" - там что-то непонятное с полями, только что это обнаружил %-) ), просьба выложить на обменник копию файла appinfo.vdf и фрагмент вывода с этими строчками включая название и ID приложения.

UP: Немного "укрепил" сканирование структуры файла.
Вложения
reader.zip
(25.2 КБ) 187 скачиваний
reader.zip
(25.2 КБ) 187 скачиваний
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#8 Сообщение 05.09.2011, 12:04

Предварительная структура записи в appinfo.vdf:
много букв

Код: Выделить всё

NODE_APP_INFO
  "_appid_"
  {
    "name"
    "metacritic_url"
    "metacritic_name"
    "metacritic_fullurl"
    "section_type"
    "type"
    "driverversion"
    "gameid"
    "ogg"
    "metacritic_score"
    "clienticon"
    "clienttga"
    "icon"
    "logo"
    "logo_small"
    "clienticns"
    "languages"
    {
      "_langname_"="_(int)bool_"
    }
  }

NODE_EXTENDED_INFO
  "extended"
  {
    "_name_"="_value_"
    "_country_codes_" ("JP RU")
    {
      "state"="eState*"
    }
  }

NODE_LAUNCH_INFO
  "_appid_"
  {
    "InstallScriptSignature"="_1024sign_"
    "shortname"
    "InstallDir"
    "DefaultLowViolenceCountries"="_country_codes_"
    "CheckGuid"="_filename_"
    "CheckGuids"="_filenames_"
    "InstallScriptSignature"="_1024sign_"
    "cegpublickey"="_key_"
    "contenttype"="_int_"
    "UseMMS"="_(int)bool_"
    "InstallScriptOverride="_(int)bool_"
    "signedfiles"
    {
      "_filename_"="_1024sign_"
    }
    "signaturescheckedonlaunch"
    {
      "_OS_"
      {
        "_OSname_"
        {
        }
      }
    }
    "launch"
    {
      "_name_"
      {
        "E(e)xecutable"="_filename_"
        "arguments"="_args_"
        "D(d)escription"="_descr_"
        "oslist"="_OSlist_"
      }
    }
  }

NODE_INSTALL
  "InstallScript"
  {
    "registry"
    {
      "_regpath_"
      {
        "_type_"
        {
          "_name_"="_value_"
        }
      }
    }
    "Run Process"
    {
      "_name_"
      {
        "HasRunKey"="_regkey_"
        "process 1"="_filename_"
        "command 1"="_com_"
        "NoCleanUp"="_(int)bool_"
        "MinimumHasRunValue"="_int_"
        "IgnoreExitCode"="_(int)bool_"
        "Requirement_OS"
        {
          "_if_"="_(int)bool_"  ("Is64BitWindows")
        }
      }
    }
    "EA OREG"
    {
      "string"
      {
        "_langname_"
        {
          "url"="_URL_"
        }
      }
    }
    "_gamename_ CD KEY"
    {
      "RegistryPath"="_regkey_"
    }
    "File Template"
    {
      "_name_"
      {
        "HasRunKey"="_regkey_"
        "template_file"="_filename_"
        "output_file"="_filename_"
        "MinimumHasRunValue"="_int_"
      }
    }
    "Registry If Not Present"
    {
      "_regpath_"
      {
        "_type_"
        {
          "_name_"="_value_"
        }
      }
    }
    "Run Process On Uninstall"
    {
      "_name_"
      {
        "HasRunKey"="_regkey_"
        "process 1"="_filename_"
        "command 1"="_com_"
        "NoCleanUp"="_(int)bool_"
        "MinimumHasRunValue"="_int_"
        "IgnoreExitCode"="_(int)bool_"
        "Requirement_OS"
        {
          "_if_"="_(int)bool_"  ("Is64BitWindows")
        }
      }
    }
    "Copy Folders"
    {
      "_name_"
      {
        "SrcFolder( )1"="_foldername_"
        "DstFolder( )1"="_foldername_"
        "IgnoreExitCode"="_(int)bool_"
        "NoCleanUp"="_(int)bool_"
        "MinimumHasRunValue"="_int_"
      }
    }
    "Copy Files"
    {
      "_name_"
      {
        "SrcFile( )1"="_filename_"
        "DstFile( )1"="_filename_"
        "IgnoreExitCode"="_(int)bool_"
        "NoCleanUp"="_(int)bool_"
        "MinimumHasRunValue"="_int_"
      }
    }
    "chmod"
    {
      "_filename_"="_int_"
    }
    "firewall"
    {
      "_name_"="_filename_"
    }
  }

     (Name='Delete Files On Uninstall') or (Name='RegistryIfNotPresent') or
     (Name='.NET Framework 2.0 SP1') then

NODE_CACHE_LIST
  "_appid_"
  {
    "_cache_appID_"
    {
      "name"=_filename_
      "systemdefined"=_(int)bool_
      "optional"=_(int)bool_
      "LVCache"=_(int)bool_
      "config"
      {
        "language"="_lang_name_"
        "lowviolence"="_(int)bool_"
        "oslist"="_OSlist"
      }
      "manifests"
      {
        "Public"="_int_"
        "maxsize"="_int_"
      }
      "testchange"="_(int)bool_"
    }
    "OverridesCDDB"=_(int)bool_
  }
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#9 Сообщение 05.09.2011, 12:11

andreil, а про acf напишешь?

Аватара пользователя
[email protected]!c_V()1D
Разработчик
Разработчик
Сообщения: 2635
Зарегистрирован: 06.12.2007
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

#10 Сообщение 05.09.2011, 12:27

Fire666
А это уже не катит?

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#11 Сообщение 05.09.2011, 14:49

Fire666
Вот изучу протоколы, по которым они качаются и изучу (пока Стим после скачивания их сразу же удаляет :( Но попробую вытянуть через WireShark).
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Morrolan e'Drien
Сержант
Сержант
Сообщения: 38
Зарегистрирован: 01.08.2009

#12 Сообщение 02.12.2011, 20:09

andreil писал(а):Предварительная структура записи в appinfo.vdf:
много букв

Код: Выделить всё

NODE_APP_INFO
  "_appid_"
  {
    "name"
    "metacritic_url"
    "metacritic_name"
    "metacritic_fullurl"
    "section_type"
    "type"
    "driverversion"
    "gameid"
    "ogg"
    "metacritic_score"
    "clienticon"
    "clienttga"
    "icon"
    "logo"
    "logo_small"
    "clienticns"
    "languages"
    {
      "_langname_"="_(int)bool_"
    }
  }

NODE_EXTENDED_INFO
  "extended"
  {
    "_name_"="_value_"
    "_country_codes_" ("JP RU")
    {
      "state"="eState*"
    }
  }

NODE_LAUNCH_INFO
  "_appid_"
  {
    "InstallScriptSignature"="_1024sign_"
    "shortname"
    "InstallDir"
    "DefaultLowViolenceCountries"="_country_codes_"
    "CheckGuid"="_filename_"
    "CheckGuids"="_filenames_"
    "InstallScriptSignature"="_1024sign_"
    "cegpublickey"="_key_"
    "contenttype"="_int_"
    "UseMMS"="_(int)bool_"
    "InstallScriptOverride="_(int)bool_"
    "signedfiles"
    {
      "_filename_"="_1024sign_"
    }
    "signaturescheckedonlaunch"
    {
      "_OS_"
      {
        "_OSname_"
        {
        }
      }
    }
    "launch"
    {
      "_name_"
      {
        "E(e)xecutable"="_filename_"
        "arguments"="_args_"
        "D(d)escription"="_descr_"
        "oslist"="_OSlist_"
      }
    }
  }

NODE_INSTALL
  "InstallScript"
  {
    "registry"
    {
      "_regpath_"
      {
        "_type_"
        {
          "_name_"="_value_"
        }
      }
    }
    "Run Process"
    {
      "_name_"
      {
        "HasRunKey"="_regkey_"
        "process 1"="_filename_"
        "command 1"="_com_"
        "NoCleanUp"="_(int)bool_"
        "MinimumHasRunValue"="_int_"
        "IgnoreExitCode"="_(int)bool_"
        "Requirement_OS"
        {
          "_if_"="_(int)bool_"  ("Is64BitWindows")
        }
      }
    }
    "EA OREG"
    {
      "string"
      {
        "_langname_"
        {
          "url"="_URL_"
        }
      }
    }
    "_gamename_ CD KEY"
    {
      "RegistryPath"="_regkey_"
    }
    "File Template"
    {
      "_name_"
      {
        "HasRunKey"="_regkey_"
        "template_file"="_filename_"
        "output_file"="_filename_"
        "MinimumHasRunValue"="_int_"
      }
    }
    "Registry If Not Present"
    {
      "_regpath_"
      {
        "_type_"
        {
          "_name_"="_value_"
        }
      }
    }
    "Run Process On Uninstall"
    {
      "_name_"
      {
        "HasRunKey"="_regkey_"
        "process 1"="_filename_"
        "command 1"="_com_"
        "NoCleanUp"="_(int)bool_"
        "MinimumHasRunValue"="_int_"
        "IgnoreExitCode"="_(int)bool_"
        "Requirement_OS"
        {
          "_if_"="_(int)bool_"  ("Is64BitWindows")
        }
      }
    }
    "Copy Folders"
    {
      "_name_"
      {
        "SrcFolder( )1"="_foldername_"
        "DstFolder( )1"="_foldername_"
        "IgnoreExitCode"="_(int)bool_"
        "NoCleanUp"="_(int)bool_"
        "MinimumHasRunValue"="_int_"
      }
    }
    "Copy Files"
    {
      "_name_"
      {
        "SrcFile( )1"="_filename_"
        "DstFile( )1"="_filename_"
        "IgnoreExitCode"="_(int)bool_"
        "NoCleanUp"="_(int)bool_"
        "MinimumHasRunValue"="_int_"
      }
    }
    "chmod"
    {
      "_filename_"="_int_"
    }
    "firewall"
    {
      "_name_"="_filename_"
    }
  }

     (Name='Delete Files On Uninstall') or (Name='RegistryIfNotPresent') or
     (Name='.NET Framework 2.0 SP1') then

NODE_CACHE_LIST
  "_appid_"
  {
    "_cache_appID_"
    {
      "name"=_filename_
      "systemdefined"=_(int)bool_
      "optional"=_(int)bool_
      "LVCache"=_(int)bool_
      "config"
      {
        "language"="_lang_name_"
        "lowviolence"="_(int)bool_"
        "oslist"="_OSlist"
      }
      "manifests"
      {
        "Public"="_int_"
        "maxsize"="_int_"
      }
      "testchange"="_(int)bool_"
    }
    "OverridesCDDB"=_(int)bool_
  }
А на что влияет "NoCleanUp" в "Run Process"? Если будет ноль, то удалит экзешник после запуска?
xoxol_007 писал(а):У вас, сударь, халява головного мозга.
Всякие файлики.

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#13 Сообщение 04.12.2011, 00:55

Morrolan e'Drien, Такого не проверял - как написал парсер, так пока и не трогал :blush:
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Ответить Вложения 1