﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-道可道，非常道；名可名，非常名</title><link>http://www.cnblogs.com/zoti/</link><description>我把兴趣当作工作,因为我把工作当作兴趣。</description><language>zh-cn</language><lastBuildDate>Wed, 19 Nov 2008 07:44:03 GMT</lastBuildDate><pubDate>Wed, 19 Nov 2008 07:44:03 GMT</pubDate><ttl>60</ttl><item><title>使用MSBuild实现完整daily build流程</title><link>http://www.cnblogs.com/zoti/archive/2007/07/14/817846.html</link><dc:creator>zoti</dc:creator><author>zoti</author><pubDate>Sat, 14 Jul 2007 00:44:00 GMT</pubDate><guid>http://www.cnblogs.com/zoti/archive/2007/07/14/817846.html</guid><wfw:comment>http://www.cnblogs.com/zoti/comments/817846.html</wfw:comment><comments>http://www.cnblogs.com/zoti/archive/2007/07/14/817846.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/zoti/comments/commentRss/817846.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/zoti/services/trackbacks/817846.html</trackback:ping><description><![CDATA[<p>[Author:Jason Wang] <p>一、MSBuild <p>在微软软件开发中，每日构建是最重要的过程之一，被称为微软产品开发的“心跳”。简单来看，每天构建系统将整个产品解决方案完整构建一遍，生成的目标文件和安装文件被放置在一个共享位置。接着，安装文件被自动部署到release server上，随后可以自动运行BVT（build verification test），并将所有结果寄送每个team member的信箱。 <p>微软有一套完善的内部系统来完成整个自动化流程，以及流程管理、reporting等工作，而如果我们没有这套系统，也想实现完整的daily build流程，该怎么做呢？ <p>在VS.NET2003时代，IDE可以控制整个方案的构建，但是所有的构建逻辑被IDE控制，对于开发人员来说，整个构建流程就像一个黑箱，很难修改和管理。当然可以使用PreBuildEvent和PostBuildEvent来控制，但是这些event都写在csproj/vbproj文件中，不便于修改，不适于扩展。而且使用IDE来做每日构建的话，要求构建系统本身装有VS.NET，这会带来额外的成本。另一种办法是使用NAnt，通过XML配置文件，来管理构建流程，这会使得整个流程易于修改，可扩展，并且不要求构建系统安装IDE，只需要有framework即可。问题是使用NAnt必须额外写一堆复杂的XML配置文件，足以让很多developer看了头疼。 <p>VS.NET2005中引入了一套全新的构建系统：MSBuild。简单来讲，MSBuild可以直接读取csproj文件，控制csc/vbc等编译器，生成整个方案。实际上，VS2005的IDE自身就是调用MSBuild来完成编译的，这与VS2003有很大的不同。并且由于VS2005的csproj文件服从MSBuild的配置schema，因此我们可以直接使用csproj，稍稍修改一下，就能组织起完整的构建流程了。 <p>&nbsp;</p> <p>二、示例项目的组织 <p>来看一个完整的例子。 <p>我们将建立一个简单的Hello方案，包括一个HelloService（Windows NT Service），一个HelloSite（ASP.NET Web Site），和一个共用组件（class library）。如图所示。 <p><img src="http://storage.msn.com/x1pbglk-vqL4BtK9_xkTBZsP5dEYlppqYMY2LJzkPNwrlM9Uw2aeiYsaOLuF147lIupf70-9p_KXBI0A24H6NJQX4cBr_V857wgWuO2eJdxuoXFDaUprPtG26WxSOkIHbeJ8AkTM1Rx79mB3VbfmOJR7A"> <p>build目录中，将用来存放构建使用的配置文件。private目录中存放解决方案本身。public目录中存放用来完成构建所使用的编译器，例如WiX（用来生成安装包）。先在private目录中新建一个空解决方案，可以命名为“HelloSolution”。然后依次新建SharedComponents、HelloService和HelloSite项目，并建立引用关系：HelloService引用了SharedComponents。最后的文件组织如图所示。 <p><img src="http://storage.msn.com/x1pbglk-vqL4BtK9_xkTBZsP5dEYlppqYMY2LJzkPNwrlNVwmtZpEfUulQZBJ1YNPluiW4T0fHOKnhZgpERxt3HxhjYXDOcs4vrZ8s66ufL2TlkjY3V7DhZilDBNoS6HL0o9UGtrbZvhSZWgAmMy434fg"> <img src="http://storage.msn.com/x1pbglk-vqL4BtK9_xkTBZsP5dEYlppqYMY2LJzkPNwrlOzS6977u84NoJR8zingaMAtRz9ooM4JCLBAOQzanacGWaAtXCNcrKQIYwAXxCiqV_H36VFosJEvGRaCwLbNPxMM_B20vFPYiSyuTPxPybX1A"> <p>删除Default.aspx第一行的引用，删除Default.aspx.cs，添加一个App_Code目录，在App_Code中新建一个Hello.cs文件，保持初始代码不用修改。 <p>在IDE中编译整个Solution，没问题。可以关闭IDE了。 <p>打开SDK的控制台，输入两条命令： <p>CD /d C:\Hello\private\HelloSolution <p>msbuild <p>很快就能看到构建结果了： <p><img src="http://storage.msn.com/x1pbglk-vqL4BtK9_xkTBZsP5dEYlppqYMY2LJzkPNwrlOvVdlUIO7d2J4Pp-6ib3rh2G-Y9Hgs8TSc108dX2swr61PRr3HNwVNucUrmfJGFuU8J6lwL3hcmtqnp1RqS5qTY_oAxP3JvW6r1m1M2qhrDQ"> <p>但这并不完全是我想要的。例如我想将所有的项目输出都放在C:\Hello\target目录；我想让HelloSite有一个自己的主目录；我想自动生成MSI安装包，并且也放在target目录下。 <p>三、修改构建流程 <p>首先我们将SharedComponent.csproj和HelloService.csproj文件copy至build目录下，并将扩展名改名为proj。用记事本打开SharedComponents.proj，看到如下内容。 <p>&lt;Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; <p>&lt;PropertyGroup&gt; <p>&lt;Configuration Condition=" '$(Configuration)' == '' "&gt;Debug&lt;/Configuration&gt; <p>&lt;Platform Condition=" '$(Platform)' == '' "&gt;AnyCPU&lt;/Platform&gt; <p>&lt;ProductVersion&gt;8.0.50727&lt;/ProductVersion&gt; <p>&lt;SchemaVersion&gt;2.0&lt;/SchemaVersion&gt; <p>&lt;ProjectGuid&gt;{FF79BA82-D6CE-4E89-9AFA-C5EF83A62C2D}&lt;/ProjectGuid&gt; <p>&lt;OutputType&gt;Library&lt;/OutputType&gt; <p>&lt;AppDesignerFolder&gt;Properties&lt;/AppDesignerFolder&gt; <p>&lt;RootNamespace&gt;SharedComponents&lt;/RootNamespace&gt; <p>&lt;AssemblyName&gt;SharedComponents&lt;/AssemblyName&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "&gt; <p>&lt;DebugSymbols&gt;true&lt;/DebugSymbols&gt; <p>&lt;DebugType&gt;full&lt;/DebugType&gt; <p>&lt;Optimize&gt;false&lt;/Optimize&gt; <p>&lt;OutputPath&gt;bin\Debug\&lt;/OutputPath&gt; <p>&lt;DefineConstants&gt;DEBUG;TRACE&lt;/DefineConstants&gt; <p>&lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; <p>&lt;WarningLevel&gt;4&lt;/WarningLevel&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "&gt; <p>&lt;DebugType&gt;pdbonly&lt;/DebugType&gt; <p>&lt;Optimize&gt;true&lt;/Optimize&gt; <p>&lt;OutputPath&gt;bin\Release\&lt;/OutputPath&gt; <p>&lt;DefineConstants&gt;TRACE&lt;/DefineConstants&gt; <p>&lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; <p>&lt;WarningLevel&gt;4&lt;/WarningLevel&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;Reference Include="System" /&gt; <p>&lt;Reference Include="System.Data" /&gt; <p>&lt;Reference Include="System.Xml" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;Compile Include="Class1.cs" /&gt; <p>&lt;Compile Include="Properties\AssemblyInfo.cs" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /&gt; <p>&lt;!-- To modify your build process, add your task inside one of the targets below and uncomment it.  <p>Other similar extension points exist, see Microsoft.Common.targets. <p>&lt;Target Name="BeforeBuild"&gt; <p>&lt;/Target&gt; <p>&lt;Target Name="AfterBuild"&gt; <p>&lt;/Target&gt; <p>--&gt; <p>&lt;/Project&gt; <p>观察可以发现，红色的部分是给VS IDE用的，与MSBuild无关，因此可以删除。最后几行中的BeforeBuild和AfterBuild暂时没用，也可以删除。 <p>从第一行开始看： <p>&lt;Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; <p>&lt;PropertyGroup&gt; <p>&lt;Configuration Condition=" '$(Configuration)' == '' "&gt;Debug&lt;/Configuration&gt; <p>&lt;Platform Condition=" '$(Platform)' == '' "&gt;AnyCPU&lt;/Platform&gt; <p>首先看到一个属性组，里面的每一条属性都可以理解成一个环境变量。属性组第一行是说，如果环境变量“Configuration”为空，那么设置属性 “Configuration”为“Debug”。同样，第二行是说，如果环境变量“Platform”为空，那么设置属性“Platform”为“AnyCPU”。这里我不想使用“AnyCPU”，于是将其改成“x86”。 <p>&lt;OutputType&gt;Library&lt;/OutputType&gt; <p>&lt;AssemblyName&gt;SharedComponents&lt;/AssemblyName&gt; <p>&lt;/PropertyGroup&gt; <p>OutputType指定了输出类型为类库。AssemblyName指定输出文件名，改为Hello.SharedComponents。 <p>&lt;PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "&gt; <p>&lt;DebugSymbols&gt;true&lt;/DebugSymbols&gt; <p>&lt;DebugType&gt;full&lt;/DebugType&gt; <p>&lt;Optimize&gt;false&lt;/Optimize&gt; <p>&lt;OutputPath&gt;bin\Debug\&lt;/OutputPath&gt; <p>&lt;DefineConstants&gt;DEBUG;TRACE&lt;/DefineConstants&gt; <p>&lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; <p>&lt;WarningLevel&gt;4&lt;/WarningLevel&gt; <p>&lt;/PropertyGroup&gt; <p>在这一段中，如果Configuration属性并上“|” 并上Platform属性，等于“Debug|AnyCPU”的话，那么定义一个属性组。换句话说，就是为debug、AnyCPU的组合配置一段编译器使用的属性。将第一行的Condition改成“'$(Configuration)' == 'Debug'”（假设我们并不需要在其它platform上进行编译）。以同样的方式修改Release的PropertyGroup。 <p>接着是一个ItemGroup，指定了这个项目引用的组件。 <p>&lt;ItemGroup&gt; <p>&lt;Reference Include="System" /&gt; <p>&lt;Reference Include="System.Data" /&gt; <p>&lt;Reference Include="System.Xml" /&gt; <p>&lt;/ItemGroup&gt; <p>然后又是一个ItemGroup，指定了参加编译的源代码文件。 <p>&lt;ItemGroup&gt; <p>&lt;Compile Include="Class1.cs" /&gt; <p>&lt;Compile Include="Properties\AssemblyInfo.cs" /&gt; <p>&lt;/ItemGroup&gt; <p>再接下来，引入了一个targets文件： <p>&lt;Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /&gt; <p>$(MSBuildBinPath)是一个环境变量，或者是之前定义的属性。Microsoft.CSharp.targets位于C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727目录下，用记事本打开，查找“Name="CoreCompile"”，可以找到真正控制编译器运行的核心配置。其中$(xxx)表示一个之前定义的属性，@(xxx)表示之前定义的ItemGroup。可以发现，先前在SharedComponents.proj中定义的属性和Item，最后实际上都是给这一段CoreCompile用的。由这个target来控制csc编译器执行最终的编译。 <p>在第一个PropertyGroup中添加一个属性：SrcDir，其值为“C:\Hello\private\HelloSolution\Shared\SharedComponents”，表示此项目源代码文件的位置。相应修改Compile项目组的Include属性为： <p>&lt;ItemGroup&gt; <p>&lt;Compile Include="$(SrcDir)\Class1.cs" /&gt; <p>&lt;Compile Include="$(SrcDir)\Properties\AssemblyInfo.cs" /&gt; <p>&lt;/ItemGroup&gt; <p>回到HelloService.proj文件，依上所述，进行类似的修改。 <p>注意ProjectReference这个ItemGroup，这一段将会被用来解析依赖关系，需要对Include属性做些修改。 <p>最后形成的两个文件为： <p>SharedComponents.proj <p>&lt;Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; <p>&lt;PropertyGroup&gt; <p>&lt;SrcDir&gt;C:\Hello\private\HelloSolution\Shared\SharedComponents&lt;/SrcDir&gt; <p>&lt;Configuration Condition=" '$(Configuration)' == '' "&gt;Debug&lt;/Configuration&gt; <p>&lt;Platform Condition=" '$(Platform)' == '' "&gt;x86&lt;/Platform&gt; <p>&lt;OutputType&gt;Library&lt;/OutputType&gt; <p>&lt;AssemblyName&gt;Hello.SharedComponents&lt;/AssemblyName&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;PropertyGroup Condition=" '$(Configuration)' == 'Debug' "&gt; <p>&lt;DebugSymbols&gt;true&lt;/DebugSymbols&gt; <p>&lt;DebugType&gt;full&lt;/DebugType&gt; <p>&lt;Optimize&gt;false&lt;/Optimize&gt; <p>&lt;OutputPath&gt;bin\Debug\&lt;/OutputPath&gt; <p>&lt;DefineConstants&gt;DEBUG;TRACE&lt;/DefineConstants&gt; <p>&lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; <p>&lt;WarningLevel&gt;4&lt;/WarningLevel&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;PropertyGroup Condition=" '$(Configuration)' == 'Release' "&gt; <p>&lt;DebugType&gt;pdbonly&lt;/DebugType&gt; <p>&lt;Optimize&gt;true&lt;/Optimize&gt; <p>&lt;OutputPath&gt;bin\Release\&lt;/OutputPath&gt; <p>&lt;DefineConstants&gt;TRACE&lt;/DefineConstants&gt; <p>&lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; <p>&lt;WarningLevel&gt;4&lt;/WarningLevel&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;Reference Include="System" /&gt; <p>&lt;Reference Include="System.Data" /&gt; <p>&lt;Reference Include="System.Xml" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;Compile Include="$(SrcDir)\Class1.cs" /&gt; <p>&lt;Compile Include="$(SrcDir)\Properties\AssemblyInfo.cs" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /&gt; <p>&lt;/Project&gt; <p>HelloService.proj <p>&lt;Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; <p>&lt;PropertyGroup&gt; <p>&lt;SrcDir&gt;C:\Hello\private\HelloSolution\Services\HelloService&lt;/SrcDir&gt; <p>&lt;Configuration Condition=" '$(Configuration)' == '' "&gt;Debug&lt;/Configuration&gt; <p>&lt;Platform Condition=" '$(Platform)' == '' "&gt;x86&lt;/Platform&gt; <p>&lt;OutputType&gt;WinExe&lt;/OutputType&gt; <p>&lt;AssemblyName&gt;Hello.HelloService&lt;/AssemblyName&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;PropertyGroup Condition=" '$(Configuration)' == 'Debug' "&gt; <p>&lt;DebugSymbols&gt;true&lt;/DebugSymbols&gt; <p>&lt;DebugType&gt;full&lt;/DebugType&gt; <p>&lt;Optimize&gt;false&lt;/Optimize&gt; <p>&lt;OutputPath&gt;bin\Debug\&lt;/OutputPath&gt; <p>&lt;DefineConstants&gt;DEBUG;TRACE&lt;/DefineConstants&gt; <p>&lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; <p>&lt;WarningLevel&gt;4&lt;/WarningLevel&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;PropertyGroup Condition=" '$(Configuration)' == 'Release' "&gt; <p>&lt;DebugType&gt;pdbonly&lt;/DebugType&gt; <p>&lt;Optimize&gt;true&lt;/Optimize&gt; <p>&lt;OutputPath&gt;bin\Release\&lt;/OutputPath&gt; <p>&lt;DefineConstants&gt;TRACE&lt;/DefineConstants&gt; <p>&lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; <p>&lt;WarningLevel&gt;4&lt;/WarningLevel&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;Reference Include="System" /&gt; <p>&lt;Reference Include="System.Data" /&gt; <p>&lt;Reference Include="System.ServiceProcess" /&gt; <p>&lt;Reference Include="System.Xml" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;Compile Include="$(SrcDir)\Service1.cs" /&gt; <p>&lt;Compile Include="$(SrcDir)\Service1.Designer.cs" /&gt; <p>&lt;Compile Include="$(SrcDir)\Program.cs" /&gt; <p>&lt;Compile Include="$(SrcDir)\Properties\AssemblyInfo.cs" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;ProjectReference Include="SharedComponents.proj" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /&gt; <p>&lt;/Project&gt; <p>最后参考上面的两个文件和MSDN上MSBuild的资料，新建HelloSite.proj文件： <p>&lt;Project DefaultTargets="PrecompileWeb" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; <p>&lt;PropertyGroup&gt; <p>&lt;VirtualPath&gt;/Hello&lt;/VirtualPath&gt; <p>&lt;PhysicalPath&gt;C:\Hello\private\HelloSolution\Web\HelloSite\&lt;/PhysicalPath&gt; <p>&lt;TargetPath&gt;Web&lt;/TargetPath&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;PropertyGroup Condition=" '$(Configuration)' == 'Debug' "&gt; <p>&lt;DebugCompile&gt;true&lt;/DebugCompile&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;PropertyGroup Condition=" '$(Configuration)' == 'Release' "&gt; <p>&lt;DebugCompile&gt;false&lt;/DebugCompile&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;Target Name="PrecompileWeb"&gt; <p>&lt;AspNetCompiler <p>VirtualPath="$(VirtualPath)" <p>PhysicalPath="$(PhysicalPath)" <p>TargetPath="$(TargetPath)" <p>Force="true" <p>Debug="$(DebugCompile)" <p>Updateable="true" /&gt; <p>&lt;/Target&gt; <p>&lt;/Project&gt; <p>转到控制台，在C:\Hello\build目录下执行msbuild HelloService.proj，观察执行结果，发现MSBuild成功解析出HelloService引用了SharedComponent组件，并首先编译了被引用的组件，然后才编译目标组件。如图所示： <p><img src="http://storage.msn.com/x1pbglk-vqL4BtK9_xkTBZsP5dEYlppqYMY2LJzkPNwrlNZK0GwHDPuJwOIUUJU_9-Zfh7uFFJx0d-gRtmvKbCCI-bJIW2CJKs1PHqQviBmUrz200T44LoUyeyYvlwCHtLrDqWsvwks6z5G65CKP9-uaw"> <p>再执行msbuild HelloSite.proj，构建也成功了。 <p>&nbsp;</p> <p>四、进一步完善 <p>在这部分中，我们使用环境变量来替代长路径，把项目输出放到指定位置，将公用的属性配置放在一个引用文件里。由于在MSBuild系统中，系统环境变量和属性是通用的，因此这些目标并不难完成。 <p>在C:\Hello\build目录中新建一个include.cmd文件。 <p>@echo off <p>@set public=%inetroot%\public <p>@set private=%inetroot%\private <p>@set target=%inetroot%\target <p>@set product=%private%\HelloSolution <p>@set setup=%product%\Setup <p>@set wix=%public%\WiX <p>@set Platform=%PROCESSOR_ARCHITECTURE% <p>call "C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sdkvars.bat" <p>在include.cmd中，我们指定了所需的环境变量，并调用了SDK的环境变量设置命令。 <p>新建include.property文件，内容为： <p>&lt;Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; <p>&lt;PropertyGroup&gt; <p>&lt;Configuration Condition=" '$(Configuration)' == '' "&gt;Debug&lt;/Configuration&gt; <p>&lt;Platform Condition=" '$(Platform)' == '' "&gt;x86&lt;/Platform&gt; <p>&lt;BaseIntermediateOutputPath&gt;$(target)\&lt;/BaseIntermediateOutputPath&gt; <p>&lt;OutputPath&gt;$(target)\$(Platform)\$(Configuration)\&lt;/OutputPath&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;PropertyGroup Condition=" '$(Configuration)' == 'Debug' "&gt; <p>&lt;DebugSymbols&gt;true&lt;/DebugSymbols&gt; <p>&lt;DebugType&gt;full&lt;/DebugType&gt; <p>&lt;Optimize&gt;false&lt;/Optimize&gt; <p>&lt;DefineConstants&gt;DEBUG;TRACE&lt;/DefineConstants&gt; <p>&lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; <p>&lt;WarningLevel&gt;4&lt;/WarningLevel&gt; <p>&lt;DebugCompile&gt;true&lt;/DebugCompile&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;PropertyGroup Condition=" '$(Configuration)' == 'Release' "&gt; <p>&lt;DebugType&gt;pdbonly&lt;/DebugType&gt; <p>&lt;Optimize&gt;true&lt;/Optimize&gt; <p>&lt;DefineConstants&gt;TRACE&lt;/DefineConstants&gt; <p>&lt;ErrorReport&gt;prompt&lt;/ErrorReport&gt; <p>&lt;WarningLevel&gt;4&lt;/WarningLevel&gt; <p>&lt;DebugCompile&gt;false&lt;/DebugCompile&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;/Project&gt; <p>修改SharedComponents.proj： <p>&lt;Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; <p>&lt;Import Project="include.property" /&gt; <p>&lt;PropertyGroup&gt; <p>&lt;SrcDir&gt;$(product)\Shared\SharedComponents&lt;/SrcDir&gt; <p>&lt;OutputType&gt;Library&lt;/OutputType&gt; <p>&lt;AssemblyName&gt;Hello.SharedComponents&lt;/AssemblyName&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;Reference Include="System" /&gt; <p>&lt;Reference Include="System.Data" /&gt; <p>&lt;Reference Include="System.Xml" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;Compile Include="$(SrcDir)\Class1.cs" /&gt; <p>&lt;Compile Include="$(SrcDir)\Properties\AssemblyInfo.cs" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /&gt; <p>&lt;/Project&gt; <p>修改HelloService.proj： <p>&lt;Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; <p>&lt;Import Project="include.property" /&gt; <p>&lt;PropertyGroup&gt; <p>&lt;SrcDir&gt;$(product)\Services\HelloService&lt;/SrcDir&gt; <p>&lt;OutputType&gt;WinExe&lt;/OutputType&gt; <p>&lt;AssemblyName&gt;Hello.HelloService&lt;/AssemblyName&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;Reference Include="System" /&gt; <p>&lt;Reference Include="System.Data" /&gt; <p>&lt;Reference Include="System.ServiceProcess" /&gt; <p>&lt;Reference Include="System.Xml" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;Compile Include="$(SrcDir)\Service1.cs" /&gt; <p>&lt;Compile Include="$(SrcDir)\Service1.Designer.cs" /&gt; <p>&lt;Compile Include="$(SrcDir)\Program.cs" /&gt; <p>&lt;Compile Include="$(SrcDir)\Properties\AssemblyInfo.cs" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;ItemGroup&gt; <p>&lt;ProjectReference Include="SharedComponents.proj" /&gt; <p>&lt;/ItemGroup&gt; <p>&lt;Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /&gt; <p>&lt;/Project&gt; <p>修改HelloSite.proj： <p>&lt;Project DefaultTargets="PrecompileWeb" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; <p>&lt;Import Project="include.property" /&gt; <p>&lt;PropertyGroup&gt; <p>&lt;VirtualPath&gt;/Hello&lt;/VirtualPath&gt; <p>&lt;PhysicalPath&gt;C:\Hello\private\HelloSolution\Web\HelloSite\&lt;/PhysicalPath&gt; <p>&lt;TargetPath&gt;$( OutputPath)\Web&lt;/TargetPath&gt; <p>&lt;/PropertyGroup&gt; <p>&lt;Target Name="PrecompileWeb"&gt; <p>&lt;AspNetCompiler <p>VirtualPath="$(VirtualPath)" <p>PhysicalPath="$(PhysicalPath)" <p>TargetPath="$(TargetPath)" <p>Force="true" <p>Debug="$(DebugCompile)" <p>Updateable="true" /&gt; <p>&lt;/Target&gt; <p>&lt;/Project&gt; <p>在C:\Hello目录下新建一个build.proj文件： <p>&lt;Project DefaultTargets="Compile" <p>xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;  <p>&lt;Target Name="Build"&gt; <p>&lt;MSBuild Projects="build\HelloService.proj" /&gt; <p>&lt;MSBuild Projects="build\HelloSite.proj" /&gt; <p>&lt;/Target&gt; <p>&lt;/Project&gt; <p>在C:\Hello目录中新建一个build.cmd文件： <p>@echo off <p>@set Configuration=Debug <p>msbuild build.proj /t:Build <p>@set Configuration=Release <p>msbuild build.proj /t:Build <p>在桌面上新建一个快捷方式，命名为“Hello”，Target设置为： <p>C:\WINDOWS\system32\cmd.exe /K set inetroot=C:\Hello&amp;"C:\Hello\build\Include.cmd" <p>Start in设置为C:\Hello，Option中选上“QuickEdit mode”。 <p>退出命令行，双击桌面上的Hello快捷方式，运行build，大约五秒钟后，整个方案就被成功构建了，所有的项目输出都在C:\Hello\target目录下。 <p><img src="http://storage.msn.com/x1pbglk-vqL4BtK9_xkTBZsP5dEYlppqYMY2LJzkPNwrlN3MpodB4mCxPcQlKTqh20mbRyy67SYVyTHm3Zt5bck9QXK40xTHrInG0xFo0-QyTKyReD60JomzQIXs0ZESt3SecAtqs62cPzP_H2KudHMMQ"> <img src="http://storage.msn.com/x1pbglk-vqL4BtK9_xkTBZsP5dEYlppqYMY2LJzkPNwrlMZXrHud_WcEXagPf9TSc_qFJc_13_tor5CHy1kb0ARsGAu7PIFkEPDPoYVoCT81A6H8xaETsY3jjnC4qlw35QiNG8AqsFNe2auVHm1_e2jUA"> <img src="http://storage.msn.com/x1pbglk-vqL4BtK9_xkTBZsP5dEYlppqYMY2LJzkPNwrlP8I4yJQ4bzJTJASVFR9RlVpqvHHcGw1NpOYZYk8bIkfBuXS-YnBshoXC9HD1GqaAAMZE-mlElA__K2UzaKqnnZWlVOh-EL03en6D1Wn7lqlQ"> <p>五、Installer <p>VS.NET中可以新建一个安装项目，用来编译生成安装包，但是这种生成方式类似用IDE来build项目一样，不适于扩展，而且很难通过命令行来执行编译。 <p>替代的方法是使用WiX toolset。WiX是Windows Installer XML的缩写，是微软的第一个开源项目，可以在SourceForge上下载。 <p>在C:\Hello\private\HelloSolution目录下新建一个Setup目录。新建一个HelloService.wxs文件： <p>&lt;Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi"&gt; <p>&lt;Product Id="YOURGUID" Language="1033" Manufacturer="Hello Corporation" Name="HelloService" Version="1.0.0.0"&gt; <p>&lt;Package Id="YOURGUID" <p>Description='Hello Service Windows Installer package' <p>Manufacturer='Hello Corporation' InstallerVersion='200' Compressed='yes' /&gt; <p>&lt;Condition Message="You need to be an administrator to install this product."&gt; <p>Privileged <p>&lt;/Condition&gt; <p>&lt;Condition Message='This product can only be installed on Windows Server 2003'&gt; <p>VersionNT = 502 <p>&lt;/Condition&gt; <p>&lt;Media Id="1" Cabinet='product.cab' EmbedCab='yes' /&gt; <p>&lt;Directory Id='TARGETDIR' Name='SourceDir'&gt; <p>&lt;Directory Id='ProgramFilesFolder' Name='PFiles'&gt; <p>&lt;Directory Id='Hello' Name='Hello'&gt; <p>&lt;Directory Id='INSTALLDIR' Name='Service'&gt; <p>&lt;Component Id='MainExecutable' Guid=' YOURGUID '&gt; <p>&lt;File Id='HelloSvc' Name='Svc.exe' LongName='Hello.HelloService.exe' DiskId='1' src='$(env.target)\$(env.Platform)\$(env.Configuration)\Hello.HelloService.exe' Vital='yes' ProcessorArchitecture="x86" /&gt; <p>&lt;ServiceInstall Id='ServiceInstall' DisplayName='Hello Service' Name='HelloService' ErrorControl='normal' Start='demand' Type='ownProcess' Vital='yes' Description="Hello service" /&gt; <p>&lt;ServiceControl Id="ServiceUninstall" Name="HelloService" Stop="both" Remove="uninstall" Wait="yes" /&gt; <p>&lt;/Component&gt; <p>&lt;Component Id="ReferencedLib" Guid='YOURGUID'&gt; <p>&lt;File Id='SharedComponents' Name='shared.dll' LongName='Hello.SharedComponents.dll' DiskId='1' src='$(env.target)\$(env.Platform)\$(env.Configuration)\Hello.SharedComponents.dll' Vital='yes' ProcessorArchitecture="x86" /&gt; <p>&lt;/Component&gt; <p>&lt;/Directory&gt; <p>&lt;/Directory&gt; <p>&lt;/Directory&gt; <p>&lt;/Directory&gt; <p>&lt;Feature Id='Complete' Level='1'&gt; <p>&lt;ComponentRef Id='MainExecutable' /&gt; <p>&lt;ComponentRef Id='ReferencedLib' /&gt; <p>&lt;/Feature&gt; <p>&lt;/Product&gt; <p>&lt;/Wix&gt; <p>其中的YOURGUID需要用一个自己生成的guid来代替，可以用C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\guidgen.exe来生成guid。 <p>新建HelloSite.wxs文件： <p>&lt;Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi"&gt; <p>&lt;Product Id="YOURGUID" Language="1033" Manufacturer="Hello Corporation" Name="HelloSite" Version="1.0.0.0"&gt; <p>&lt;Package Id="YOURGUID" <p>Description='Hello Site Windows Installer package' <p>Manufacturer='Hello Corporation' InstallerVersion='200' Compressed='yes' /&gt; <p>&lt;Condition Message="You need to be an administrator to install this product."&gt; <p>Privileged <p>&lt;/Condition&gt; <p>&lt;Condition Message='This product can only be installed on Windows Server 2003'&gt; <p>VersionNT = 502 <p>&lt;/Condition&gt; <p>&lt;Media Id="1" Cabinet='product.cab' EmbedCab='yes' /&gt; <p>&lt;Directory Id='TARGETDIR' Name='SourceDir'&gt; <p>&lt;Directory Id='ProgramFilesFolder' Name='PFiles'&gt; <p>&lt;Directory Id='Hello' Name='Hello'&gt; <p>&lt;Directory Id='INSTALLDIR' Name='Site'&gt; <p>&lt;Component Id='Page' Guid='YOURGUID'&gt; <p>&lt;File Id='Default_aspx' Name='Default.asp' LongName='Default.aspx' DiskId='1' src='$(env.target)\$(env.Platform)\$(env.Configuration)\Web\Default.aspx' Vital='yes' /&gt; <p>&lt;/Component&gt; <p>&lt;Directory Id='binDir' Name='bin'&gt; <p>&lt;Component Id="ReferencedLib" Guid='YOURGUID'&gt; <p>&lt;File Id='AppCode' Name='App_Code.dll' LongName='App_Code.dll' DiskId='1' src='$(env.target)\$(env.Platform)\$(env.Configuration)\Web\bin\App_Code.dll' Vital='yes' ProcessorArchitecture="x86" /&gt; <p>&lt;/Component&gt; <p>&lt;/Directory&gt; <p>&lt;/Directory&gt; <p>&lt;/Directory&gt; <p>&lt;/Directory&gt; <p>&lt;Component Id='SiteInstall' Guid='YOURGUID'&gt; <p>&lt;WebSite Id='DefaultWebSite' Description='Default Web Site' Directory='INSTALLDIR' DirProperties='webSiteProp'&gt; <p>&lt;WebAddress Id='AllUnassigned' Port='80' /&gt; <p>&lt;WebApplication Id='HelloSite' Name='HelloSite' /&gt; <p>&lt;/WebSite&gt; <p>&lt;/Component&gt; <p>&lt;/Directory&gt; <p>&lt;Feature Id='Complete' Level='1'&gt; <p>&lt;ComponentRef Id='Page' /&gt; <p>&lt;ComponentRef Id='ReferencedLib' /&gt; <p>&lt;ComponentRef Id='SiteInstall' /&gt; <p>&lt;/Feature&gt; <p>&lt;WebDirProperties Id='webSiteProp' Script='yes' /&gt; <p>&lt;CustomAction Id='ToggleASPNETVersion' ExeCommand='aspnet_regiis -s W3SVC/1/Root/' /&gt; <p>&lt;/Product&gt; <p>&lt;/Wix&gt; <p><b>注意HelloSite</b><b>将在把Site</b><b>程序安装在WebSite</b><b>下，因此不要在你的关键机器上安装这个示例，并且安装HelloSite</b><b>前要备份你的IIS</b><b>设置。</b> <p>修改build.cmd文件： <p>@echo off <p>@set Configuration=Debug <p>msbuild build.proj /t:Build <p>if not exist "%target%\%Platform%\%Configuration%\Setup" (mkdir "%target%\%Platform%\%Configuration%\Setup") ELSE (del "%target%\%Platform%\%Configuration%\Setup\*.*" /q) <p>%wix%\candle %setup%\HelloService.wxs -out "%target%\%Platform%\%Configuration%\Setup\\" <p>%wix%\light "%target%\%Platform%\%Configuration%\Setup\HelloService.wixobj" /out "%target%\%Platform%\%Configuration%\Setup\HelloService.msi" <p>%wix%\candle %setup%\HelloSite.wxs -out "%target%\%Platform%\%Configuration%\Setup\\" <p>%wix%\light "%target%\%Platform%\%Configuration%\Setup\HelloSite.wixobj" "%wix%\ca\sca.wixlib" /out "%target%\%Platform%\%Configuration%\Setup\HelloSite.msi" <p>@set Configuration=Release <p>msbuild build.proj /t:Build <p>if not exist "%target%\%Platform%\%Configuration%\Setup" (mkdir "%target%\%Platform%\%Configuration%\Setup") ELSE (del "%target%\%Platform%\%Configuration%\Setup\*.*" /q) <p>%wix%\candle %setup%\HelloService.wxs -out "%target%\%Platform%\%Configuration%\Setup\\" <p>%wix%\light "%target%\%Platform%\%Configuration%\Setup\HelloService.wixobj" /out "%target%\%Platform%\%Configuration%\Setup\HelloService.msi" <p>%wix%\candle %setup%\HelloSite.wxs -out "%target%\%Platform%\%Configuration%\Setup\\" <p>%wix%\light "%target%\%Platform%\%Configuration%\Setup\HelloSite.wixobj" "%wix%\ca\sca.wixlib" /out "%target%\%Platform%\%Configuration%\Setup\HelloSite.msi" <p>运行build，构建完成后，发现target目录中，MSI installer也被生成了。接下去运行 <p>msiexec /i %target%\%Platform%\%Configuration%\Setup\HelloService.msi <p>C:\Program Files\Hello\Service目录中出现了安装好的文件。打开services.msc，找到“Hello Service”，试着运行一下。 <p><img src="http://storage.msn.com/x1pbglk-vqL4BtK9_xkTBZsP5dEYlppqYMY2LJzkPNwrlMZPzH7bJ1dRpVTAjc01lV88qOWJylusbxAkpCxSuAoWHrzzmSp200GCimP5GURikM2IJvA5m9AwX79HA0RlsX_74AtNO-SF7Dp-MlRgGe4RA"> <p>运行msiexec /x %target%\%Platform%\%Configuration%\Setup\HelloService.msi卸载。 <p>运行msiexec /i %target%\%Platform%\%Configuration%\Setup\HelloSite.msi安装Web程序。 <p><img src="http://storage.msn.com/x1pbglk-vqL4BtK9_xkTBZsP5dEYlppqYMY2LJzkPNwrlPSRFpfnBhjpfPY-sRt__wOeXRnCifZ2JDGqJkpNtQoyCnL6pNP-jB2oEYtLa77jDRKYypUkY4ue6WZGfFjw3q1ZO85_BUTHSAx2vQLDVR9pA"> <p>运行msiexec /x %target%\%Platform%\%Configuration%\Setup\HelloSite.msi卸载。 <p>&nbsp;</p> <p>六、自动化 <p>最后一个任务就是实现自动化，每日定时构建。 <p>在C:\Hello目录中新建一个DailyBuild.bat文件： <p>@echo off <p>@set inetroot=C:\Hello <p>call C:\Hello\build\Include.cmd <p>call C:\Hello\build.cmd <p>在Services.msc中enable “Task Scheduler”服务。在控制面板的“Scheduled Tasks”中，新建一个任务：Build Hello，指定其每天03:00AM运行C:\DailyBuild.bat。 <p>右键点击这个task，选择运行，可以先看一下结果。 <p>就这样，daily build的任务完全实现自动化了。 <p>&nbsp;</p> <p>七、扩展 <p>在示例方案中，由于MSI安装包都已经自动生成了，接下去能做的就更多了，例如实现自动部署，自动测试（BVT），自动report结果，等等。这些工作需要与tester合作，本文不再展开。 <p>自动化流程是保持项目良好运作的关键，在微软公司，这一流程受到高度的重视，通常由developer manager直接负责。如果哪天出现了build break，那么developer在开始一天的coding之前，必须先找到昨天的build哪里出现了问题，先去修复，重新build，直到build成功为止，没有例外。 <img src ="http://www.cnblogs.com/zoti/aggbug/817846.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43607/" target="_blank">[新闻]后“开放”平台时代</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>如何：使用 Tlbimp.exe 生成主互操作程序集[轉]</title><link>http://www.cnblogs.com/zoti/archive/2007/07/13/816954.html</link><dc:creator>zoti</dc:creator><author>zoti</author><pubDate>Fri, 13 Jul 2007 03:06:00 GMT</pubDate><guid>http://www.cnblogs.com/zoti/archive/2007/07/13/816954.html</guid><wfw:comment>http://www.cnblogs.com/zoti/comments/816954.html</wfw:comment><comments>http://www.cnblogs.com/zoti/archive/2007/07/13/816954.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/zoti/comments/commentRss/816954.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/zoti/services/trackbacks/816954.html</trackback:ping><description><![CDATA[<p>轉自：<a title="http://msdn2.microsoft.com/zh-cn/library/tw4zwhbe(VS.80).aspx" href="http://msdn2.microsoft.com/zh-cn/library/tw4zwhbe(VS.80).aspx">http://msdn2.microsoft.com/zh-cn/library/tw4zwhbe(VS.80).aspx</a> <p>.NET Framework 开发人员指南  <p>如何：使用 Tlbimp.exe 生成主互操作程序集  <p>生成主互操作程序集的最简单方法是使用<a href="http://msdn2.microsoft.com/tt0cf3sx(VS.80).aspx">类型库导入程序 (Tlbimp.exe)</a>。  <h5>使用 Tlbimp.exe 生成主互操作程序集</h5> <ul> <li> <p>在命令提示处，键入：  <p><b>tlbimp</b> <i>tlbfile </i><b>/primary /keyfile:</b> <i>filename</i> <b>/out:</b> <i>assemblyname</i>  <p>在这个命令中，<i>tlbfile</i> 是包含 COM 类型库的文件，<i>filename</i> 是包含密钥对的容器或文件的名称，<i>assemblyname </i>是要使用强名称签名的程序集的名称。</p></li></ul> <p>主互操作程序集只能引用其他主互操作程序集。如果您的程序集引用第三方 COM 类型库中的类型，必须先从发行者获取一个主互操作程序集，才能生成您的主互操作程序集。如果您是发行者，必须先为相关类型库生成一个主互操作程序集，才能生成引用这些类型库的主互操作程序集。  <p>如果相关主互操作程序集的版本号与原类型库的版本号不同，即使安装在当前目录中也无法发现该程序集。必须在 Windows 注册表中注册该相关主互操作程序集或使用 <b>/reference</b> 选项，确保 Tlbimp.exe 能找到该相关 DLL。  <p>您还可以包装类型库的多个版本。有关说明，请参见<a href="http://msdn2.microsoft.com/1565h6hc(VS.80).aspx">如何：包装类型库的多个版本</a>。  <h3>示例</h3> <p><a></a> <p>下面的示例导入 COM 类型库 <tt>LibUtil.tlb</tt> 并使用密钥文件 <tt>CompanyA.snk</tt> 为程序集 <tt>LibUtil.dll</tt> 签署强名称。通过省略特定命名空间名称，此示例生成默认命名空间 <tt>LibUtil</tt>。  <p>tlbimp LibUtil.tlb /primary /keyfile:CompanyA.snk /out:LibUtil.dll <p>为使名称更具有说明性，（使用 <i>VendorName</i>.<i>LibraryName</i> 命名指导原则），下面的示例将重写程序集文件名和命名空间名称。  <p>tlbimp LibUtil.tlb /primary /keyfile:CompanyA.snk /namespace:CompanyA.LibUtil /out:CompanyA.LibUtil.dll <p>下面的示例导入 <tt>MyLib.tlb</tt>（它引用 <tt>CompanyA.LibUtil.dll</tt>）并使用密钥文件 <tt>CompanyB.snk</tt> 为程序集 <tt>CompanyB.MyLib.dll</tt> 签署强名称。命名空间 <tt>CompanyB.MyLib</tt> 会重写默认命名空间名称。  <p>tlbimp MyLib.tlb /primary /keyfile:CompanyB.snk /namespace:CompanyB.MyLib /reference:CompanyA.LibUtil.dll /out:CompanyB.MyLib.dll <h3>请参见</h3> <h6>任务</h6><a href="http://msdn2.microsoft.com/1565h6hc(VS.80).aspx">如何：包装类型库的多个版本</a><br><a href="http://msdn2.microsoft.com/1w557csx(VS.80).aspx">如何：手动创建主互操作程序集</a>  <h6>概念</h6><a href="http://msdn2.microsoft.com/dwe56e27(VS.80).aspx">生成主 Interop 程序集</a><br><a href="http://msdn2.microsoft.com/hfac4fky(VS.80).aspx">产生主 Interop 程序集</a><img src ="http://www.cnblogs.com/zoti/aggbug/816954.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43606/" target="_blank">[新闻]李彦宏首次表态竞价排名问题:有错能改善莫大焉</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>在使用Remoting時，對象比較需要注意的</title><link>http://www.cnblogs.com/zoti/archive/2007/07/11/813559.html</link><dc:creator>zoti</dc:creator><author>zoti</author><pubDate>Wed, 11 Jul 2007 01:50:00 GMT</pubDate><guid>http://www.cnblogs.com/zoti/archive/2007/07/11/813559.html</guid><wfw:comment>http://www.cnblogs.com/zoti/comments/813559.html</wfw:comment><comments>http://www.cnblogs.com/zoti/archive/2007/07/11/813559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/zoti/comments/commentRss/813559.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/zoti/services/trackbacks/813559.html</trackback:ping><description><![CDATA[<p>前幾天做一個小程序時，需要使用Remoting，在服務器端維護一對像的數組，客戶端會通過Remoting使用服務器提供的方法對數組操作，程序原型如下：</p> <p>&nbsp;</p> <p>對象：</p> <p>public class Employe</p> <p>{</p> <blockquote> <p>private int _ID;</p> <p>private&nbsp;string _Name;</p></blockquote> <p>&nbsp;</p> <blockquote> <p>public int ID</p> <p>{</p> <p>get{return this._ID;}</p> <p>set{this._ID=value;}</p> <p>}</p> <p>public string Name</p> <p>{</p> <p>get{return this._Name;}</p> <p>set{this._Name=value;}</p> <p>}</p></blockquote> <p>}</p> <p>服務器端有這一個組數：</p> <p>List&lt;Employe&gt; Employes;</p> <p>&nbsp;</p> <p>提供了如下方法：</p> <p>RemoveEmploye(Employe employe);</p> <p>具體實現為：</p> <p>public RemoveEmploye(Employe employe)</p> <p>{</p> <blockquote> <p>Employes.Remove(employe);</p></blockquote> <p>}</p> <p>程序看起來好像沒問題，可是在執行的時候，怎么也不能移除傳入的employe。</p> <p>後來一想，客戶端的object怎么可能會和服務器的object相等呢？</p> <p>在Employe類加上如下代碼即解決問題：</p> <p>&nbsp;</p> <p>public override int GetHashCode()<br>{<br>&nbsp;&nbsp;&nbsp; return this.ID.GetHashCode ();<br>}<br>public override bool Equals(object obj)<br>{<br>&nbsp;&nbsp;&nbsp; return this.GetHashCode().Equals( (obj as Employe).GetHashCode());<br>}  <p>原來，客戶端的object傳到服務器是要先經過Serializable再DeSerializable的，必須告訴.net如何比較兩個對象是否相等才行。</p><img src ="http://www.cnblogs.com/zoti/aggbug/813559.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43605/" target="_blank">[新闻]杨致远发表博客解释辞职原因</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item></channel></rss>