(转)刚开始Outlook Addin的布署问题
转自:http://weblogs.asp.net/mnissen/articles/427504.aspx遇到的问题:用VSTO开发的Outlook Addin生成的默认setup工程不能正确的将插件安装到客户端,安装过程没有报错,注册表的Outlook下面的Addin也有注册。
最后的解决:客户端需要满足下面几个条件:
1. .NET Framework 2.0 (RC1)
2. Microsoft Office 2003 w/Outlook
3. Microsoft Office 2003 SP1 (or later)
4. Microsoft Office 2003 Primary Interop Assemblies (O2003PIA.exe) (how-to)
5. Visual Studio Tools for Office Runtime (vstor.exe) (Same version as .NET Framework!)
6. Language pack for vstor (Optional)
7. Registry keys for Outlook plugin (fixed by default VSTO Setup project)
8. Code Access Security FullTrust grant to your assemblies
相关的软件可以去Microsoft网站下载。
VSTO模版中生成的setup工程中欠缺如下两个方面:
1. reference中缺少Microsoft.Office.Tools.Common.dll,这点可以简单的在主工程中添加reference选择相应的dll即可。
2. 需要msi自动的实现Code Access Security(而不是在客户机安装.NET Framework 2.0 Configuration Tools然后手动配置安全策略),实现方法如下:
新建一个System.Configuration.Install.Installer的继承,通过右键点击你的工程然后Add New Item | Installer Class,命名为Installer,然后在Installer.cs中写入代码如下:
1using System;
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Security.Policy;
5using System.Security;
6
7namespace EOfficeSync
8{
9 // Code Access Security configuring installer by Mads Nissen 2005
10 // http://weblogs.asp.net/mnissen
11
12
13 public partial class Installer : System.Configuration.Install.Installer
14 {
15
16 private readonly string installPolicyLevel = "Machine";
17 private readonly string namedPermissionSet = "FullTrust";
18 private readonly string codeGroupDescription = "VSTO Permissions for Objectware Plugins";
19 private readonly string productName = "Objectware SharepointConnector";
20 private readonly bool debugBreakOnInstall = false;
21
22 private string codeGroupName = "";
23
24 /**//// <summary>
25 /// Gets a CodeGroup name based on the productname and URL evidence
26 /// </summary>
27 private string CodeGroupName
28 {
29 get
30 {
31 if (codeGroupName.Length == 0)
32 {
33 codeGroupName = "[" + productName + "] " + InstallDirectory;
34 }
35 return codeGroupName;
36 }
37 }
38
39 /**//// <summary>
40 /// Gets the installdirectory with a wildcard suffix for use with URL evidence
41 /// </summary>
42 private string InstallDirectory
43 {
44 get
45 {
46 // Get the install directory of the current installer
47 string assemblyPath = this.Context.Parameters["assemblypath"];
48 string installDirectory =
49 assemblyPath.Substring(0, assemblyPath.LastIndexOf("\\"));
50
51 if (!installDirectory.EndsWith(@"\"))
52 installDirectory += @"\";
53 installDirectory += "*";
54
55 return installDirectory;
56 }
57 }
58
59 public Installer()
60 {
61 }
62
63 public override void Install(System.Collections.IDictionary stateSaver)
64 {
65 base.Install(stateSaver);
66
67 try
68 {
69 ConfigureCodeAccessSecurity();
70 // Method not able to persist configuration to config file:
71 // SetPortalUrlFromInstallerParameter();
72 }
73 catch (Exception ex)
74 {
75 System.Windows.Forms.MessageBox.Show(ex.ToString());
76 this.Rollback(stateSaver);
77 }
78 }
79
80 /**//// <summary>
81 /// Configures FullTrust for the entire installdirectory
82 /// </summary>
83 private void ConfigureCodeAccessSecurity()
84 {
85
86 PolicyLevel machinePolicyLevel = GetPolicyLevel();
87
88 if (null == GetCodeGroup(machinePolicyLevel))
89 {
90 // Create a new FullTrust permission set
91 PermissionSet permissionSet = new NamedPermissionSet(this.namedPermissionSet);
92
93 IMembershipCondition membershipCondition =
94 new UrlMembershipCondition(InstallDirectory);
95
96 // Create the code group
97 PolicyStatement policyStatement = new PolicyStatement(permissionSet);
98 CodeGroup codeGroup = new UnionCodeGroup(membershipCondition, policyStatement);
99 codeGroup.Description = this.codeGroupDescription;
100 codeGroup.Name = this.codeGroupName;
101
102 // Add the code group
103 machinePolicyLevel.RootCodeGroup.AddChild(codeGroup);
104
105 // Save changes
106 SecurityManager.SavePolicy();
107 }
108 }
109
110 /**//// <summary>
111 /// Gets the currently defined policylevel
112 /// </summary>
113 /// <returns></returns>
114 private PolicyLevel GetPolicyLevel()
115 {
116 // Find the machine policy level
117 PolicyLevel machinePolicyLevel = null;
118 System.Collections.IEnumerator policyHierarchy = SecurityManager.PolicyHierarchy();
119
120 while (policyHierarchy.MoveNext())
121 {
122 PolicyLevel level = (PolicyLevel)policyHierarchy.Current;
123 if (level.Label.CompareTo(installPolicyLevel) == 0)
124 {
125 machinePolicyLevel = level;
126 break;
127 }
128 }
129
130 if (machinePolicyLevel == null)
131 {
132 throw new ApplicationException(
133 "Could not find Machine Policy level. Code Access Security " +
134 "is not configured for this application."
135 );
136 }
137 return machinePolicyLevel;
138 }
139
140 /**//// <summary>
141 /// Gets current codegroup based on CodeGroupName at the given policylevel
142 /// </summary>
143 /// <param name="policyLevel"></param>
144 /// <returns>null if not found</returns>
145 private CodeGroup GetCodeGroup(PolicyLevel policyLevel)
146 {
147 foreach (CodeGroup codeGroup in policyLevel.RootCodeGroup.Children)
148 {
149 if (codeGroup.Name.CompareTo(CodeGroupName) == 0)
150 {
151 return codeGroup;
152 }
153 }
154 return null;
155 }
156
157 public override void Uninstall(System.Collections.IDictionary savedState)
158 {
159 if (debugBreakOnInstall)
160 System.Diagnostics.Debugger.Break();
161
162 base.Uninstall(savedState);
163 try
164 {
165 this.UninstallCodeAccessSecurity();
166 }
167 catch (Exception ex)
168 {
169 System.Windows.Forms.MessageBox.Show("Unable to uninstall code access security:\n\n" + ex.ToString());
170 }
171 }
172
173 private void UninstallCodeAccessSecurity()
174 {
175 PolicyLevel machinePolicyLevel = GetPolicyLevel();
176
177 CodeGroup codeGroup = GetCodeGroup(machinePolicyLevel);
178 if (codeGroup != null)
179 {
180 machinePolicyLevel.RootCodeGroup.RemoveChild(codeGroup);
181
182 // Save changes
183 SecurityManager.SavePolicy();
184 }
185 }
186 }
187}
VB.Net版本的请查看:http://weblogs.asp.net/mnissen/articles/429117.aspx
在setup工程View | Custom Action的install和uninstall中添加新的Custom Action,选择生成好的Primary Output。完工。
详细内容可以参考http://weblogs.asp.net/mnissen
页:
[1]