Introduction
Sometimes it's good to know basic information concerning a ClickOnce deployment such as publish version, where the application was installed from, name of the manifest and so on.
This tip helps to resolve this information. It's usable only for applications that have ApplicationIdentity
set (such as ClickOnce deployed applications).
The code
First, the full code:
public static class PublishInfo {
public enum IdentityType {
Deployment = 1,
Application = 2
}
private static System.Text.RegularExpressions.Regex _versionRegex =
new System.Text.RegularExpressions.Regex(@"Version=(?<Major>\d*)." +
@"(?<Minor>\d*).(?<Build>\d*).(?<Revision>\d*)",
System.Text.RegularExpressions.RegexOptions.Compiled);
private static System.Text.RegularExpressions.Regex _cultureRegex =
new System.Text.RegularExpressions.Regex(@", Culture=(?<Culture>[^,]*),",
System.Text.RegularExpressions.RegexOptions.Compiled);
private static System.Text.RegularExpressions.Regex _publicKeyTokenRegex =
new System.Text.RegularExpressions.Regex(@", PublicKeyToken=(?<PublicKeyToken>[^,]*),",
System.Text.RegularExpressions.RegexOptions.Compiled);
private static System.Text.RegularExpressions.Regex _processorArchitectureRegex =
new System.Text.RegularExpressions.Regex(@", processorArchitecture=(?<ProcessorArchitecture>[^,]*)",
System.Text.RegularExpressions.RegexOptions.Compiled);
public static System.Uri Uri { get; private set; }
public static Identity DeploymentIdentity { get; private set; }
public static Identity ApplicationIdentity { get; private set; }
public class Identity {
public PublishInfo.IdentityType IdentityType { get; private set; }
public System.Version Version { get; private set; }
public string ApplicationName { get; private set; }
public string PublicKeyToken { get; private set; }
public System.Reflection.ProcessorArchitecture ProcessorArchitecture { get; private set; }
private Identity() { }
internal Identity(string identity, PublishInfo.IdentityType identityType) {
System.Text.RegularExpressions.Match regexMatch;
System.Reflection.ProcessorArchitecture architecture;
this.IdentityType = identityType;
try {
this.ApplicationName = identity.Substring(0, identity.IndexOf(','));
regexMatch = _versionRegex.Match(identity);
this.Version = new System.Version(int.Parse(regexMatch.Groups["Major"].ToString()),
int.Parse(regexMatch.Groups["Minor"].ToString()),
int.Parse(regexMatch.Groups["Build"].ToString()),
int.Parse(regexMatch.Groups["Revision"].ToString()));
regexMatch = _publicKeyTokenRegex.Match(identity);
this.PublicKeyToken = regexMatch.Groups["PublicKeyToken"].ToString();
regexMatch = _processorArchitectureRegex.Match(identity);
if (!System.Enum.TryParse<System.Reflection.ProcessorArchitecture>(
regexMatch.Groups["ProcessorArchitecture"].ToString(), true, out architecture)) {
architecture = System.Reflection.ProcessorArchitecture.None;
}
this.ProcessorArchitecture = architecture;
} catch { }
}
}
static PublishInfo() {
string identities;
string[] identity;
try {
identities = System.AppDomain.CurrentDomain.ApplicationIdentity.FullName;
PublishInfo.Uri = new System.Uri(identities.Substring(0, identities.IndexOf('#')));
identities = identities.Substring(identities.IndexOf('#') + 1);
if (identities.IndexOf("\\") > -1) {
identity = identities.Split('\\');
} else {
identity = identities.Split('/');
}
PublishInfo.DeploymentIdentity = new Identity(identity[0], IdentityType.Deployment);
PublishInfo.ApplicationIdentity = new Identity(identity[1], IdentityType.Application);
} catch { }
}
}
Main parts explained
The ApplicationIdentity
of CurrentDomain
returns a string representation for the application. This string contains three informative parts:
- Application URL
#
as a separator - Deployment identity
- \ as a separator (1)
- Application identity
The PublishInfo
constructor first separates the application URL and stores it statically in this class. After this the remainder of the string is splitted using the separator.
1 Even though the MSDN documentation states that \
is used as a separator, when I tested this /
was the actual separator used. For this reason both variations are implemented in the code.
The Identity
class holds the information for individual identity, application or deployment. In the constructor of this class the key information is parsed from the identity string and placed on proper properties such as Version
.
The properties of the Identity class are:
IdentityType
: Which type of identity is this: Application or Deployment ApplicationName
: either the application name or the deployment manifest name depending on the identity typeVersion
: Version for the identity described using System.Version class PublicKeyToken
: Public key token of the identityProcessorArchitecture
: Processor architecture of the identity, described using System.Reflection.ProcessorArchitecture enumeration
Using the class
As an example of the usage of the class I wrote the property values of both identities to output window of Visual Studio using Debug class:
System.Diagnostics.Debug.WriteLine("Uri: " + PublishInfo.Uri.ToString());
System.Diagnostics.Debug.WriteLine("");
System.Diagnostics.Debug.WriteLine("DeploymentIdentity");
System.Diagnostics.Debug.WriteLine("------------------");
System.Diagnostics.Debug.WriteLine("ApplicationName: " + PublishInfo.DeploymentIdentity.ApplicationName);
System.Diagnostics.Debug.WriteLine("Version: " + PublishInfo.DeploymentIdentity.Version.ToString());
System.Diagnostics.Debug.WriteLine("PublicKeyToken: " + PublishInfo.DeploymentIdentity.PublicKeyToken);
System.Diagnostics.Debug.WriteLine("ProcessorArchitecture: " +
PublishInfo.DeploymentIdentity.ProcessorArchitecture.ToString());
System.Diagnostics.Debug.WriteLine("");
System.Diagnostics.Debug.WriteLine("ApplicationIdentity");
System.Diagnostics.Debug.WriteLine("-------------------");
System.Diagnostics.Debug.WriteLine("ApplicationName: " + PublishInfo.ApplicationIdentity.ApplicationName);
System.Diagnostics.Debug.WriteLine("Version: " + PublishInfo.ApplicationIdentity.Version.ToString());
System.Diagnostics.Debug.WriteLine("PublicKeyToken: " + PublishInfo.ApplicationIdentity.PublicKeyToken);
System.Diagnostics.Debug.WriteLine("ProcessorArchitecture: " +
PublishInfo.ApplicationIdentity.ProcessorArchitecture.ToString());
The results were like
Uri: file:///C:/Temp/publish/Tester.application
DeploymentIdentity
------------------
ApplicationName: Tester.application
Version: 1.0.0.9
PublicKeyToken: 79481f74d589e5cd
ProcessorArchitecture: X86
ApplicationIdentity
-------------------
ApplicationName: Tester.exe
Version: 1.0.0.9
PublicKeyToken: 79481f74d589e5cd
ProcessorArchitecture: X86
Note that if you're running the program from Visual Studio, you'll get different results, such as
Uri: http://tempuri.org/Tester.application
DeploymentIdentity
------------------
ApplicationName: Tester.application
Version: 1.0.0.9
PublicKeyToken: 0000000000000000
ProcessorArchitecture: X86
ApplicationIdentity
-------------------
ApplicationName: DomainIdentity.exe
Version: 1.0.0.9
PublicKeyToken: 0000000000000000
ProcessorArchitecture: X86
Also note that if the application hasn't been deployed yet, ApplicationIdentity
is null so both identities in the static helper class are null.
History
- March 27, 2012: Tip created.