2012-04-25 59 views
2

我有一个类,只是返回AssemblyInfo.cs中的值(此代码是Windows Phone的):生成WMAppManifest.xml与T4

using System.Runtime.InteropServices; 
using System.Reflection; 

namespace Tiletoons 
{ 
    class AppInfo 
    { 
     public static readonly string Id = string.Empty; 
     public static readonly string Product = string.Empty; 
     public static readonly string Company = string.Empty; 
     public static readonly string Version = string.Empty; 

     static AppInfo() 
     { 
      Assembly assembly = Assembly.GetExecutingAssembly(); 

      foreach (object attribute in assembly.GetCustomAttributes(false)) { 
       if (attribute.GetType() == typeof(GuidAttribute)) { 
        Id = (attribute as GuidAttribute).Value; 
       } else if (attribute.GetType() == typeof(AssemblyProductAttribute)) { 
        Product = (attribute as AssemblyProductAttribute).Product; 
       } else if (attribute.GetType() == typeof(AssemblyCompanyAttribute)) { 
        Company = (attribute as AssemblyCompanyAttribute).Company; 
       } 
      } 

      Version = assembly.FullName.Split('=')[1].Split(',')[0]; 
     } 
    } 
} 

...我想用它来通过T4转换自动生成我的WMAppManifest.xml;这里是我的ttinclude文件:

<#@ assembly name="System.Core" #> 
<#@ assembly name="EnvDTE" #> 
<#@ import namespace="EnvDTE" #> 
<#@ import namespace="System" #> 
<# 
IServiceProvider hostServiceProvider = Host as IServiceProvider; 
EnvDTE.DTE dte = hostServiceProvider.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE; 
EnvDTE.ProjectItem containingProjectItem = dte.Solution.FindProjectItem(Host.TemplateFile); 
Project project = containingProjectItem.ContainingProject; 
var projectName = project.FullName; 
ProjectItem deploymentConfiguration = GetProjectItem(project, "AppInfo.cs"); 

if (deploymentConfiguration == null) { 
    throw new Exception("Unable to resolve AppInfo.cs"); 
} 

var codeModel = deploymentConfiguration.FileCodeModel; 

string id = null; 
string product = null; 
string company = null; 
string version = null; 

foreach (CodeElement codeElement in codeModel.CodeElements) { 
    if (codeElement.Name == "AppInfo") { 
     CodeClass codeClass = codeElement as CodeClass; 

     foreach (CodeElement memberElement in codeClass.Members) { 
      CodeVariable variable = memberElement as CodeVariable; 

      switch (memberElement.Name) { 
       case "Id": 
        id = variable.InitExpression as string; 
        break; 
       case "Product": 
        product = variable.InitExpression as string; 
        break; 
       case "Company": 
        company = variable.InitExpression as string; 
        break; 
       case "Version": 
        version = variable.InitExpression as string; 
        break; 
      } 
     } 
    } 
} 
#> 
<#+ EnvDTE.ProjectItem GetProjectItem(Project project, string fileName) 
{ 
    foreach (ProjectItem projectItem in project.ProjectItems) { 
     if (projectItem.Name.EndsWith(fileName)) { 
      return projectItem; 
     } 

     var item = GetProjectItem(projectItem, fileName); 

     if (item != null) { 
      return item; 
     } 
    } 

    return null; 
} 

EnvDTE.ProjectItem GetProjectItem(EnvDTE.ProjectItem projectItem, string fileName) 
{ 
    if (projectItem.ProjectItems != null && projectItem.ProjectItems.Count > 0) { 
     foreach (ProjectItem item in projectItem.ProjectItems) { 
      if (item.Name.EndsWith(fileName)) { 
       return item; 
      } 
     } 
    } 

    return null; 
} 
#> 

...终于在这里是我的清单模板:

<#@ template debug="false" hostspecific="true" language="C#" #> 
<#@ output extension=".xml" #> 
<#@ include file="AppInfo.ttinclude" #> 
<?xml version="1.0" encoding="utf-8"?> 
<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.0"> 
    <App xmlns="" ProductID="<#= id #>" Title="<#= product #>" RuntimeType="XNA" Version="<#= version #>" Genre="apps.games" Author="Gonzo" Description="<#= description #>" Publisher="<#= company #>"> 
    <IconPath IsRelative="true" IsResource="false"> 
    ... 
    </App> 
</Deployment> 

是否有可能使用填充类像我(了AppInfo)清单模板?我不想重复已经在AssemblyInfo.cs中定义的常量,即这个想法是查看从那里发布我的WP应用程序所需的所有信息。

任何想法将是真正欢迎:-)

J3D

+0

你想达到什么目的?清单是由Visual Studio为您创建的。你用T4生成它会得到什么? – 2012-04-26 21:41:50

回答

0

好吧,我有两个不同的部署配置我的应用程序(精简版版或专业版),并为每个配置我需要一个特定的Guid ,标题名称,版本,等我能够通过修改WMAppManifest.tt这样解决我的问题:

<#@ template debug="false" hostspecific="true" language="C#" #> 
<#@ output extension=".xml" #> 
<#@ assembly name="$(TargetPath)" #> 
<?xml version="1.0" encoding="utf-8"?> 
<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.0"> 
    <App xmlns="" ProductID="<#= AppInfo.Id #>" Title="<#= AppInfo.Product + " " + AppInfo.Edition #>" RuntimeType="XNA" Version="<#= AppInfo.Version #>" Genre="apps.games" Author="Gonzo" Description="<#= AppInfo.Description #>" Publisher="<#= AppInfo.Company #>"> 
     ... 
    </App> 
</Deployment> 

在这里我上面的集指令指定$(TARGETPATH)的代码片段(这点到我在汇编导演编译的程序集y),最终我能够从AssemblyInfo中查看自定义属性。就这样,我只是定义的GUID和其他需要的数据只有一次 - 这里是一片我的AssemblyInfo的:

... 
#if !LITE_EDITION 
[assembly: Guid("716ab9de-f88e-9a14-8d81-65sn67dbf99e")] 
[assembly: AssemblyEdition("Pro")] 
#else 
[assembly: Guid("91e6742f-6273-1a8b-55a69-e70ad5644827")] 
[assembly: AssemblyEdition("Lite")] 
#endif 
... 

根据当前的配置(例如调试,调试精简版,版本,发布精简版),我产生应用程序将显示正确的信息。我希望有所帮助。

j3d

+0

为什么要制作精简版和专业版?为什么不在试用模式下暴露“精简”功能? – 2012-04-27 08:09:57

+0

你是对的,我将删除版本属性和第二个GUID ......但是从AssemblyInfo中查看自定义属性(guid,product,version等)然后自动生成清单的机制仍然有意义。我不喜欢在这里和那里重复相同的指导。此外,当我发布一个新版本时,我只需修改AssemblyInfo.cs中的版本属性就是这样。你明白这一点吗? – j3d 2012-04-27 12:04:43

+0

由于试用付费应用程序获得了免费应用程序下载量的1/10左右。拥有lite免费应用程序和几乎相同的试用版将推动WAY WAY更多下载。我已经尝试过与多个应用程序。 j3d虽然没有简单的方法来做到这一点。 – 2012-08-18 06:33:17