liyeho 发表于 2015-9-12 13:58:45

(转)刚开始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]
查看完整版本: (转)刚开始Outlook Addin的布署问题