返回目录

0. 概述和Portable Class Library

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

在继续之前,必须先提一下微软的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。

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

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

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

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

最后保存。

返回目录

2. 修改AssemblyInfo.cs

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

使用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. 修改当前工程名称

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

返回目录

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

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

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

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

返回目录

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

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

这里需要做两个任务。

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

返回目录

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

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

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

打开记事本后:

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

修改后是:

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

注意别忘了保存!

返回目录

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

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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

返回目录

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

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

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

#if NET20

    //桌面读取配置文件

#elif WP7

    //WP7访问独立存储

#endif

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

实现同一套代码针对不同平台工程的编辑和编译
Visual Studio Express: 实现同一套代码针对不同平台工程的编辑和编译
0. 概述和Portable Class Library
1. 配置工程属性
2. 修改AssemblyInfo.cs
3. 修改当前工程名称
4. 建立另一个平台的工程
5. 将两个平台的工程整合到一块
6. 修改第二个工程的解决方案文件
7. 把第一个工程的源代码加入到第二个工程中
8. 预处理指令消除编译问题

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