Author Topic: API for PackageContents.xml  (Read 441 times)

0 Members and 1 Guest are viewing this topic.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
API for PackageContents.xml
« on: February 05, 2024, 02:29:45 AM »
Hi,

Is exist .Net API for reading, editing and creating the PackageContents.xml files?

Thank you.

AlexFielder

  • Mosquito
  • Posts: 11
Re: API for PackageContents.xml
« Reply #1 on: February 06, 2024, 11:42:35 AM »
Hi Andrey,

I have wondered this myself in recent weeks but it doesn't seem as though there is one.

What I am using however is something I recently found called "Text Transform". Inside Visual Studio 2022 this creates files with the .tt file extension. Basically, what it does is write/rewrite a file of the same name/path with the extension of your choosing, so in the case of the PackageContents.xml file you place it in the working directory and then use content such as the following to auto-populate the relevant file whenever you run a build:

Code: [Select]
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".xml" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#
    string output = File.ReadAllText(this.Host.ResolvePath("Properties\\AssemblyInfo.cs"));
    Regex pattern = new Regex("AssemblyVersion\\(\"(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<revision>\\d+)\\.(?<build>\\d+)\"\\)");
    MatchCollection matches = pattern.Matches(output);
    if(matches.Count == 1)
    {
        major = Convert.ToInt32(matches[0].Groups["major"].Value);
        minor = Convert.ToInt32(matches[0].Groups["minor"].Value);
        revision = Convert.ToInt32(matches[0].Groups["revision"].Value);
        build = Convert.ToInt32(matches[0].Groups["build"].Value);
    }
#>
<?xml version="1.0" encoding="utf-8" ?>
<ApplicationPackage
    SchemaVersion="1.0"
    AutodeskProduct="AutoCAD"
    ProductType="Application"
    Name="YourApplicationName"
    AppVersion="<#= major #>.<#= minor #>.<#= revision #>.<#= build #>"
    Description="YourApplicationDescription"
    Author="YourCompanyName"
    HelpFile="./Contents/Resources/YourHelpFile.htm"
    ProductCode="{Your-Product-GUID-Value}"
    UpgradeCode="{Your-Upgrade-GUID-Value}"
    Icon="./Contents/Resources/YourIcon.ico">
    <RuntimeRequirements OS="Win64" Platform="YourPlatform" SeriesMin="YourSeriesMin" SeriesMax="YourSeriesMax" SupportPath="./Contents/" />
    <CompanyDetails Name="YourCompanyName"
                    Email="YourCompanyEmail"
                    URL="YourCompanyWebsite"
                    Phone="YourCompanyPhone"/>
    <Components Description="YourComponentDescription">
        <AssemblyMappings>
            <AssemblyMapping Name="YourAssemblyName" Path="./Contents/YourAssembly.dll"/>
        </AssemblyMappings>
        <ComponentEntry AppName="YourComponentAppName"
                        Version="<#= major #>.<#= minor #>.<#= revision #>.<#= build #>"
                        ModuleName="./Contents/YourAssembly.dll"
                        AppDescription="YourComponentAppDescription."
                        LoadOnStartup="True"/>
    </Components>
</ApplicationPackage>

<#+
    int major = 0;
    int minor = 0;
    revision = 0;
    build = 0;
#>

the only change I needed to make to ensure these .tt files run (because I am using the same method for the AssemblyInfo.cs file is to add a pre-build event for both:

Code: [Select]
call "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)Properties\AssemblyInfo.tt"
call "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)PackageContents.tt"

 :-)

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: API for PackageContents.xml
« Reply #2 on: February 06, 2024, 12:41:07 PM »
Hello. Thanks for your answer.

Thanks for the suggestion, but in cases like this I would prefer to work with the object model.

Yes, I already realized that no API has appeared over the years. Many years ago I already created such an API and used it in my work. But since then this code has been lost by the customer. Now I'm writing this API again. Using this API, I want to automate the generation of PackageContents.xml files and also add functionality for their validation. It's code sources are here. One of the "tests" shows how to construct the object model and generate PackageContents.xml. Another "test" shows how to perform model validation. These are not real tests and I will replace them with real ones later. The project is under development.

For example, based on the example indicated in the test here, it generates such XML (Sorry, this site replaces the russian code chars by their codes):

Code - XML: [Select]
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <ApplicationPackage SchemaVersion="1.0" AppVersion="1.0" Author="Some developer" NameEnu="SomePackage" NameRus="SomePackage" DescriptionEnu="Some AutoCAD extension..." DescriptionRus="&#1053;&#1077;&#1082;&#1086;&#1090;&#1086;&#1088;&#1086;&#1077; &#1088;&#1072;&#1089;&#1096;&#1080;&#1088;&#1077;&#1085;&#1080;&#1077; &#1076;&#1083;&#1103; AutoCAD..." Icon="/Resources/Images/SomePackage.ico" HelpfileEnu="/Help/ENU/SomePackage.ENU.html" HelpfileRus="/Help/RUS/SomePackage.RUS.html" ProductCode="99ccd00e-d8d3-4225-9ab9-2205b38e5381" UpgradeCode="4d9ffebb-f415-4365-8bc1-7f15e709bd68">
  3.   <CompanyDetails Name="GPSM" PhoneEnu="+7-111-222-33-44" PhoneRus="+7-111-222-33-44" URLEnu="https://some.site.ru" URLRus="https://some.site.ru" EmailEnu="some.site@yandex.ru" EmailRus="some.site@yandex.ru" />
  4.   <Components>
  5.     <RuntimeRequirements OS="Win64" Platform="AutoCAD|Civil|Civil3D" SeriesMin="1.0" SeriesMax="2.0" SupportPathEnu="/ENU/Resources/Fonts;/ENU/Resources/Hatches" SupportPathRus="/RUS/Resources/Fonts;/RUS/Resources/Hatches" ToolPalettePathEnu="/ENU/Resources/ToolPalettes/Old;/ENU/Resources/ToolPalettes/New" ToolPalettePathRus="/RUS/Resources/ToolPalettes/Old;/RUS/Resources/ToolPalettes/New" />
  6.     <RegistryEntries>
  7.       <RegistryEntry Name="SomeRegistryName_1" Value="123" Flags="Create|Open" Type="REG_DWORD" />
  8.       <RegistryEntry Name="SomeRegistryName_2" Value="456" Flags="Create" Type="REG_QWORD" />
  9.       <RegistryEntry Name="SomeRegistryName_3" Value="%AppData%\SomeDir\SomeFile.json" Flags="OpenOnce" Type="REG_EXPAND_SZ" />
  10.       <RegistryEntry Name="SomeRegistryName_4" Value="C:\SomeDir2\SomeFile2.json" Flags="Open" Type="REG_SZ" />
  11.     </RegistryEntries>
  12.     <SystemVariables>
  13.       <SystemVariable Name="SomeSystemVariableName_1" Value="123" PrimaryType="Int16" StorageType="User" Owner="SomeAcRXservice" Flags="NoUndo" />
  14.       <SystemVariable Name="SomeSystemVariableName_11" Value="+234" PrimaryType="Int16" StorageType="User" Owner="SomeAcRXservice" Flags="SpacesAllowed" />
  15.       <SystemVariable Name="SomeSystemVariableName_12" Value="-345" PrimaryType="Int16" StorageType="User" Owner="SomeAcRXservice" Flags="OpenOnce" />
  16.       <SystemVariable Name="SomeSystemVariableName_13" Value="&amp;456" PrimaryType="Int16" StorageType="User" Owner="SomeAcRXservice" Flags="Create|Open" />
  17.       <SystemVariable Name="SomeSystemVariableName_14" Value="|567" PrimaryType="Int16" StorageType="User" Owner="SomeAcRXservice" Flags="Create" />
  18.       <SystemVariable Name="SomeSystemVariableName_2" Value="300" PrimaryType="Int32" StorageType="Database" Owner="SomeAcRXservice" Flags="DotIsEmpty" />
  19.       <SystemVariable Name="SomeSystemVariableName_3" Value="357,88" PrimaryType="Real" StorageType="Profile" Owner="SomeAcRXservice" Flags="Create|Chatty" />
  20.       <SystemVariable Name="SomeSystemVariableName_4" Value="Bingo" PrimaryType="String" StorageType="Session" Owner="SomeAcRXservice" Flags="SpacesAllowed" />
  21.     </SystemVariables>
  22.     <EnvironmentVariables>
  23.       <EnvironmentVariable Name="SomeEnvironmentVariableName_1" Value="SomeEnvironmentVariableValue_1" Type="String" Flags="Open" />
  24.       <EnvironmentVariable Name="SomeEnvironmentVariableName_2" Value="SomeEnvironmentVariableValue_2" Type="String" Flags="Open" />
  25.       <EnvironmentVariable Name="SomeEnvironmentVariableName_3" Value="SomeEnvironmentVariableValue_3" Type="String" Flags="Open" />
  26.       <EnvironmentVariable Name="SomeEnvironmentVariableName_4" Value="SomeEnvironmentVariableValue_4" Type="String" Flags="Open" />
  27.     </EnvironmentVariables>
  28.     <ComponentEntry AppName="SomeAppName_1" AppDescription="SomeAppName_1 description." AppType=".NET" ModuleNameEnu="My.MyAppName.Module_1" ModuleNameRus="&#1052;&#1086;&#1081;.&#1052;&#1086;&#1076;&#1091;&#1083;&#1100;.MyAppName_1" PerDocument="True" LoadReasons="LoadOnCommandInvocation|LoadOnProxy" XamlType="ContextualTabRule">
  29.       <Commands GroupName="SomeGroupName">
  30.         <Command Global="globName_1" LocalEnu="test_1" LocalRus="&#1090;&#1077;&#1089;&#1090;_1" HelpTopic="helpTopic_1" StartupCommand="True" />
  31.         <Command Global="globName_2" LocalEnu="test_2" LocalRus="&#1090;&#1077;&#1089;&#1090;_2" HelpTopic="helpTopic_2" StartupCommand="False" />
  32.         <Command Global="globName_3" LocalEnu="test_3" LocalRus="&#1090;&#1077;&#1089;&#1090;_3" HelpTopic="helpTopic_3" StartupCommand="False" />
  33.         <Command Global="globName_4" LocalEnu="test_4" LocalRus="&#1090;&#1077;&#1089;&#1090;_4" HelpTopic="helpTopic_4" StartupCommand="False" />
  34.       </Commands>
  35.       <AssemblyMappings>
  36.         <AssemblyMapping Name="SomeAppName_1" Path="./bin/win64/SomeAppName_1.dll" />
  37.         <AssemblyMapping Name="SomeAppName_2" Path="./bin/win64/SomeAppName_2.dll" />
  38.         <AssemblyMapping Name="SomeAppName_3" Path="./bin/win64/SomeAppName_3.dll" />
  39.         <AssemblyMapping Name="SomeAppName_4" Path="./bin/win64/SomeAppName_4.dll" />
  40.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_1.dll" />
  41.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_2.dll" />
  42.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_3.dll" />
  43.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_4.dll" />
  44.       </AssemblyMappings>
  45.     </ComponentEntry>
  46.     <ComponentEntry AppName="SomeAppName_2" AppDescription="SomeAppName_2 description." AppType=".NET" ModuleNameEnu="My.MyAppName.Module_2" ModuleNameRus="&#1052;&#1086;&#1081;.&#1052;&#1086;&#1076;&#1091;&#1083;&#1100;.MyAppName_2" PerDocument="False" LoadReasons="LoadOnCommandInvocation|LoadOnProxy" XamlType="ContextualTabRule">
  47.       <Commands GroupName="SomeGroupName">
  48.         <Command Global="globName_1" LocalEnu="test_1" LocalRus="&#1090;&#1077;&#1089;&#1090;_1" HelpTopic="helpTopic_1" StartupCommand="True" />
  49.         <Command Global="globName_2" LocalEnu="test_2" LocalRus="&#1090;&#1077;&#1089;&#1090;_2" HelpTopic="helpTopic_2" StartupCommand="False" />
  50.         <Command Global="globName_3" LocalEnu="test_3" LocalRus="&#1090;&#1077;&#1089;&#1090;_3" HelpTopic="helpTopic_3" StartupCommand="False" />
  51.         <Command Global="globName_4" LocalEnu="test_4" LocalRus="&#1090;&#1077;&#1089;&#1090;_4" HelpTopic="helpTopic_4" StartupCommand="False" />
  52.       </Commands>
  53.       <AssemblyMappings>
  54.         <AssemblyMapping Name="SomeAppName_1" Path="./bin/win64/SomeAppName_1.dll" />
  55.         <AssemblyMapping Name="SomeAppName_2" Path="./bin/win64/SomeAppName_2.dll" />
  56.         <AssemblyMapping Name="SomeAppName_3" Path="./bin/win64/SomeAppName_3.dll" />
  57.         <AssemblyMapping Name="SomeAppName_4" Path="./bin/win64/SomeAppName_4.dll" />
  58.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_1.dll" />
  59.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_2.dll" />
  60.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_3.dll" />
  61.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_4.dll" />
  62.       </AssemblyMappings>
  63.     </ComponentEntry>
  64.     <ComponentEntry AppName="SomeAppName_3" AppDescription="SomeAppName_3 description." AppType=".NET" ModuleNameEnu="My.MyAppName.Module_3" ModuleNameRus="&#1052;&#1086;&#1081;.&#1052;&#1086;&#1076;&#1091;&#1083;&#1100;.MyAppName_3" PerDocument="False" LoadReasons="LoadOnCommandInvocation|LoadOnProxy" XamlType="ContextualTabRule">
  65.       <Commands GroupName="SomeGroupName">
  66.         <Command Global="globName_1" LocalEnu="test_1" LocalRus="&#1090;&#1077;&#1089;&#1090;_1" HelpTopic="helpTopic_1" StartupCommand="True" />
  67.         <Command Global="globName_2" LocalEnu="test_2" LocalRus="&#1090;&#1077;&#1089;&#1090;_2" HelpTopic="helpTopic_2" StartupCommand="False" />
  68.         <Command Global="globName_3" LocalEnu="test_3" LocalRus="&#1090;&#1077;&#1089;&#1090;_3" HelpTopic="helpTopic_3" StartupCommand="False" />
  69.         <Command Global="globName_4" LocalEnu="test_4" LocalRus="&#1090;&#1077;&#1089;&#1090;_4" HelpTopic="helpTopic_4" StartupCommand="False" />
  70.       </Commands>
  71.       <AssemblyMappings>
  72.         <AssemblyMapping Name="SomeAppName_1" Path="./bin/win64/SomeAppName_1.dll" />
  73.         <AssemblyMapping Name="SomeAppName_2" Path="./bin/win64/SomeAppName_2.dll" />
  74.         <AssemblyMapping Name="SomeAppName_3" Path="./bin/win64/SomeAppName_3.dll" />
  75.         <AssemblyMapping Name="SomeAppName_4" Path="./bin/win64/SomeAppName_4.dll" />
  76.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_1.dll" />
  77.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_2.dll" />
  78.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_3.dll" />
  79.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_4.dll" />
  80.       </AssemblyMappings>
  81.     </ComponentEntry>
  82.     <ComponentEntry AppName="SomeAppName_4" AppDescription="SomeAppName_4 description." AppType=".NET" ModuleNameEnu="My.MyAppName.Module_4" ModuleNameRus="&#1052;&#1086;&#1081;.&#1052;&#1086;&#1076;&#1091;&#1083;&#1100;.MyAppName_4" PerDocument="False" LoadReasons="LoadOnCommandInvocation|LoadOnProxy" XamlType="ContextualTabRule">
  83.       <Commands GroupName="SomeGroupName">
  84.         <Command Global="globName_1" LocalEnu="test_1" LocalRus="&#1090;&#1077;&#1089;&#1090;_1" HelpTopic="helpTopic_1" StartupCommand="True" />
  85.         <Command Global="globName_2" LocalEnu="test_2" LocalRus="&#1090;&#1077;&#1089;&#1090;_2" HelpTopic="helpTopic_2" StartupCommand="False" />
  86.         <Command Global="globName_3" LocalEnu="test_3" LocalRus="&#1090;&#1077;&#1089;&#1090;_3" HelpTopic="helpTopic_3" StartupCommand="False" />
  87.         <Command Global="globName_4" LocalEnu="test_4" LocalRus="&#1090;&#1077;&#1089;&#1090;_4" HelpTopic="helpTopic_4" StartupCommand="False" />
  88.       </Commands>
  89.       <AssemblyMappings>
  90.         <AssemblyMapping Name="SomeAppName_1" Path="./bin/win64/SomeAppName_1.dll" />
  91.         <AssemblyMapping Name="SomeAppName_2" Path="./bin/win64/SomeAppName_2.dll" />
  92.         <AssemblyMapping Name="SomeAppName_3" Path="./bin/win64/SomeAppName_3.dll" />
  93.         <AssemblyMapping Name="SomeAppName_4" Path="./bin/win64/SomeAppName_4.dll" />
  94.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_1.dll" />
  95.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_2.dll" />
  96.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_3.dll" />
  97.         <AssemblyMappingFolder Path="./bin/win64/SomeAppName_4.dll" />
  98.       </AssemblyMappings>
  99.     </ComponentEntry>
  100.   </Components>
  101.   <DependentBundles>
  102.     <DependentBundle UpgradeCode="db69a20b-5cd9-449d-b8e4-ad6659fd8be6" VersionMin="1.0" VersionMax="2.0">
  103.       <Component AppName="Some.Other.Dependent.Bundle_1.Name" />
  104.       <Component AppName="Some.Other.Dependent.Bundle_2.Name" />
  105.       <Component AppName="Some.Other.Dependent.Bundle_3.Name" />
  106.       <Component AppName="Some.Other.Dependent.Bundle_4.Name" />
  107.     </DependentBundle>
  108.     <DependentBundle UpgradeCode="7e0b8649-56f9-49c5-8728-fdb289c75b5b" VersionMin="1.0" VersionMax="2.0">
  109.       <Component AppName="Some.Other.Dependent.Bundle_1.Name" />
  110.       <Component AppName="Some.Other.Dependent.Bundle_2.Name" />
  111.       <Component AppName="Some.Other.Dependent.Bundle_3.Name" />
  112.       <Component AppName="Some.Other.Dependent.Bundle_4.Name" />
  113.     </DependentBundle>
  114.     <DependentBundle UpgradeCode="cb1fc385-2c9a-4715-8358-3a2ab67096b6" VersionMin="1.0" VersionMax="2.0">
  115.       <Component AppName="Some.Other.Dependent.Bundle_1.Name" />
  116.       <Component AppName="Some.Other.Dependent.Bundle_2.Name" />
  117.       <Component AppName="Some.Other.Dependent.Bundle_3.Name" />
  118.       <Component AppName="Some.Other.Dependent.Bundle_4.Name" />
  119.     </DependentBundle>
  120.     <DependentBundle UpgradeCode="d5f3ed9d-65ee-46aa-abaa-f575f2b298e9" VersionMin="1.0" VersionMax="2.0">
  121.       <Component AppName="Some.Other.Dependent.Bundle_1.Name" />
  122.       <Component AppName="Some.Other.Dependent.Bundle_2.Name" />
  123.       <Component AppName="Some.Other.Dependent.Bundle_3.Name" />
  124.       <Component AppName="Some.Other.Dependent.Bundle_4.Name" />
  125.     </DependentBundle>
  126.   </DependentBundles>
  127. </ApplicationPackage>

« Last Edit: February 06, 2024, 12:54:05 PM by Andrey Bushman »