2012-04-25 67 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