Modifying an OS Design Programatically

Posted by: Brent Bishop

As an extention of my previous post Automating the Creation of an OS Design Project I like to show how to modify the OS design that was created in that sample.

The first thing that you need to do is get an OSDesignProject interface. We get the OSDesignProject interface from the DTE2 interface that was passed into the run method in the example in my previous post. The code to do that looks like this:

    // Varibales
Project vsproject = null;
OSDesignProject osproject = null;

// Get a list of OS design projects
Projects projects = (Projects)dte.GetObject("PBProjects");

// Make sure at least one project was found
if (projects != null && projects.Count > 0)
{
// Get the first project
vsproject = projects.Item(1);
osproject = (OSDesignProject)vsproject.Object;
}

Note: The Project interface is defined in the EnvDTE namespace so I added the following using statement at the top of OSDesignSample.cs.

    using EnvDTE;

Now that we have the interface to the project we can start modifying it or getting information about it. You'll notice that the code above gets a Project interface from Visual Studio and a OSDesignProject interface from Platform Builder. The Project interface is useful for getting or modifying anything about the project that is managed by Visual Studio. For example we can get information like the name of the project and the projects path.

    // Get information about the project
dte.ToolWindows.OutputWindow.ActivePane.OutputString(vsproject.Name + "\n");
dte.ToolWindows.OutputWindow.ActivePane.OutputString(vsproject.FileName + "\n");

On the other hand we use the OSDesignProject interface to modify or get information about the project related to Platform Builder. There are two different areas of settings to work with. First there are settings related to the project as a whole. Selected catalog items and favorites are examples of these type of settings. The methods and properties for these types of settings are found at the root of the OSDesignProject interface. The other settings are those specific to a configuration. These are the settings you find in the project properties dialog (Locales, Environment Variables, Custom Build Actions). To modify or view these settings we must first find the configuration (in the Configurations collection) or just modify the active configuration.

Here are some samples of the common types of things we can do with the project.  Note: This is just a sample of the many properties and methods available.  If there is a specific property you are trying to access and can't figure out please post a comment and ask for help.

    // Add or remove a catalog item
osproject.AddCatalogItemToOSDesign("SYSGEN_SOLITARE");
//osproject.RemoveCatalogItemFromOSDesign("SYSGEN_SOLITARE");

// See which catalog items are selected
foreach (CatalogItemReference item in osproject.SelectedCatalogItems)
{
dte.ToolWindows.OutputWindow.ActivePane.OutputString(item.Id + "\n");
}

// Get the path of the run-time image
OSDesignConfiguration config = osproject.ActiveConfiguration;
string image = Path.Combine(config.ReleaseDirectory, config.TargetBinFilename);
dte.ToolWindows.OutputWindow.ActivePane.OutputString(image + "\n");

// Notice that the path contains an environment variable so we can replace
// the environment variable with it's value to get the full path
image = osproject.ReplaceEnvironmentVariablesInString(image, config);
dte.ToolWindows.OutputWindow.ActivePane.OutputString(image + "\n");

// Add or remove a locale
// In this case add Japanese (LCID: 0x0411 or 1041)
osproject.ActiveConfiguration.LocaleInformation.Locales.Add(0x0411);
//osproject.ActiveConfiguration.LocaleInformation.Locales.Remove(0x0411);

// Add or remove an environment variable
osproject.ActiveConfiguration.EnvironmentVariables.Add("MyVariable", "MyValue");
//osproject.ActiveConfiguration.EnvironmentVariables.Remove("MyVariable");

// Add a custom build action
osproject.ActiveConfiguration.CustomBuildActions.GetCustomBuildActions(BuildStep.PostSysgen).Add("echo This is my custom build action!");

The last thing I like to show is how to change the active configuration.  The active configuration is the one that Visual Studio will build when we call the dte.Solution.SolutionBuild.Build method.

    // Set the active configuration
foreach (SolutionConfiguration configuration in dte.Solution.SolutionBuild.SolutionConfigurations)
{
// TODO: Replace <NAME> with the name of the configuration to set as the active configuration
if (configuration.Name == "<NAME>")
{
configuration.Activate();
break;
}
}

You can find more information on the DTE2 interface or the Project interface in the MSDN library.