返回目录

0. 概述和Portable Class Library

首先这里说的内容不是Visual Studio中工程属性的Target framework编译:

image

工程属性的Target framework仅仅是针对同一个平台的不同Runtime版本。

这里讲的是同一套代码,可以针对不同平台,也就是不同Visual Studio Express程序的工程文件。

image

在继续之前,必须先提一下微软的Portable Class Library。这也是所有用户应该优先考虑的方式。

用户编译一次针对Portable Class Library的函数库后,整个工程就可以顺利运行在.NET,Silverlight,Window Phone,WinRT(.NET for Windows Store apps)甚至是XBox上。(细节请参考:MSDN

当然Portable Class Library也不是万能的,我总结有如下几点缺陷:

1. 工程模板限制在Visual Studio的非Express版中。

2. 部分平台有版本限制。比如.NET桌面平台的最低版本必须是4.0。

3. 只支持部分通用的.NET类库子集(大多数是BCL相关的)。

而目前我正在写的Mgen Rfi工程 2.0,最低可支持.NET 2.0,同时我一直只使用Visual Studio Express,所以不适合使用Portable Class Library。决定使用另一种方法,这种方法其实在许多其他类库中都看到过,比如Json.NET,MVVM Light等。

返回目录

1. 配置工程属性

OK,现在,比如我写好了.NET桌面平台的类库,他的源代码就够目前是这样的,最上面文件夹是类库的名称(本例中的Mgen.Rfi),下面两个文件夹是Demo。

image

然后使用Visual Studio Express for Windows Desktop打开整个工程解决方案,我们需要在当前平台的工程中做一些修改。

在工程属性的Build选项卡中设置如下两项:

1. 在General - Conditional compilation symbols中加入当前平台标识,比如NET20(代表.NET 2.0)。

2. 在Output – Output path中设置当前平台标识的目录。比如bin_NET20。

image

接着切换Configuration Manager的配置项,确保所有配置项(如Debug和Release)都设置了上面两步。

image

最后保存。

返回目录

2. 修改AssemblyInfo.cs

接着,打开工程的AsssemblyInfo.cs文件:

image

使用C#中的#if等预处理指令通过判断不同平台并加入不同的信息,比如这样:

#if NET20

[assemblyAssemblyTitle("Mgen Rfi Project for .NET 2.0")]

#elif WP7

[assembly: AssemblyTitle("Mgen Rfi Project for Windows Phone 7")]

#endif

返回目录

3. 修改当前工程名称

接着把当前工程以及解决方案的名称都加入当前平台的标识,如下:

image

修改后工程源代码目录变成了这样:

image

返回目录

4. 建立另一个平台的工程

接下来,在另一个平台的Visual Studio Express中创建相应的工程。比如打开Visual Studio Express for Windows Phone,创建工程,选择Class Library:

image

创建完成后,删除Visual Studio Class Library模版默认创建的没用的Class1.cs文件,此时解决方案是空的:

image

这里也可以加入一个类库的Demo,当然这个步骤是可选的。加完Demo后,解决方案是这样子:

image

接下来重复上面“1. 配置工程属性”的步骤,按照要求,设置当前平台的工程属性。如下结果:

image

(注意Configuration Manager中的Debug和Release配置项都要设置)

此时还需要设置工程的AssemblyInfo.cs吗?

当然不需要了,这里只需要设置工程的属性,工程内的文件会直接使用第一个工程的文件(本例中.NET 2.0平台的文件)!

返回目录

5. 将两个平台的工程整合到一块

接下来就需要把两个平台的工程文件整合到一块了。首先打开第二个工程的源代码根目录(本例中刚才创建的WP7工程的文件夹):

image

这里需要做两个任务。

1. 除了类库工程的文件夹(本例中的Mgen.Rfi.WP7文件夹),把其他文件夹和文件复制到第一个工程(本例中的.NET 2.0平台工程)解决方案目录下。

image

(这个suo文件其实是本地Visual Studio解决方案用户选项文件,也可以不复制)

操作完成后,第一个工程(本例中的.NET 2.0平台工程)根目录是这样的:

image

(被选中的项目是刚才加入的项目)

2. 把类库工程的文件夹(本例中的Mgen.Rfi.WP7文件夹)中的工程文件选中后复制到第一个工程(本例中的.NET 2.0平台工程)的类库文件夹(本例中的Mgen.Rfi文件夹)下:

image

(这个user文件也是工程的用户配置文件,可以不复制)

操作完成后,第一个工程(本例中的.NET 2.0平台工程)的类库文件夹(本例中的Mgen.Rfi文件夹)是这样的:

image

(被选中的项目是刚才加入的项目)

返回目录

6. 修改第二个工程的解决方案文件

工程文件夹结构处理好后,在整合后的解决方案根目录下选中第二个工程的解决方案(也就是本例中的WP7工程):

image

使用记事本打开这个文件,我们需要修改他。

为什么?因为创建解决方案时,类库工程目录的名称就是解决方案的名称(本例中的Mgen.Rfi.WP7文件夹),这个名称是有平台标识的,而把第二个工程整合到第一个工程中后,这个类库的名称是没有平台标识的(本例中的Mgen.Rfi文件夹),因为此时这个类库文件夹代表着跨平台的代码。但是这样的话,原来第二个工程的解决方案会无法定位到类库的工程,所以需要修改第二个工程的解决方案文件。否则解决方案不会成功打开类库的工程。

打开记事本后:

image

找到子工程的相对路径引用(本例中是“Mgen.Rfi.WP7Mgen.Rfi.WP7.ccsprog”),把它引用的带有平台标识旧目录(本例中的Mgen.Rfi.WP7)改成新的没有平台标识的类库名称(本例中的Mgen.Rfi)。

修改后是:

image

注意别忘了保存!

返回目录

7. 把第一个工程的源代码加入到第二个工程中

修改好第二个工程的解决方案文件后,打开第二个工程的解决方案(本例中会使用Visual Studio Express for Windows Phone),此时类库文件会被成功打开,但是不会有任何文件:

image

接下来,选中类库工程(本例中的Mgen.Rfi.WP7工程),在Solution Explorer上选择Show All Files:

image

然后源代码文件会全部出现,接着选中需要的文件,右键,选择Include In Project:

image

第一个平台工程的源代码文件就会加入到第二个平台工程中了。

返回目录

8. 预处理指令消除编译问题

上面步骤全部完成后,就可以对第二个平台的工程进行编译了,如果有任何编译错误,请使用预处理指令解决,方法类似”2. 修改AssemblyInfo.cs“提到的方式。

比如,在桌面环境下配置数据可能存储在文件中,而在Windows Phone 7环境下配置数据可能存储在独立存储中,所以需要使用预处理指令区分平台来实现不同平台的不同代码编译:

#if NET20

    //桌面读取配置文件

#elif WP7

    //WP7访问独立存储

#endif

OK,最终我们实现了,同一份代码,在不同Visual Studio Express支持的平台上进行编辑和编译!

image

作者:Mgen 
出处:www.cnblogs.com/mgen 
其他参考页面:我的软件和工程博客导读