用C#显示Project2007+TFS2008结合后的实时项目进度

前期说明:在Project2007中可以选择一个团队项目(TFS),然后在Project2007中排好进度,作为工作项发布到TFS服务器上。之后可以直接作为工作项在VS2005等工具中填写项目进度。本文的目的就是要显示出TFS中保存的实时项目进度情况等。
技术说明:在Project2007之前的版本可以通过oledb的方式直接读取project的mpp文件来显示进度,在project2007时不再提供oledb的方式了,可能的两种实现方法有:
1、使用Project2007提供的COM接口,读取mpp文件中的任务 + TFS中的实时进度
2、把所有的进度安排(包括父任务)发布到TFS中,直接读取TFS中的实时进度

一、COM接口的方式
Code
        private void Bind()
        
{
            
//Interop Com方式
            MSProject.ApplicationClass app = null;
            ArrayList taskList 
= new ArrayList();
            
try
            
{
                
//try
                
//{
                
//    app = (MSProject.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("MSProject.Application");
                
//}
                
//catch (Exception ex)
                
//{
                
//    //
                
//}

                
// execute the Microsoft Project Application
                app = new MSProject.ApplicationClass();

                
// Do not display Microsoft Project
                app.Visible = false;

                
// open the project file.
                app.FileOpen(mppFileName, true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, MSProject.PjPoolOpen.pjPoolReadOnly, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

                
// go through all the open projects--there should only be one
                foreach (MSProject.Project proj in app.Projects)
                
{
                    
// go through all the tasks in the project
                    foreach (MSProject.Task task in proj.Tasks)
                    
{
                        ProTask proTask 
= new ProTask();
                        
int iTaskLevel = task.OutlineLevel;
                        
for (int j = 0; j < iTaskLevel; j++)
                        
{
                            proTask.TaskName 
+= "  ";
                        }

                        proTask.TaskName 
+= task.Name;
                        proTask.StartDate 
= Convert.ToDateTime(task.Start);
                        proTask.FinishDate 
= Convert.ToDateTime(task.Finish);

                        
//项目进度从TFS服务器中取得
                        
//proTask.PCT = task.PercentComplete.ToString() + "%";
                        proTask.PCT = GetPCTFromTFS(task.Text10);

                        proTask.Resources 
= task.ResourceNames;
                        taskList.Add(proTask);
                    }

                }


                gvTask.DataSource 
= taskList;
                gvTask.DataBind();
            }

            
catch (Exception ex)
            
{
                
throw ex;
            }

            
finally
            
{
                
if (app != null)
                
{
                    app.Quit(MSProject.PjSaveType.pjDoNotSave);
                }

            }

        }


        
private string GetPCTFromTFS(string id)
        
{
            
if (string.IsNullOrEmpty(id))
            
{
                
return "";
            }

            
string strSql = "Select [Microsoft.VSTS.Scheduling.RemainingWork],[Microsoft.VSTS.Scheduling.CompletedWork],[Microsoft.VSTS.Scheduling.TaskHierarchy] from workitems where id=" + id;
            WorkItemStore Store 
= new WorkItemStore(tfsServer);
            WorkItemCollection wicollection 
= Store.Query(strSql);
            
if (wicollection.Count > 0)
            
{
                
float RemainingWork = Convert.ToSingle(wicollection[0]["Microsoft.VSTS.Scheduling.RemainingWork"]);
                
float CompletedWork = Convert.ToSingle(wicollection[0]["Microsoft.VSTS.Scheduling.CompletedWork"]);
                
if ((int)CompletedWork == 0)
                
{
                    
return "0%";
                }

                
else if ((int)RemainingWork == 0)
                
{
                    
return "100%";
                }

                
else
                
{
                    
float Rate = CompletedWork / (CompletedWork + RemainingWork);
                    Rate 
= Rate * 100;
                    
string strRate = Convert.ToString(Rate);
                    
if (strRate.Length > 2)
                    
{
                        strRate 
= strRate.Substring(02);
                    }

                    
return strRate + "%";
                }

            }


            
return "";
        }
这种方式我就不具体说了,可以看代码中的注释。采用这种方式有几个问题:
速度比较慢;b/s结构时有点问题;
经常报错: 异常详细信息:   System.Runtime.InteropServices.COMException:   消息筛选器显示应用程序正在使用中。试了一些解决方案,好像都不行的。

二、直接读取TFS的方式
主意思路是:在TFS中定制一个新的工作项类型,其中包含一个新的工作项字段(项目分解结构);设置Project和TFS之间同步哪些字段,把新的字段包含进去;在Project中使用这个新的工作项类型;使用TFS SDK读出进度情况。
主要分成以下几个步骤进行:
(以下的command命令都是在VS2005命令提示窗口输入的)、
1、加入新的工作项类型
用以下命令导出原有的工作项类型:
witexport  / " E:\scheduletask.xml "   / http://server:8080/   / p projectname  / " 任务 "
然后编辑这个xml文件,以下文件中红色的部分是修改的地方:
工作项类型
<?xml version="1.0" encoding="utf-8"?>
<witd:WITD application="Work item type editor" version="1.0" xmlns:witd="http://schemas.microsoft.com/VisualStudio/2005/workitemtracking/typedef">
  
<WORKITEMTYPE name="进度">
    
<DESCRIPTION>包括在整个 MSF Agile 生命周期内跟踪进度的信息</DESCRIPTION>
    
<FIELDS>
      
<FIELD name="标题" refname="System.Title" type="String" reportable="dimension">
        
<HELPTEXT>此进度的简短描述,用于在列表或报告中区分它。</HELPTEXT>
        
<REQUIRED />
      
</FIELD>
      
<FIELD name="状况" refname="System.State" type="String" reportable="dimension">
        
<HELPTEXT>此进度的工作流状态</HELPTEXT>
      
</FIELD>
      
<FIELD name="修订" refname="System.Rev" type="Integer" reportable="dimension" />
      
<FIELD name="更改者" refname="System.ChangedBy" type="String" reportable="dimension">
        
<VALIDUSER />
      
</FIELD>
      
<FIELD name="问题" refname="Microsoft.VSTS.Common.Issue" type="String" reportable="dimension">
        
<HELPTEXT>用于突出显示进度,例如,将其标记为问题</HELPTEXT>
        
<REQUIRED />
        
<ALLOWEDVALUES expanditems="true">
          
<LISTITEM value="" />
          
<LISTITEM value="" />
        
</ALLOWEDVALUES>
        
<DEFAULT from="value" value="" />
      
</FIELD>
      
<FIELD name="状态更改日期" refname="Microsoft.VSTS.Common.StateChangeDate" type="DateTime">
        
<WHENCHANGED field="System.State">
          
<SERVERDEFAULT from="clock" />
        
</WHENCHANGED>
        
<WHENNOTCHANGED field="System.State">
          
<READONLY />
        
</WHENNOTCHANGED>
      
</FIELD>
      
<FIELD name="激活日期" refname="Microsoft.VSTS.Common.ActivatedDate" type="DateTime" reportable="dimension">
        
<WHENNOTCHANGED field="System.State">
          
<READONLY />
        
</WHENNOTCHANGED>
      
</FIELD>
      
<FIELD name="激活者" refname="Microsoft.VSTS.Common.ActivatedBy" type="String" reportable="dimension">
        
<WHENNOTCHANGED field="System.State">
          
<READONLY />
        
</WHENNOTCHANGED>
      
</FIELD>
      
<FIELD name="原因" refname="System.Reason" type="String" reportable="dimension">
        
<HELPTEXT>此进度处于当前状态的原因</HELPTEXT>
      
</FIELD>
      
<FIELD name="指派给" refname="System.AssignedTo" type="String" reportable="dimension">
        
<VALIDUSER />
      
</FIELD>
      
<FIELD name="工作项类型" refname="System.WorkItemType" type="String" reportable="dimension" />
      
<FIELD name="关闭者" refname="Microsoft.VSTS.Common.ClosedBy" type="String" reportable="dimension">
        
<WHENNOTCHANGED field="System.State">
          
<READONLY />
        
</WHENNOTCHANGED>
      
</FIELD>
      
<FIELD name="关闭日期" refname="Microsoft.VSTS.Common.ClosedDate" type="DateTime" reportable="dimension">
        
<WHENNOTCHANGED field="System.State">
          
<READONLY />
        
</WHENNOTCHANGED>
      
</FIELD>
      
<FIELD name="级别" refname="Microsoft.VSTS.Common.Rank" type="String" reportable="dimension">
        
<HELPTEXT>用于确定工作优先级别的堆栈级别</HELPTEXT>
      
</FIELD>
      
<FIELD name="项目分解结构" refname="Microsoft.VSTS.Scheduling.WBS" type="String" reportable="dimension">
        <HELPTEXT>项目分解结构</HELPTEXT>
      </FIELD>
      <FIELD name="创建日期" refname="System.CreatedDate" type="DateTime" reportable="dimension" />
      
<FIELD name="创建者" refname="System.CreatedBy" type="String" reportable="dimension" />
      
<FIELD name="集成版本" refname="Microsoft.VSTS.Build.IntegrationBuild" type="String" reportable="dimension">
        
<HELPTEXT>完成此进度的版本</HELPTEXT>
        
<SUGGESTEDVALUES expanditems="true">
          
<LISTITEM value="&lt;无&gt;" />
        
</SUGGESTEDVALUES>
      
</FIELD>
      
<FIELD name="专业领域" refname="Microsoft.VSTS.Common.Discipline" type="String" reportable="dimension">
        
<HELPTEXT>此进度所属的专业领域</HELPTEXT>
        
<ALLOWEDVALUES expanditems="true">
          
<LISTITEM value="开发" />
          
<LISTITEM value="测试" />
          
<LISTITEM value="项目管理" />
          
<LISTITEM value="要求" />
          
<LISTITEM value="体系结构" />
          
<LISTITEM value="发布管理" />
        
</ALLOWEDVALUES>
      
</FIELD>
      
<FIELD name="剩余工作" refname="Microsoft.VSTS.Scheduling.RemainingWork" type="Double" reportable="measure" formula="sum">
        
<HELPTEXT>完成此进度还需要的小时数的估计</HELPTEXT>
      
</FIELD>
      
<FIELD name="已完成工作" refname="Microsoft.VSTS.Scheduling.CompletedWork" type="Double" reportable="measure" formula="sum">
        
<HELPTEXT>执行此进度已花费的小时数</HELPTEXT>
      
</FIELD>
      
<FIELD name="基线工作" refname="Microsoft.VSTS.Scheduling.BaselineWork" type="Double" reportable="measure" formula="sum">
        
<HELPTEXT>基线计划中的工作小时数</HELPTEXT>
      
</FIELD>
      
<FIELD name="完成日期" refname="Microsoft.VSTS.Scheduling.FinishDate" type="DateTime" reportable="dimension">
        
<HELPTEXT>完成进度的日期</HELPTEXT>
      
</FIELD>
      
<FIELD name="任务层次结构" refname="Microsoft.VSTS.Scheduling.TaskHierarchy" type="String" reportable="dimension">
        
<HELPTEXT>表示给定进度的 MS-Project 上下文的字符串</HELPTEXT>
      
</FIELD>
      
<FIELD name="开始日期" refname="Microsoft.VSTS.Scheduling.StartDate" type="DateTime" reportable="dimension">
        
<HELPTEXT>开始进度的日期</HELPTEXT>
      
</FIELD>
      
<FIELD name="退出条件" refname="Microsoft.VSTS.Common.ExitCriteria" type="String" reportable="dimension">
        
<HELPTEXT>用于确定是否应将此方案作为迭代的退出条件进行跟踪的标志</HELPTEXT>
        
<REQUIRED />
        
<ALLOWEDVALUES expanditems="true">
          
<LISTITEM value="" />
          
<LISTITEM value="" />
        
</ALLOWEDVALUES>
        
<DEFAULT from="value" value="" />
      
</FIELD>
      
<FIELD name="说明" refname="System.Description" type="PlainText" />
      
<FIELD name="历史记录" refname="System.History" type="History">
        
<HELPTEXT>讨论线索和其他历史记录信息</HELPTEXT>
      
</FIELD>
      
<FIELD name="相关链接计数" refname="System.RelatedLinkCount" type="Integer" />
      
<FIELD name="迭代路径" refname="System.IterationPath" type="TreePath" reportable="dimension">
        
<HELPTEXT>与此进度关联的产品迭代</HELPTEXT>
      
</FIELD>
      
<FIELD name="迭代 ID" refname="System.IterationId" type="Integer" />
      
<FIELD name="外部链接计数" refname="System.ExternalLinkCount" type="Integer" />
      
<FIELD name="团队项目" refname="System.TeamProject" type="String" reportable="dimension" />
      
<FIELD name="超链接计数" refname="System.HyperLinkCount" type="Integer" />
      
<FIELD name="附加文件计数" refname="System.AttachedFileCount" type="Integer" />
      
<FIELD name="节点名称" refname="System.NodeName" type="String" />
      
<FIELD name="区域路径" refname="System.AreaPath" type="TreePath" reportable="dimension">
        
<HELPTEXT>与此进度关联的产品区域</HELPTEXT>
      
</FIELD>
      
<FIELD name="修订日期" refname="System.RevisedDate" type="DateTime" />
      
<FIELD name="更改日期" refname="System.ChangedDate" type="DateTime" reportable="dimension" />
      
<FIELD name="ID" refname="System.Id" type="Integer" reportable="dimension" />
      
<FIELD name="区域 ID" refname="System.AreaId" type="Integer" />
      
<FIELD name="更改用户 " refname="System.AuthorizedAs" type="String" />
    
</FIELDS>
    
<WORKFLOW>
      
<STATES>
        
<STATE value="活动的">
          
<FIELDS>
            
<FIELD refname="Microsoft.VSTS.Common.ClosedDate">
              
<EMPTY />
            
</FIELD>
            
<FIELD refname="Microsoft.VSTS.Common.ClosedBy">
              
<EMPTY />
            
</FIELD>
          
</FIELDS>
        
</STATE>
        
<STATE value="已关闭" />
      
</STATES>
      
<TRANSITIONS>
        
<TRANSITION from="" to="活动的">
          
<REASONS>
            
<DEFAULTREASON value="新的" />
          
</REASONS>
          
<FIELDS>
            
<FIELD refname="Microsoft.VSTS.Common.ActivatedBy">
              
<COPY from="currentuser" />
              
<VALIDUSER />
              
<REQUIRED />
            
</FIELD>
            
<FIELD refname="Microsoft.VSTS.Common.ActivatedDate">
              
<SERVERDEFAULT from="clock" />
            
</FIELD>
            
<FIELD refname="System.AssignedTo">
              
<DEFAULT from="currentuser" />
            
</FIELD>
          
</FIELDS>
        
</TRANSITION>
        
<TRANSITION from="活动的" to="已关闭">
          
<REASONS>
            
<DEFAULTREASON value="已完成" />
            
<REASON value="已推迟" />
            
<REASON value="已过时" />
            
<REASON value="剪切" />
          
</REASONS>
          
<FIELDS>
            
<FIELD refname="Microsoft.VSTS.Common.ClosedDate">
              
<SERVERDEFAULT from="clock" />
            
</FIELD>
            
<FIELD refname="Microsoft.VSTS.Common.ClosedBy">
              
<COPY from="currentuser" />
              
<VALIDUSER />
              
<REQUIRED />
            
</FIELD>
            
<FIELD refname="Microsoft.VSTS.Common.ActivatedBy">
              
<READONLY />
            
</FIELD>
            
<FIELD refname="Microsoft.VSTS.Common.ActivatedDate">
              
<READONLY />
            
</FIELD>
          
</FIELDS>
          
<ACTIONS>
            
<ACTION value="Microsoft.VSTS.Actions.Checkin" />
          
</ACTIONS>
        
</TRANSITION>
        
<TRANSITION from="已关闭" to="活动的">
          
<REASONS>
            
<DEFAULTREASON value="已重新激活" />
          
</REASONS>
          
<FIELDS>
            
<FIELD refname="Microsoft.VSTS.Common.ActivatedBy">
              
<COPY from="currentuser" />
              
<VALIDUSER />
              
<REQUIRED />
            
</FIELD>
            
<FIELD refname="Microsoft.VSTS.Common.ActivatedDate">
              
<SERVERDEFAULT from="clock" />
            
</FIELD>
            
<FIELD refname="System.AssignedTo">
              
<COPY from="field" field="Microsoft.VSTS.Common.ClosedBy" />
            
</FIELD>
          
</FIELDS>
        
</TRANSITION>
      
</TRANSITIONS>
    
</WORKFLOW>
    
<FORM>
      
<!-- Guidelines for updating the form section
     
1) All labels should have mnemonics (you must use &amp; not just &)
     
2) No mnemonics on Tabs or Group Boxes
     
3) Labels must use sentence casing (i.e. "Assigned to:" is correct; "Assigned To:" is wrong)
     
4) No colons in Group Boxes
     
5) Label names should match the field name in whole or in part. They should not be completely different.
     
6) Do not use the same mnemonics on two labels
     
     The following mnemonics are common to MSF Agile work items:
     T 
-> Title
     A 
-> Area
     I 
-> Iteration
     G 
-> Assigned to
     S 
-> State
     R 
-> Reason
     H 
-> Comment and history
     U 
-> Issue
     B 
-> Integration build
     C 
-> Description
     E 
-> Start Date
     F 
-> Finish Date
     
     The following mnemonics are also used on 
this work item type
     D 
-> Discipline
     K 
-> Rank
     X 
-> Exit criteria
     W 
-> Remaining work
     P 
-> Completed work
     O 
-> Task Context
   
-->
      
<Layout>
        
<Group>
          
<Column PercentWidth="70">
            
<Control Type="FieldControl" FieldName="System.Title" Label="标题(&amp;T):" LabelPosition="Left" />
          
</Column>
          
<Column PercentWidth="30">
            
<Control Type="FieldControl" FieldName="Microsoft.VSTS.Common.Discipline" Label="准则(&amp;D):" LabelPosition="Left" />
          
</Column>
        
</Group>
        
<Group Label="分类">
          
<Column PercentWidth="100">
            
<Control Type="WorkItemClassificationControl" FieldName="System.AreaPath" Label="区域(&amp;A):" LabelPosition="Left" />
            
<Control Type="WorkItemClassificationControl" FieldName="System.IterationPath" Label="迭代(&amp;I):" LabelPosition="Left" />
          
</Column>
        
</Group>
        
<Group Label="状态">
          
<Column PercentWidth="50">
            
<Control Type="FieldControl" FieldName="System.AssignedTo" Label="指派给(&amp;G):" LabelPosition="Left" />
            
<Control Type="FieldControl" FieldName="Microsoft.VSTS.Common.Rank" Label="级别(&amp;K):" LabelPosition="Left" NumberFormat="WholeNumbers" MaxLength="10" />
          
</Column>
          
<Column PercentWidth="50">
            
<Control Type="FieldControl" FieldName="System.State" Label="状态(&amp;S):" LabelPosition="Left" />
            
<Control Type="FieldControl" FieldName="System.Reason" Label="原因(&amp;R):" LabelPosition="Left" />
          
</Column>
        
</Group>
        
<TabGroup>
          
<Tab Label="说明">
            
<Control Type="HtmlFieldControl" FieldName="System.Description" Label="说明(&amp;C):" LabelPosition="Top" Dock="Fill" />
          
</Tab>
          
<Tab Label="历史记录">
            
<Control Type="WorkItemLogControl" FieldName="System.History" Label="历史记录(&amp;H):" LabelPosition="Top" Dock="Fill" />
          
</Tab>
          
<Tab Label="链接">
            
<Control Type="LinksControl" />
          
</Tab>
          
<Tab Label="文件附件">
            
<Control Type="AttachmentsControl" />
          
</Tab>
          
<Tab Label="详细信息">
            
<Group>
              
<Column PercentWidth="50">
                
<Group Label="常规">
                  
<Column PercentWidth="100">
                    
<Control Type="FieldControl" FieldName="Microsoft.VSTS.Common.Issue" Label="问题(&amp;U):" LabelPosition="Left" />
                    
<Control Type="FieldControl" FieldName="Microsoft.VSTS.Common.ExitCriteria" Label="退出条件(&amp;X):" LabelPosition="Left" />
                    
<Control Type="FieldControl" FieldName="Microsoft.VSTS.Build.IntegrationBuild" Label="集成版本(&amp;B):" LabelPosition="Left" />
                    
<Control Type="FieldControl" FieldName="Microsoft.VSTS.Scheduling.TaskHierarchy" Label="进度上下文(&amp;O):" LabelPosition="Left" ReadOnly="True" />
                  
</Column>
                
</Group>
              
</Column>
              
<Column PercentWidth="50">
                
<Group Label="安排">
                  
<Column PercentWidth="100">
                    
<Control Type="FieldControl" FieldName="Microsoft.VSTS.Scheduling.RemainingWork" Label="剩余工作(小时)(&amp;W):" LabelPosition="Left" NumberFormat="DecimalNumbers" MaxLength="10" />
                    
<Control Type="FieldControl" FieldName="Microsoft.VSTS.Scheduling.CompletedWork" Label="已完成工作(小时)(&amp;P):" LabelPosition="Left" NumberFormat="DecimalNumbers" MaxLength="10" />
                    
<Control Type="FieldControl" FieldName="Microsoft.VSTS.Scheduling.StartDate" Label="开始日期(&amp;E):" LabelPosition="Left" ReadOnly="True" />
                    
<Control Type="FieldControl" FieldName="Microsoft.VSTS.Scheduling.FinishDate" Label="完成日期(&amp;F):" LabelPosition="Left" ReadOnly="True" />
                  
</Column>
                
</Group>
              
</Column>
            
</Group>
          
</Tab>
        
</TabGroup>
      
</Layout>
    
</FORM>
  
</WORKITEMTYPE>
</witd:WITD>
然后用以下命令把它加入到tfs中去:
witimport  / " E:\\scheduletask.xml "   / " http://server:8080/ "   / p projectname
这样我们就增加了一个新的工作项类型:进度,和一个新的工作项字段: Microsoft.VSTS.Scheduling.WBS

2、确定TFS和project之间可以同步哪些字段
首先下载原有配置:
TFSFieldMapping.exe download http: // server:8080 projectname  "E:\MappingFile.xml"
在原有配置上修改,见红色部分:
TFS配置
<?xml version="1.0" encoding="utf-8"?>
<MSProject>
    
<Mappings>
        
<Mapping WorkItemTrackingFieldReferenceName="System.Id" ProjectField="pjTaskText10" ProjectName="工作项 ID"/>
        
<Mapping WorkItemTrackingFieldReferenceName="System.Title" ProjectField="pjTaskName"/>
        
<Mapping WorkItemTrackingFieldReferenceName="System.WorkItemType" ProjectField="pjTaskText24"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Common.Discipline" ProjectField="pjTaskText17"/>
        
<Mapping WorkItemTrackingFieldReferenceName="System.AssignedTo" ProjectField="pjTaskResourceNames"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Scheduling.CompletedWork" ProjectField="pjTaskActualWork" ProjectUnits="pjHour"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Scheduling.RemainingWork" ProjectField="pjTaskRemainingWork" ProjectUnits="pjHour"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Scheduling.BaselineWork" ProjectField="pjTaskBaselineWork" ProjectUnits="pjHour"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Scheduling.StartDate" ProjectField="pjTaskStart" PublishOnly="true"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Scheduling.FinishDate" ProjectField="pjTaskFinish" PublishOnly="true"/>
        
<Mapping WorkItemTrackingFieldReferenceName="System.State" ProjectField="pjTaskText13" ProjectName="状况"/>
        
<Mapping WorkItemTrackingFieldReferenceName="System.Reason" ProjectField="pjTaskText14"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Common.Rank" ProjectField="pjTaskText16"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Common.Issue" ProjectField="pjTaskText15"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Common.ExitCriteria" ProjectField="pjTaskText20"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Common.QualityOfServiceType" ProjectField="pjTaskText21"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Common.RoughOrderOfMagnitude" ProjectField="pjTaskText22"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Common.Priority" ProjectField="pjTaskText19" ProjectName="工作项优先级别"/>
        
<Mapping WorkItemTrackingFieldReferenceName="System.AreaPath" ProjectField="pjTaskOutlineCode9"/>
        
<Mapping WorkItemTrackingFieldReferenceName="System.IterationPath" ProjectField="pjTaskOutlineCode10"/>
        
<Mapping WorkItemTrackingFieldReferenceName="System.Rev" ProjectField="pjTaskText23"/>
        
<Mapping WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Scheduling.WBS" ProjectField="pjTaskWBS" PublishOnly="true"/>
        <ContextField WorkItemTrackingFieldReferenceName="Microsoft.VSTS.Scheduling.TaskHierarchy"/>
        
<LinksField ProjectField="pjTaskText26"/>
        
<SyncField ProjectField="pjTaskText25"/>
    
</Mappings>
</MSProject>
再把配置文件上传:
TFSFieldMapping.exe upload http: // server:8080 projectname  "E:\MappingFile.xml"
这样就把TFS字段和project中的指定字段对应起来了

三、在project中使用"进度"工作项类型
这一步比较简单,就是在project中选择团队项目,排计划时选择"进度"类型,然后发布到tfs中就可以了

四、使用tfs SDK读取进度
就是使用TFS SDK就可以了:
         private   void  BindTfs()
        
{
            ArrayList taskList 
= new ArrayList();

            StringBuilder sbSql 
= new StringBuilder();
            sbSql.Append(
"Select [Microsoft.VSTS.Scheduling.RemainingWork],[Microsoft.VSTS.Scheduling.CompletedWork]");
            sbSql.Append(
",[System.Title]");
            sbSql.Append(
",[System.AssignedTo]");
            sbSql.Append(
",[Microsoft.VSTS.Scheduling.StartDate]");
            sbSql.Append(
",[Microsoft.VSTS.Scheduling.FinishDate]");
            sbSql.Append(
",[Microsoft.VSTS.Scheduling.WBS]");
            sbSql.Append(
" from workitems where [System.WorkItemType]='进度' ");
            sbSql.Append(
" order by [Microsoft.VSTS.Scheduling.WBS]");
            WorkItemStore Store 
= new WorkItemStore(tfsServer);
            WorkItemCollection wicollection 
= Store.Query(sbSql.ToString());
            
foreach (WorkItem item in wicollection)
            
{
                ProTask proTask 
= new ProTask();

                
//当前进度
                string strRate = "";
                
float RemainingWork = Convert.ToSingle(item["Microsoft.VSTS.Scheduling.RemainingWork"]);
                
float CompletedWork = Convert.ToSingle(item["Microsoft.VSTS.Scheduling.CompletedWork"]);
                
if ((int)CompletedWork == 0)
                
{
                    strRate 
= "0%";
                }

                
else if ((int)RemainingWork == 0)
                
{
                    strRate 
= "100%";
                }

                
else
                
{
                    
float Rate = CompletedWork / (CompletedWork + RemainingWork);
                    Rate 
= Rate * 100;
                    strRate 
= Convert.ToString(Rate);
                    
if (strRate.Length > 2)
                    
{
                        strRate 
= strRate.Substring(02);
                    }

                    strRate 
= strRate + "%";
                }

                proTask.PCT 
= strRate;

                proTask.TaskName 
= item.Title;
                proTask.StartDate 
= Convert.ToDateTime(item["Microsoft.VSTS.Scheduling.StartDate"]);
                proTask.FinishDate 
= Convert.ToDateTime(item["Microsoft.VSTS.Scheduling.FinishDate"]);
                proTask.Resources 
= item["System.AssignedTo"].ToString();
                proTask.WBS 
= item["Microsoft.VSTS.Scheduling.WBS"].ToString();
                taskList.Add(proTask);
            }



            gvTask.DataSource 
= taskList;
            gvTask.DataBind();
        }

附:
在浏览所有进度时出现问题:拒绝访问(The work item does not exist, or you do not have permission to access it. )
原因:tfs装的是90天测试版,在过期时把日期改为之前两个月了,导致进度这个工作项的加入时间和系统时间有冲突,将系统时间改为工作项加入之后的时间,重启iis就可以了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值