Home > Blogs > VMware ThinApp Blog


ThinApp Factory Feeds, Recipes, and FAQ

ThinApp Factory Feeds

What’s involved in creating a ThinApp Factory Feed or Recipe?

This is a post to describe the format and syntax for writing application feeds and recipes for ThinApp Factory.

What is a ThinApp Factory Feed? A feed is an online application source which can dynamically update applications whenever vendors patch and upgrade them. You can create your own feeds and add them to ThinApp Factory.

ThinApp Feed FAQ

  1. How do I subscribe to a feed in ThinApp Factory? In ThinApp Factory, go to Data sources > Feeds > Add Feed and type a feed name and feed URL. If you check OK to scan, ThinApp Factory automatically scans the feed. If you check OK to convert, ThinApp Factory automatically converts the applications in the feed into ThinApp packages.
  2. Is the feed in JSON format? Does the document need to comply with RFC 4726? Yes. A feed must be in JSON format and must comply with RFC 4627. However, ThinApp Factory accepts (ignores) comments in the JSON data.
  3. How can I validate a feed? When you scan a feed with ThinApp Factory, errors appear in the Data Sources view in ThinApp Factory. You can also point your browser to a feed and use a plug-in such as JSONView to validate the feed. (This plugin displays the JSON text nicely formatted, which helps you to debug.)
  4. What if one section has errors? A feed must be completely valid before ThinApp Factory can use any part of it. Any error, including an invalid feed URL, shows up in the Data Sources view in ThinApp Factory. URLs inside the feed that are not valid do not cause a feed parsing error but do result in a failed conversion task. A URL might be invalid if, for example, an application refers to an installer that no longer exists.
  5. Which image file formats make valid icons (jpg, png, and so on)? ThinApp Factory does not require, interpret, or infer image types and does not download images. Any image format supported by all popular browsers is acceptable.
  6. What if my recipe applies to Firefox 4.0, 4.0.1, 4.0.2, and so on? You need to specify multiple recipe application keys (appKeys) for the versions you want to include in the recipe. Each key should define an acceptable version.
  7. appKeys: Can I define a range of versions? No. You need to specify more than one key in the same recipe. Define one appKeys entry for each version. See
    the preceding question.

JSON Files

For those not familiar with JSON, Wikipedia has a good definition and sources for learning it – it’s not hard to learn either. Quite simply, it’s a TEXT file which defines arrays. There are also many different free tools for viewing and editing JSON available on the web – such as JSONVIEW.COM. They make plugins for Chrome and Firefox which allows one to open the JSON extensioned Text file with these browsers and view the arrays in easy-to-read formats.

JSON Format with ThinApp Factory

The JSON file used for feeds and recipes follows a few standards:

  • ThinApp Factory uses JSON version 4
  • Feed descriptions are optional
  • Listing Applications (application arrays) are optional
  • Listing Recipes (recipe arrays) are optional

Defining Applications in a Feed

A feed can contain applications, each of which describes a Windows application installer or ISO. You must uniquely define each application in a feed by specifying an application name, version, locale, and installer revision. Name and version are required. Locale and installerRevision are optional. The following attributes describe a particular version of a sample application.

{
// Name of the application (required).
"name": "Spotify",

// Version of the application (required).
"version": "4.56.23-Final",

// Locale of this application (optional).
"locale": "en_US",

// Revision of the installer for this application
// If you package the same application (name and version) into multiple installers,
// then each installer needs a unique revision:
"installerRevision": "Rev-01",

// An array of categories this application might belong to (optional).
"categories": [
"Media",
"Freeware"
],

// Name of the application vendor or author (optional).
"vendor": "Spotify, Inc.",

// Description of the application (optional).
"description": {
"contentType": "text/plain",
"content": "Online Music Service"
},

// Application icons (optional).
// UI currently renders them at 32x32 and 16x16.
// If you don't provide any icons, a default one will be used.
"icons" : [ {
// location of icon
"url": "http://ninite.com/static/app_icons/Chrome32.png",

// icon size
"size": 32
}, {
"url": "http://ninite.com/static/app_icons/Chrome128.png",
"size": 128 }

],
// End user license agreement text (optional).
"eula": {
"contentType": "text/plain",
"content": "..."
},
// File that installs this application. (required).
// See 'Application File'.
"file": { ...
},

// Application should have none or ONLY ONE of the following:
// "recipe"
// "recipes"
// "install"
// Installation recipe (optional).
// If not specified, TAF will install the application by downloading
// and executing the files from the "file" section. See also "install".
"recipe": {
// See 'Application Recipe'.
...
}
// Or
"recipes" : [ {
// See 'Application Recipe'.
...
} ],

// Or
// Installation commands: an alternative to 'recipe'.
// If the recipe contains just one install command (no precapture, etc),
// then you can just include an "install" section instead.
// See 'Application Recipe'.
"install": {
"command": "..."
}
}

Application File

An application needs a file for ThinApp Factory to download. You define the file by using a URL attribute. The URL can be an absolute URL or a relative path/filename. If you specify a relative path, the path is appended to the path where the JSON feed file is located.

For example, a feed defined at http://example.com/feeds/taf.json can include an application with a URL attribute installer.exe. In this case, ThinApp Factory tries to download http://example.com/feeds/installer.exe when converting the application.

The same format is used for recipe files as well.

"file" :{
// Location of bytes to download (required).
// Absolute URL or relative path.
"url": "...",

// Name of the file (optional).
// If missing, TAF will use the HTTP headers to determine the file name.
"name": "...",

// Description of what this file is for (optional)
"description": "...",

// hash of the download (optional)
"hash" : {

// hash function: currently only "sha1" is supported
"function": "sha1",
"value": "00000000000000000000"
}
}

Application Recipe

If an application can be installed with a single command line, you can omit the recipe and use an “install” node in its place. The “install” node contains one child node, called “command”, which contains the installation command to run.

    "install": {
    "command": "..."
    }

For a more complex installation process, the application can include as much as it needs of an entire recipe.

    "recipe": {
    // See 'Defining Recipes in a Feed'
    ...
    }

If there are multiple ways to install an application, you can define an array of recipes.

    "recipes": [ {
    // See 'Defining Recipes in a Feed'
    ...
    } ]

NOTE: An application can have only one of the following nodes. These nodes are optional. You do not have to use any of them.

  • “install”
  • “recipe”
  • “recipes”
  • How to Reference the Application’s Installer

    When you write install commands or any other recipe commands, you can reference the application’s installer by using the built-in variable $appfile. When the installation is performed, ThinApp Factory replaces this variable with the path to the application installer.

    Defining Recipes in a Feed

    You can include recipes in a feed. A recipe is a customization script that refines and controls the building of an application package. Recipes are optional in feeds.

    Recipes can appear in two places in a feed:

    1. An application can include a “recipe” node, which defines a specific recipe that is required to install and, possibly, capture that application into a ThinApp package. When ThinApp Factory encounters such an application in a feed, it creates a new application and a new recipe, and links the application and recipe together.
    2. A feed can contain standalone recipes, which can refer (by name and version) to applications to which the recipes can be applied. When ThinApp Factory encounters such a recipe in a feed, it creates a new recipe, and the user can select the recipe when building applications.

    The format for a recipe is the same, whether it is included in a feed as an application “recipe” node or as part of a list of “recipes”.

    General Recipe Attributes

    The following general attributes apply to the entire recipe.

    {
    // Recipe name (required).
    // All recipes in a feed must have unique names.
    "name": "...",

    // Description of the recipe (optional).
    "description": {
    "contentType": "text/plain",
    "content": "..."
    }

    // See "Recipe Application Keys"
    "appKeys": [
    ...
    ],

    // See "Recipe Variables"
    "variables": [
    ...
    ],

    // See "Recipe Files"
    "files": [
    ...
    ],

    // See "Recipe Steps"
    "steps": [
    ...
    ]
    }

    Recipe Application Keys

    The “appKeys” section defines the applications for which this recipe is suitable. If the “appKeys” section is missing, the recipe is assumed to be applicable to all applications.

    If a feed contains at least one “appKeys” entry, ThinApp Factory uses the entry to determine whether this recipe is recommended for building any particular application. If at least one “appKeys” entry matches the application, the recipe is recommended.

    Each “appKeys” entry can omit any of the four key fields. Omitting a key field means the recipe applies to any value for that field. For example, an “appKeys” key that specifies only the name “Firefox” means that ThinApp Factory might recommend this recipe for any version of Firefox.

    {
    ...

    // Which application(s) this recipe is designed for.
    // For standalone recipes, this is recommended. If omitted, the recipe is
    // assumed to apply to any application. For application-specific
    // recipes, this is not required.
    "appKeys": [ {
    // Application that the recipe can apply to
    "application": {
    // Application name (optional)
    "name": "...",

    // Application version (optional)
    "version": "...",

    // Application locale (optional)
    "locale": "...",

    // Application installer revision (optional)
    "installerRevision": "..."
    }
    } ],

    ...
    }

    Recipe Variables

    If a recipe calls for values that must be supplied by a ThinApp Factory user when an application is converted, the values can be defined in the feed as variables.

    You can reference the variables in any of the recipe step commands. To use a variable in a command, use the syntax $varName. Do not include the $ symbol in a variable name.

    Feeds can include a built-in variable, $appfile. ThinApp Factory replaces this name with the path to the application installer when the install is performed.

    {
    ...

    "variables": [ {
    // Name of the variable (required).
    // Use alphanumeric characters only (underscore OK).
    "name": "...",

    // Is a value for this variable required? (optional)
    // Must be "true" or "false".
    "required": "...",

    // Regular expression for validating a value (optional)
    "pattern": "..."
    } ]

    ...
    }

    Recipe Files

    ThinApp Factory cannot convert certain applications without using files that are needed before, during, or after installation. For example, configuration files, DOS or VB scripts, helper applications such as unzip tools, might be needed for the conversion. You can include these files in the recipe.

    The URL for a recipe file can be an absolute URL or a relative path/filename. If you specify a relative path, the path is appended to the path where the JSON feed file is located.

    For example, a feed defined at http://example.com/feeds/taf.json can include an application with a file that has a URL attribute config.xml. In this case, ThinApp Factory tries to download http://example.com/feeds/config.xml when converting an application that uses that recipe.

    Recipe files and application files use the same format.

    {
    ...

    "files": [
    // This file is supplied by the recipe itself
    {
    // Name of the file (optional)
    "name": "...",

    // Where the file is located. This can be an absolute
    // URL or a relative path/file name. (required)
    "url": "...",

    // Description of what this file is for (optional)
    "description": "...",

    // hash of the download (optional)
    "hash" : {
    // hash function: currently only "sha1" is supported
    "function": "sha1",
    "value": "00000000000000000000"
    }
    }
    ],

    ...
    }

    Recipe Steps

    ThinApp Factory divides the conversion process into fives stages: precapture, preinstall, install, postinstall, and prebuild. For each stage, the recipe can define commands that must be executed.

    {
    ...

    "steps": {
    // Before capture is started.
    // Useful for installing prerequisites that you do
    // not want captured.
    "precapture": {
    // See 'install'
    },

    // Before the main application is installed.
    // Anything done here is captured into the final package.
    "preinstall": {
    // See 'install'
    },

    // Main application installation.
    // This will override install commands from the
    // application (if any).
    // Anything done here is captured into the final package.
    "install": {
    "commands": [ {
    // Short description of the command (optional).
    "label": "...",

    // Command to run (required).
    "command": "..."
    } ]
    },

    // After the main application is installed.
    // Anything done here is captured into the final package.
    "postinstall": {
    // See 'install'
    },

    // After the capture, but before the build.
    // This can be used to modify the project before the
    // package is built.
    "prebuild": {
    // See 'install'
    }
    }
    }

    The commands for each phase are executed in the order in which they appear in the feed. The order of the phases in the recipe does not matter.

    If the recipe defines variables, the variables can be used in any commands in any steps. ThinApp Factory replaces the variable name ($variableName) with the value entered by the user when an application is converted.

    If the recipe defines files, the files can be used in any commands. Commands can be written as if every recipe file is the same working directory from which the commands are executed.

  • NOTE The steps node is optional. You can specify each node, such as install or precapture, as a child node of the parent recipe if desired.
  • How to Reference the Application’s Installer

    When you write recipe commands, you can reference the application’s installer by using the built-in variable $appfile. When the installation is performed, ThinApp Factory replaces this variable with the path to the application installer.

    Custom Recipe Tools

    Using SETOPTION.EXE in a Recipe to Change INI options

    One of the things necessary for some customers is the ability to change the during capture or after post-capture before build of a ThinApp package to accommodate for custom changes. One tool build into ThinApp Factory and deployed to a capture and build (CnB) system is a command line tool called SETOPTION.EXE. This tool allows for modifications of INI files such as the PACKAGE.INI from within the recipe so it does not have to be done manually after the fact.

    Below is the command line setup of SETOPTION.EXE:

    Usage: setoption.exe Section Key Value IniFilename
    example: setoption.exe BuildOptions QualityReportingEnabled 1 .\package.ini

    SETOPTION Usages

    In the above example, the below are the actual commands entered into the ThinApp Factory Recipe in the “Before Build” section.

    SetOption.exe BuildOptions SandboxName "$SANDBOX" "%ProjectDirectory%\\package.ini"
    SetOption.exe BuildOptions InventoryName "$INVENTORY" "%ProjectDirectory%\\package.ini"

    Using Variables in ThinApp Factory Recipes

    It should also be noted in the above commands, ThinApp Factory Recipe Variables are being used – specifically $SANDBOX and $INVENTORY are shown in the commands.

    To properly use Variables, they must be created in the VARIABLES tab as shown below.

    TAF Recipe Variables

    Using REG.EXE in a Recipe to Change registry values

    Additional to SETOPTION.EXE is the need to change registry values on the fly. Fortunately, Windows has a command line tool built into the operating system for this in REG.EXE.

    Below is the command line setup of REG.EXE within a recipe:

    reg.exe add "REGISTRY_HIVE" /v registry_value /t registry_type /d registry_data

    REG EXE in TAF

    In the above example, we are using the below command to modify the Adobe Reader 10 registry value to disable Adobe Reader 10’s protected memory mode.

    reg.exe add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Adobe\Acrobat Reader\10.0\FeatureLockDown" /v bProtectedMode /t REG_DWORD /d 0

  • NOTE: Execute “REG.EXE /?” at a command line for full help on how to use REG.EXE.
  • This entry was posted in FAQs, ThinApp Factory and tagged , , on by .
    Dean Flaming

    About Dean Flaming

    Dean is currently an EUC Architect and member of the VMware End User Computing Enablement and Lighthouse Support teams, working to develop communications and IP around VMware End User Computing products and solutions as well as support many various Lighthouse accounts with their own EUC practices. Prior to this, from 2008 through 2012 Dean was one of VMware's End User Computing Specialists. Throughout his time at VMware, Dean has also written and published various articles, videos, and podcasts regarding VMware's EUC Solutions.