首先,简单说说取资源的方法
我建了两个资源文件,分别是 ResourceFileName.resx(默认使用英文), ResourceFileName.zh-ch.resx(中文),之所以不写 ResourceFileName.en-us.resx是因为当没有找到当前所需要的语言时,可以默认使用 ResourceFileName.resx文件。
在取资源的时候,我选择使用了 HttpContext.GetGlobalResourceObject方法并把它包装在一个Helper类的静态方法里面,方便其它地方的调用,详细代码如下:
1
/**/
/// <summary>
2
/// 全局资源文件名
3
/// </summary>
4
internal
const
string
ResourceFileName
=
"
ResourceFileName
"
;
5
6
/**/
/// <summary>
7
/// 返回全局资源
8
/// </summary>
9
/// <param name="key">资源关键字</param>
10
/// <returns></returns>
11
public
static
object
GetGlobalResource(
string
key)
12
{
13
return GetGlobalResource(ResourceFileName, key);
14
}
15
/**/
/// <summary>
16
/// 返回全局资源
17
/// </summary>
18
/// <param name="resourceFileName">资源文件名</param>
19
/// <param name="key">资源关键字</param>
20
/// <returns></returns>
21
public
static
object
GetGlobalResource(
string
resourceFileName,
string
key)
22
{
23
try
24
{
25
return HttpContext.GetGlobalResourceObject(resourceFileName, key, Thread.CurrentThread.CurrentCulture);
26
}
27
catch (Exception ex)
28
{
29
Log(ex.Message, EventLogEntryType.Warning);
30
return string.Empty;
31
}
32
}


2

3

4

5

6


7

8

9

10

11

12



13

14

15


16

17

18

19

20

21

22



23

24



25

26

27

28



29

30

31

32

调用时:
HelperClassName.GetGlobalResource(
"
KeyName
"
).ToString();
第二,说说关于部署的问题
在开发时,代码编译后把RESX文件与DLL拷到相应目录后就可以正常工作了,但由于我开发的是通用控件,不能使用手工部署,必须打包成WSP并在多个应用程序下都可以使用。恰恰是由于我写的resx文件是放在应用程序的App_GlobalResources文件夹下的,而打包成解决方案(wsp)的manifest并不支持把文件放到该文件夹下,当时我是打算改变取资源的方法,仅使用DLL文件形式的资源文件,因为dll文件我可以通过wsp部署到应用程序的bin或者GAC中,但最后考虑到使用起来的确不方便,还是放弃了这一想法,并集中火力,想方设法把文件拷到App_GlobalResources下。
查阅了很多资料后,发现App_GlobalResources这个文件夹是在当应用程序建立时创建的(废话,嘻嘻),而App_GlobalResources文件夹里面的文件是从 “C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG\Resources”中拷贝过来的,而且仅当应用程序建立时才把文件全部拷贝过来,应用程序建立后,无论源文件夹怎样改变,应用程序的App_GlobalResources文件夹也不会得到同步。
那么,wsp不能拷贝文件到App_GlobalResources下,源文件夹也不会自动与应用程序的App_GlobalResources同步,就是说MOSS本身是不支持App_GlobalResources下文件的部署的,而我们偏偏就需要部署文件到它下面。
经过上面的分析,我们可以做的事就只剩下一样的,利用eventhandler使用代码拷贝文件。要利用代码拷贝文件要考虑几件事情,首先是当wsp部署时要把文件拷贝过去,当wsp卸载时,要把文件删除;其次是当有多台前端服务器时要一起拷贝,一起删除。
我在这里利用了MOSS的 SPJobDefinition类(从一个老外那查到的资料),把多台服务器一起执行的工作交给MOSS自己去处理 ,我们只要写做拷贝与删除的代码并写在SPJobDefinition中,在恰当的时候启动一个SPJob:
因为我是写一个通用控件,可以通过Feature来控件是启用该控件,当在启用该控件时,我便可以启动那个拷贝文件的SPJob类来拷贝需要的文件。
下面是详细的代码
1.从SPJobDefinition下继承下来的“拷贝文件工作类”:
1
public
class
DeployGlobalResources : SPJobDefinition
2
{
3
Fields#region Fields
4
[Persisted]
5
private string sourcePath;
6
#endregion
7
8
Constructors#region Constructors
9
/**//// <summary>
10
/// Default constructor used by the system.
11
/// </summary>
12
public DeployGlobalResources() : base()
{ }
13
14
15
/**//// <summary>
16
/// Contructor used to create an instance, which deploys the resource files.
17
/// </summary>
18
/// <param name="WebApp">The SPWebApplication which needs to be updated</param>
19
public DeployGlobalResources(string jobName, SPWebApplication webApp, string featureName)
20
: base(jobName, webApp, null, SPJobLockType.Job)
21
{
22
// Detrmine the path to the feature's resource files
23
sourcePath = string.Format("{0}\\FEATURES\\{1}\\",
24
SPUtility.GetGenericSetupPath("Template"),
25
featureName);
26
}
27
28
#endregion
29
30
Job Handling#region Job Handling
31
/**//// <summary>
32
/// Called by OWSTIMER when the job runs on a server. Overriden from SPJobDefinition.
33
/// </summary>
34
public override void Execute(Guid targetInstanceId)
35
{
36
try
37
{
38
SPWebApplication webApp = this.Parent as SPWebApplication;
39
40
foreach (SPUrlZone zone in webApp.IisSettings.Keys)
41
{
42
// The settings of the IIS application to update
43
SPIisSettings oSettings = webApp.IisSettings[zone];
44
45
// Determine the destination path
46
string destPath = Path.Combine(oSettings.Path.ToString(), "App_GlobalResources");
47
string[] filePaths = Directory.GetFiles(sourcePath, "*.resx");
48
49
// Copy the files
50
foreach (string filePath in filePaths)
51
{
52
string fileName = Path.GetFileName(filePath);
53
File.Copy(filePath, Path.Combine(destPath, fileName), true);
54
}
55
}
56
}
57
catch (Exception ex)
58
{
59
Debug.WriteLine("Failed to copy global resources");
60
Debug.WriteLine(ex);
61
throw;
62
}
63
}
64
#endregion
65
}
2. Feature的事件处理类

2



3


4

5

6

7

8


9


10

11

12



13

14

15


16

17

18

19

20

21



22

23

24

25

26

27

28

29

30


31


32

33

34

35



36

37



38

39

40

41



42

43

44

45

46

47

48

49

50

51



52

53

54

55

56

57

58



59

60

61

62

63

64

65

1
public
class
GlobalResourcesEventReceiver : SPFeatureReceiver
2
{
3
Constants#region Constants
4
5
const string JOB_TITLE = "Deploy Global Resources";
6
const string JOB_NAME = "job-deploy-global-resources";
7
8
#endregion
9
10
Events#region Events
11
12
public override void FeatureActivated(SPFeatureReceiverProperties properties)
13
{
14
SPSite site = properties.Feature.Parent as SPSite;
15
16
// Check for an exising instance of the job
17
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
18
{
19
if (job.Name == JOB_NAME && job.WebApplication.Name == site.WebApplication.Name)
20
{
21
job.Delete();
22
}
23
}
24
// Create new job
25
DeployGlobalResources gsJob = new DeployGlobalResources(JOB_NAME, site.WebApplication, properties.Definition.DisplayName);
26
gsJob.Title = JOB_TITLE;
27
// Set up the job to run once
28
gsJob.Schedule = new SPOneTimeSchedule(DateTime.Now);
29
gsJob.Update();
30
}
31
32
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
33
{
34
SPSite site = properties.Feature.Parent as SPSite;
35
36
// delete the job
37
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
38
{
39
if (job.Name == JOB_NAME &&
40
job.WebApplication.Name == site.WebApplication.Name)
41
{
42
job.Delete();
43
}
44
}
45
// Possibly delete the files on retract??
46
}
47
48
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
49
{
50
//throw new Exception("The method or operation is not implemented.");
51
}
52
53
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
54
{
55
//throw new Exception("The method or operation is not implemented.");
56
}
57
58
#endregion
59
}

2



3


4

5

6

7

8

9

10


11

12

13



14

15

16

17

18



19

20



21

22

23

24

25

26

27

28

29

30

31

32

33



34

35

36

37

38



39

40

41



42

43

44

45

46

47

48

49



50

51

52

53

54



55

56

57

58

59

因为是项目的原因,只能把部分代码拷下来,其它的代码就不再详细说了,代码中也只写了拷贝文件,没写删除文件,只要根据提示加上相应的代码就行了。
另外,这是利用了MOSS的SPJOB来实现的,而spjob是使用wss的Timer服务调度的,在Feature启用时,文件的拷贝会有一定的延迟,默认延迟的时间不长,就几秒钟的时间。