2007年9月22日 星期六

平淡無味地落幕 - TechEd 2007 心得與紀實

  今年 TechEd 2007 給我只有一個感覺 - [ 太陽底下無鮮事 ] 的悶.

  老實說, 開發議題想打的重量級王牌 - SilverLight, 震撼力道不如去年宣傳 WPF ( 更何況之前他只是 WPF 的子集 - 之前稱為 WPF Everywhere ), 而他所能達到的效果也只是跟隨目前當紅的 RIA ( Rich Internet Application ) 潮流, 想和已經行之有年的 Adobe Flash 分庭抗禮而已.

  雖然 SilverLight 解決了一些 Flash 為人詬病的問題 - 例如搜尋引擎無法抓取 Flash 網頁的文字資料, 採用 XAML 作為技術核心的 SilverLight 可以避免這個問題; 但畢竟沒辦法突破 Flash 的里程碑太多.

  再加上原本被視為重量級的 SilverLight 主題場次因首日天公疼愛, 派來暐帕前來包場作客, 讓其他學員無緣一見, 重重地削弱此次 TechEd - 一個微軟本該使出看家本領技壓群雄的技術盛會 - 的力道.

  對於新技術不再 exciting 的我, 結論就是一整個.

  圖一是會場剪影, 沒啥特別的... 可惜是我沒看到 Open session 的 KeyNote, 被帳單先生搶去這個場次, 不然 KeyNote 應該會有些靈魂級的展示和表演, 不至於讓我只感到無限的悶.



  跟上一屆不同, 這次 TechEd 帶入了一些美少女活動, 包含 TechEd Girl 選拔賽, 大概想讓大部分宅男出身的軟體工程師一飽眼福當作福利.


  好吧, TechEd 既然肚子裡沒有墨水, 那就來點美人計, 用美色來替活動增添些色彩吧? 一整個模仿車展裝扮的 show girl, 台風水準都不怎麼樣, 實在冏到令我失望. 另外還有 IT 狂人賽, 這不是模仿超級武林大會的 KUSO 比賽嗎? 但是看到幾個出槌的設備問題, 我轉身掉頭就走. 無趣, 又是一整個悶...


  圖三的 AMD 的 Show Girl 不用比賽, 但素質卻比起 TechEd Girls 好多了. 微軟的初選眼光該修正一下, 不然就是這一屆沒什麼人來參賽吧?

 圖四是上課實況與學員休息區, 休息區還提供 XBOX 360 不限制玩到爽, 造成一整個翹課風潮...XD, 讓許多課只有小貓幾隻.

  圖五是去新光三越吃午餐 - 奶油海鮮義大利麵. 這次不同於過去以往只接訂購外面的便當在國際會議中心集中用餐, 而是發給學員餐券, 讓學員到周邊商業設施自由用餐.



  這次參加, 我最感到收穫和最重視的主題, 就是軟體開發的專案議題. 所以幾乎所有 Visual Studio Team System Fundation Server 的相關場次, 談到如何做專案管理和協同作業開發的議題我都去聽. 也替 Microsoft 在工具上加強軟體專案管理的功能感到十分激賞和鼓掌.

  軟體的專案管理有著很特殊的特性, 這就是為何既使擁有 PMP 管理師證照的專業經理人, 也很難把軟體專案管好. 因為軟體專案的易於變動, 多了非常重要的版本控管等機制存在, 這些特性都只存在於軟體專案中, 而這些問題也是最難只靠人工去克服.

  版本控管方面, 雖然已經有不少現成的方案可供選擇, 如 CVS, Subversion, VSS, SourceDepot..., 免費或是要錢的都有. 但是各自獨立不能跟開發工作或是專案流程管理系統整合, 常導致版本控管淪為雜亂的備分中心而已.

  工程師 check-in 程式碼, 不寫說明或是不寫這次變更是根據哪項需求而動, 甚至不等該需求或是 Debug 完成, 就先將今天的進度 check-in, 把版本控管的倉儲當做資料備份而已, 不但造成無法推行 Daily build 機制 ( 因為修改到一半的 code 可能根本無法通過 complier 測試 ), 或是一個功能的修改和完成橫跨數個不同 check-in 的版本號, 造成日後出錯尋找問題發生點困難.

  然而這些問題, 隨著 Team System Fundation Server 所提供的 Check-in policy 與 work item 整合, 得到了不錯的解決效果. 且在協同作業部分, Sheving 機制也提供將進行修改中的工作, 以類似虛擬 Check-in 的機制讓其他人接手原本未完成的工作. 這些都是針對軟體專案的痛點所設計的解決方案, 令人激賞拍案叫絕!



  此外在軟體測試方面, 整合過去 NUnit 功能的單元測試也強化了, 最令人印象深刻的是測試涵蓋率的支援, 以及自動化測試資料的產生, 以及可以數量化的報表和建立專案專屬的 Web Portal, 都是十分切題的貼心設計.

  然而, 這麼棒的東西, 卻綁定了只有微軟的 Visual Studio 和 .NET 平台才可使用, 不免有所憾恨...

  期望, 有一個共通性的軟體專案開發平台可以像是微軟 Team Fundation Server 一樣, 整合到這樣完善的地步! ( 最好還是免費的 Open Source...:D, 把 CVS, Subversion 都整進去吧? )

  此次 TechEd 中, 微軟在軟體專案管理上的貢獻, 是最令我拜倒佩服的. 比起其他新技術, 這才是國內軟體業急需取經引進的重要參考!

2007年9月18日 星期二

[ 轉載 ] 在VS2005 环境下面使用.NET Framework 1.1 进行编译


由于 MSBuild 未能直接提供编译 .NET framework 1.1 的功能, 不能直接在VS2005下使用.NET framework 1.1 编译
幸运的是 MSBuild 有强大的扩展性,可以使我们去找到一种办法去解决这个问题。
让我们来看看应该怎么做:

首先把下面这个XML 保存为C:\program files\msbuild\CrossCompile.CSharp.targets, 一定要是这个路径

<!--
Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm
Written by Jomo Fisher
-->

<Project
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <!--
These two property groups inform VS that there is a Platform called .NET 1.1.
-->

 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|.NET 1.1' ">
  <DebugSymbols Condition="'$(DebugSymbols)'==''">true</DebugSymbols>
  <DebugType Condition="'$(DebugType)'==''">full</DebugType>
  <Optimize Condition="'$(Optimize)'==''">false</Optimize>
  <OutputPath Condition="'$(OutputPath)'==''">bin\.NET 1.1\Debug\</OutputPath>
  <DefineConstants Condition="'$(DefineConstants)'==''">DEBUG;TRACE</DefineConstants>
  <DefineConstants>$(DefineConstants);TARGETTING_FX_1_1</DefineConstants>
  <ErrorReport></ErrorReport>
  <WarningLevel Condition="'$(WarningLevel)'==''">4</WarningLevel>
  <UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
  <CscToolPath>$(SystemRoot)\Microsoft.NET\Framework\v1.1.4322</CscToolPath>
  <TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
 </PropertyGroup>
 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|.NET 1.1' ">
  <DebugType Condition="'$(DebugType)'==''">pdbonly</DebugType>
  <Optimize Condition="'$(Optimize)'==''">true</Optimize>
  <OutputPath Condition="'$(OutputPath)'==''">bin\.NET 1.1\Release\</OutputPath>
  <DefineConstants Condition="'$(DefineConstants)'==''">TRACE</DefineConstants>
  <DefineConstants>$(DefineConstants);TARGETTING_FX_1_1</DefineConstants>
  <ErrorReport></ErrorReport>
  <WarningLevel Condition="'$(WarningLevel)'==''">4</WarningLevel>
  <UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
  <CscToolPath>$(SystemRoot)\Microsoft.NET\Framework\v1.1.4322</CscToolPath>
  <TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
 </PropertyGroup>
 <!--
Import the standard C# targets
-->

 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
 <!--
Now that the standard targets have been brought in. Override some properties
and items it created.
-->

 <PropertyGroup>
  <AvailablePlatforms>$(AvailablePlatforms),.NET 1.1</AvailablePlatforms>
  <AssemblySearchPaths Condition=" '$(Platform)' == '.NET 1.1' ">
   {CandidateAssemblyFiles};
   $(ReferencePath);
   {HintPathFromItem};
   {TargetFrameworkDirectory};
   {AssemblyFolders};
   $(OutputPath);
   {GAC}
  </AssemblySearchPaths>
  <TargetFrameworkDirectory Condition=" '$(Platform)' == '.NET 1.1'">
   $(SystemRoot)\Microsoft.NET\Framework\v1.1.4322
  </TargetFrameworkDirectory>
 </PropertyGroup>
 <ItemGroup Condition=" '$(Platform)' == '.NET 1.1'">
  <TargetFrameworkDirectoryItem Include="$(SystemRoot)\Microsoft.NET\Framework\v1.1.4322">
   <InProject>false</InProject>
  </TargetFrameworkDirectoryItem>
 </ItemGroup>
 <!--
Override this target from Microsoft.Common.Targets so that we can supply our own
value for $(TargetFrameworkDirectory). This controls where assembly resolution
logic finds FX assemblies.
-->

 <Target
     Name="GetFrameworkPaths"
     DependsOnTargets="$(GetFrameworkPathsDependsOn)">
  <!-- Get the path to the target .NET framework directory. -->
  <GetFrameworkPath
   Condition=" '$(Platform)' != '.NET 1.1' ">
   <Output TaskParameter="Path" PropertyName="TargetFrameworkDirectory"/>
   <Output TaskParameter="Path" ItemName="TargetFrameworkDirectoryItem"/>
  </GetFrameworkPath>
  <!-- Get the path to the target .NET framework SDK directory. -->
  <GetFrameworkSDKPath
   Condition=" '$(Platform)' != '.NET 1.1' ">
   <Output TaskParameter="Path" PropertyName="TargetFrameworkSDKDirectory"/>
   <Output TaskParameter="Path" ItemName="TargetFrameworkSDKDirectoryItem"/>
  </GetFrameworkSDKPath>
 </Target>
 <!--
For 1.1 builds, intercept the call to CorResGen target (which generates 2.0 resources) and
slip in a call to our own CoreResGen_1_1.

Handily, the devices version of the ResGen task is able to call the 1.1 version of
ResGen directly.
-->

 <UsingTask TaskName="CFResGen" AssemblyFile="$(MSBuildBinPath)\Microsoft.CompactFramework.Build.Tasks.dll" />
 <PropertyGroup Condition="'$(Platform)' == '.NET 1.1'">
  <ResGenDependsOn>ResolveAssemblyReferences;BeforeResGen;CoreResGen_1_1;AfterResGen</ResGenDependsOn>
 </PropertyGroup>
 <Target
     Name="CoreResGen_1_1"
     DependsOnTargets="$(CoreResGenDependsOn)">
  <CFResGen
       Condition = " '@(ResxWithNoCulture)' != ''"
       Sources = "@(ResxWithNoCulture)"
       UseSourcePath = "$(UseSourcePath)"
       StateFile = "$(IntermediateOutputPath)$(MSBuildProjectFile).CrossCompileResGen.Cache"
       OutputResources = "@(ManifestResourceWithNoCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
    >
   <!-- Appending to 'FilesWritten' list lets us be part of Clean and Incremental Clean. -->
   <Output TaskParameter = "FilesWritten" ItemName="FileWrites"/>
   <Output TaskParameter = "OutputResources" ItemName="ManifestResourceWithNoCulture"/>
  </CFResGen>
  <CFResGen
       Condition = " '@(ResxWithCulture)' != ''"
       Sources = "@(ResxWithCulture)"
       UseSourcePath = "$(UseSourcePath)"
       StateFile = "$(IntermediateOutputPath)$(MSBuildProjectFile).CrossCompileResGen.Cache"
       OutputResources = "@(ManifestResourceWithCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
    >
   <!-- Appending to 'FilesWritten' list lets us be part of Clean and Incremental Clean. -->
   <Output TaskParameter = "FilesWritten" ItemName="FileWrites"/>
   <Output TaskParameter = "OutputResources" ItemName="ManifestResourceWithCulture"/>
  </CFResGen>
 </Target>
</Project>

然后新建一个 2005 的 c# 项目, 或者转换一个 2003 的项目到 2005 的项目格式. 取名为: myApp
手工编辑myApp.csproj
用<Import Project="$(MSBuildExtensionsPath)\CrossCompile.CSharp.targets" />
替换 整个<Import >节点
保存
重新加载项目
在配置管理器(Configuration Manager)里面
平台(platform)下拉菜单里面 选择.NET 1.1 ()

OK. 如果代码没有问题就可以编译了

Enjoy

related link: http://blogs.msdn.com/jomo_fisher/archive/2005/04/22/410903.aspx
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=509134

Microsoft TechEd 2007 開跑



  微軟一年一度的盛會, TechEd 2007 今天正式展開.


  原訂 9/18 開始的 KeyNote 意外的遇上中颱暐帕而延期到 9/19 早上, 三天的 Agenda 夭折成兩天, 首日的課程瞬間蒸發. 真不知道那些拿一萬多元買入場券的可憐蟲心裡怎麼想. 照例, 今年我又是拿免費票入場, 跟帳單先生共用一張.


  去年我參加 TechEd 2006 是個有趣美好的回憶, 當時 JACK 還在..., 今年的 TechEd, 有種孤寂的感覺, 原本也就沒特別想去, 所以沒有主動跟帳單先生索票過...

  Anyway, 今年的 TechEd, 研究過課程總表 ( 分 12 大主題 ), 發現我對開發議題提不起什麼興趣, 沒啥吸引我的主題. 反倒是 Mobile 和軟體專案開發週期的管理等, 較吸引我. 於是我規劃的課程大致如下 ( 衝堂的當作是擠不進教室的候選課程吧 ):






  1. 將 ADO.NET Entity Framework 整合到應用程式中

  2. 微軟虛擬化技術解決方案與願景 ( 衝堂放棄 )

  3. 落實高效率流程導向開發團隊 - 導入 Visual Studio Team System 的最佳實務

  4. ASP.NET AJAX 與 Silverlight 的完美結合 ( 衝堂放棄 )

  5. 加速行動商務應用程式開發的秘技

  6. JavaScript 程式碼在瀏覽器中的效能 ( 衝堂放棄 )

  7. 深入剖析資料庫應用程式開發流程

  8. Visual Studio Team Foundation Server 開發團隊管理平台

  9. 實作單元測試與測試導向開發方法