I want to access the Title value that is stored in the WMAppManifest.xml file from my ViewModel code. This is the same application title that is set through the project prop
This last answer seems overly complicated to me ; you could have simply done something like:
string name = "";
var executingAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var customAttributes = executingAssembly.GetCustomAttributes(typeof(System.Reflection.AssemblyTitleAttribute), false);
if (customAttributes != null)
{
var assemblyName = customAttributes[0] as System.Reflection.AssemblyTitleAttribute;
name = assemblyName.Title;
}
Only the first two answers are correct in scope of the original question. And the second is certainly not over complicated. Wrapping the helper method with a class for each possible attribute is good object orientated development and exactly what Microsoft do all over the framework, e.g. settings designer files generated by Visual Studio.
I'd recommend using the first if you just want one specific property, the second if you want more. Should be part of the SDK really. We're trying to read the WMAppManifest.xml here not the AssemblyInfo so standard assembly reflection metadata is no good.
By the way, if you really want to get the product name from the assembly attributes (not WPAppManifest.xml) then the last sample was reading the wrong attribute! Use the AssemblyProductAttribute not the AssemblyTitleAttribute. The assembly title is really the file title, by default the same as the assembly file name (e.g. MyCompany.MyProduct.WinPhone7App) whereas the product will typically be something like the properly formatted "title" of your app in the store (e.g. "My Product"). It may not even be up-to-date after using the VS properties page, so you should check that.
I use AssemblyInfo reflection for all other application types to show the official product name and build version on an about page, it's certainly correct for that. But for these special phone app types the store manifest has more importance and other attributes you may need.
Look at the source code for WP7DataCollector.GetAppAttribute() in the Microsoft Silverlight Analytics Framework. GetAppAttribute("Title") will do it.
/// <summary>
/// Gets an attribute from the Windows Phone App Manifest App element
/// </summary>
/// <param name="attributeName">the attribute name</param>
/// <returns>the attribute value</returns>
private static string GetAppAttribute(string attributeName)
{
string appManifestName = "WMAppManifest.xml";
string appNodeName = "App";
var settings = new XmlReaderSettings();
settings.XmlResolver = new XmlXapResolver();
using (XmlReader rdr = XmlReader.Create(appManifestName, settings))
{
rdr.ReadToDescendant(appNodeName);
if (!rdr.IsStartElement())
{
throw new System.FormatException(appManifestName + " is missing " + appNodeName);
}
return rdr.GetAttribute(attributeName);
}
}
The problem with all of those answers is that they have to read the file every single time it is accessed. This is bad for performance as there are battery issues to consider if you use it frequently. Koen was closer to a proper solution, but his design still went back to the file every time you wanted to access the value.
The solution below is a one-and-done read of the file. Since it is not likely to change, there is no reason to keep going back to it. The attributes are read as the static class is initialized, with minimal fuss.
I created this Gist to demonstrate.
HTH!
I have used Michael S. Scherotter his excellent code sample to work it out to a fully working code sample:
using System.Xml;
namespace KoenZomers.WinPhone.Samples
{
/// <summary>
/// Allows application information to be retrieved
/// </summary>
public static class ApplicationInfo
{
#region Constants
/// <summary>
/// Filename of the application manifest contained within the XAP file
/// </summary>
private const string AppManifestName = "WMAppManifest.xml";
/// <summary>
/// Name of the XML element containing the application information
/// </summary>
private const string AppNodeName = "App";
#endregion
#region Properties
/// <summary>
/// Gets the application title
/// </summary>
public static string Title
{
get { return GetAppAttribute("Title"); }
}
/// <summary>
/// Gets the application description
/// </summary>
public static string Description
{
get { return GetAppAttribute("Description"); }
}
/// <summary>
/// Gets the application version
/// </summary>
public static string Version
{
get { return GetAppAttribute("Version"); }
}
/// <summary>
/// Gets the application publisher
/// </summary>
public static string Publisher
{
get { return GetAppAttribute("Publisher"); }
}
/// <summary>
/// Gets the application author
/// </summary>
public static string Author
{
get { return GetAppAttribute("Author"); }
}
#endregion
#region Methods
/// <summary>
/// Gets an attribute from the Windows Phone App Manifest App element
/// </summary>
/// <param name="attributeName">the attribute name</param>
/// <returns>the attribute value</returns>
private static string GetAppAttribute(string attributeName)
{
var settings = new XmlReaderSettings {XmlResolver = new XmlXapResolver()};
using (var rdr = XmlReader.Create(AppManifestName, settings))
{
rdr.ReadToDescendant(AppNodeName);
// Return the value of the requested XML attribute if found or NULL if the XML element with the application information was not found in the application manifest
return !rdr.IsStartElement() ? null : rdr.GetAttribute(attributeName);
}
}
#endregion
}
}