C#을 사용하여 Outlook 2003보기 컨트롤
-
20-09-2019 - |
문제
사용자 정의 C# Windows 양식 (또는 WPF) 사용자 컨트롤을 Outlook보기에 포함 시키려고합니다. Outlook 2003 및 Visual Studio 2008을 사용하고 있습니다.
여기에 Outlook 2007의 예를 다운로드했습니다.
또한 여기 :
http://msdn.microsoft.com/en-us/library/aa479345.aspx
나는 그것을 테스트했고 2007 년 미만으로 작동하지만 2003 년에는보기를 열면 다음과 같은 오류가 발생합니다.
오류 80131509로 인해 작업을 완료 할 수 없습니다
Visual Studio에서 시작할 수 있습니다. 폴더를 잘 등록하여 디버깅이 작동합니다. 내 유형을 객체 매개 변수로 포함하는 HTML 페이지를 만듭니다. 그러나 호출 해야하는 초기화 메소드는 존재하지 않거나 (JS를 통해 표시되지 않음) 오류가 있습니다.
RegisterSafeForscripting의 중단 점도 결코 맞지 않을 것입니다.
해결책 2
먼저 Amissico에게 감사합니다. 그리고 나는 당신이 제공 한 설명과 링크를 조사 할 것입니다. Follwinng 코드는 저에게 트릭을 만들었습니다 (그러나 버튼 컨트롤과 다른 사람들은 레이아웃이 고장 났지만 WFP가 작동하므로 WPF를 사용합니다). 코드를 리팩터링해야하지만 저를위한 작업 버전이었습니다 ...
내가 마침내 그것을 발견 한 예제는 나를 위해 약간 조정 한 후에 효과가있었습니다.http://www.microsoft.com/downloads/details.aspx?familyid=078124e9-1e88-4f51-8c98-3c1999cfe743&displaylang=en
다음 파일은 위의 예에서 가져온 것입니다.
using System;
using System.IO;
using System.Collections.Generic;
using MSOutlook = Microsoft.Office.Interop.Outlook;
using System.Runtime.InteropServices;
namespace Outlook2003KnowledgeBaseAddIn.Setup
{
public sealed class FolderHomePage
{
/// <summary>
/// List of web view files that have been written out during this Outlook intance
/// </summary>
private static List<string> listWebViewFiles = new List<string>();
/// <summary>
/// Registers a specific managed type as a folder home page. Returns a file path for the folder home page
/// </summary>
/// <param name="viewType">Type of the home page control.
/// Control must be ComVisible should be registered safe for scripting</param>
/// <returns>file path to the folder home page</returns>
public static string RegisterType(Type viewType)
{
if (viewType == null)
return null;
//TODO: ensure that viewType inherits from System.Windows.Forms.Control
//Create the Local App Data directory for the Web view files to reside in
string webViewDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Properties.Resources.WebViewDirectoryName);
if (Directory.Exists(webViewDirectory) == false)
Directory.CreateDirectory(webViewDirectory);
//Create the web view file name based on the viewType guid in the web view directory
string webViewFile = Path.Combine(webViewDirectory, viewType.GUID.ToString("N") + ".htm");
//if the file has been written out already in this session, return
if (listWebViewFiles.Contains(webViewFile))
return webViewFile;
//If the file exists, delete it (for versioning reasons)
if (File.Exists(webViewFile))
File.Delete(webViewFile);
//Open a file stream and text writer for the Web view stream
FileStream stm = new FileStream(webViewFile, FileMode.Create, FileAccess.Write);
TextWriter writer = new StreamWriter(stm, System.Text.Encoding.ASCII);
//Look to see if the viewType has an init method that takes a single Outlook App parameter
System.Reflection.MethodInfo initInfo = viewType.GetMethod("Initialize", new Type[] { typeof(MSOutlook.Application) });
//If the viewType doesn't have an Init method, just write out the html page header
//TODO move HTML code to resource strings
if (initInfo == null)
{
writer.WriteLine("<html><body rightmargin = '0' leftmargin ='0' topmargin ='0' bottommargin = '0'>");
}
//If the viewType does have an Init method, write script to trap the Body.OnLoad event and call the Init method
//passing in the window.external.OutlookApplication object as the parameter
else
{
writer.WriteLine("<html><body rightmargin = '0' leftmargin ='0' topmargin ='0' bottommargin = '0' onload='OnBodyLoad()'>");
writer.WriteLine("<script>\n\tfunction OnBodyLoad()\n\t{\n\t\tvar oApp = window.external.OutlookApplication;");
writer.WriteLine("\t\t{0}.Initialize(oApp);", viewType.Name);
writer.WriteLine("\t}\n</script>");
}
//Write out an object tag that loads up the viewType as a com object via its class id
writer.WriteLine("<object classid='clsid:{0}' ID='{1}' VIEWASTEXT width='100%' height='100%'/>", viewType.GUID, viewType.Name);
writer.WriteLine("</body></html>");
//Close the file
writer.Close();
stm.Close();
//save this file name so we don't write it out multiple times per outlook session
listWebViewFiles.Add(webViewFile);
return webViewFile;
}
private const string CATID_SafeForScripting = "7DD95801-9882-11CF-9FA9-00AA006C42C4";
private const string CATID_SafeForInitializing = "7DD95802-9882-11CF-9FA9-00AA006C42C4";
/// <summary>
/// Registers a managed type that's exposed for COM interop as safe for initializing and scripting
/// </summary>
/// <param name="comType"></param>
public static void RegisterSafeForScripting(Type comType)
{
Guid clsid = comType.GUID;
Guid interfaceSafeScripting = new Guid(CATID_SafeForScripting);
Guid interfaceSafeForInitializing = new Guid(CATID_SafeForInitializing);
ICatRegister reg = (ICatRegister)new ComComponentCategoriesManager();
reg.RegisterClassImplCategories(ref clsid, 1, new Guid[] { interfaceSafeScripting });
reg.RegisterClassImplCategories(ref clsid, 1, new Guid[] { interfaceSafeForInitializing });
}
/// <summary>
/// Unregisters a managed type that's exposed for COM interop as safe for initializing and scripting
/// </summary>
/// <param name="comType"></param>
public static void UnregisterSafeForScripting(Type comType)
{
Guid clsid = comType.GUID;
Guid interfaceSafeScripting = new Guid(CATID_SafeForScripting);
Guid interfaceSafeForInitializing = new Guid(CATID_SafeForInitializing);
ICatRegister reg = (ICatRegister)new ComComponentCategoriesManager();
reg.UnRegisterClassImplCategories(ref clsid, 1, new Guid[] { interfaceSafeScripting });
reg.UnRegisterClassImplCategories(ref clsid, 1, new Guid[] { interfaceSafeForInitializing });
}
}
[ComImport(), Guid("0002E005-0000-0000-C000-000000000046")]
class ComComponentCategoriesManager
{
}
[ComImport(), Guid("0002E012-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface ICatRegister
{
void RegisterCategories(int cCategories, IntPtr rgCategoryInfo);
void UnRegisterCategories(int cCategories, IntPtr rgcatid);
void RegisterClassImplCategories(
[In()] ref Guid rclsid,
int cCategories,
[In(), MarshalAs(UnmanagedType.LPArray)] Guid[] rgcatid);
void UnRegisterClassImplCategories(
[In()] ref Guid rclsid,
int cCategories,
[In(), MarshalAs(UnmanagedType.LPArray)] Guid[] rgcatid);
void RegisterClassReqCategories(
[In()] ref Guid rclsid,
int cCategories,
[In(), MarshalAs(UnmanagedType.LPArray)] Guid[] rgcatid);
void UnRegisterClassReqCategories(
[In()] ref Guid rclsid,
int cCategories,
[In(), MarshalAs(UnmanagedType.LPArray)] Guid[] rgcatid);
}
}
이 파일과 함께 :
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Policy;
using System.Security;
using Outlook2003KnowledgeBaseAddIn.Setup;
using Outlook2003KnowledgeBaseAddIn.UI;
using Outlook2003KnowledgeBaseAddIn.UI.OutlookIntegration;
namespace Outlook2003KnowledgeBaseAddIn
{
[System.ComponentModel.RunInstaller(true)]
public class Installer : System.Configuration.Install.Installer
{
public Installer()
{
}
public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
try
{
ConfigureSecurityPolicy();
RegisterFolderHomePages();
}
catch (Exception ex)
{
throw new System.Configuration.Install.InstallException("Custom Installer Failed", ex);
}
}
public override void Uninstall(System.Collections.IDictionary savedState)
{
base.Uninstall(savedState);
try
{
DeleteSecurityPolicy();
UnregisterFolderHomePages();
}
catch (Exception ex)
{
throw new System.Configuration.Install.InstallException("Custom Installer Failed", ex);
}
}
private void RegisterFolderHomePages()
{
//Utility.FolderHomePage.RegisterSafeForScripting(typeof(FolderHomePages.AccountToday));
FolderHomePage.RegisterSafeForScripting(typeof(WebViewControl));
}
private void UnregisterFolderHomePages()
{
//Utility.FolderHomePage.UnregisterSafeForScripting(typeof(FolderHomePages.AccountToday));
FolderHomePage.UnregisterSafeForScripting(typeof(WebViewControl));
}
private void ConfigureSecurityPolicy()
{
// Find the machine policy level
PolicyLevel machinePolicyLevel = GetMachinePolicyLevel();
// Get the install directory of the current installer
string assemblyPath = this.Context.Parameters["assemblypath"];
string installDirectory =
assemblyPath.Substring(0, assemblyPath.LastIndexOf("\\"));
if (!installDirectory.EndsWith(@"\"))
installDirectory += @"\";
installDirectory += "*";
// Create the code group
CodeGroup codeGroup = new UnionCodeGroup(
new UrlMembershipCondition(installDirectory),
new PolicyStatement(new NamedPermissionSet("FullTrust")));
codeGroup.Description = Properties.Resources.CasPolicyDescription;
codeGroup.Name = Properties.Resources.CasPolicyName;
// Add the code group
machinePolicyLevel.RootCodeGroup.AddChild(codeGroup);
// Save changes
SecurityManager.SavePolicy();
}
private static void DeleteSecurityPolicy()
{
PolicyLevel machinePolicy = GetMachinePolicyLevel();
foreach (CodeGroup codeGroup in machinePolicy.RootCodeGroup.Children)
{
if (codeGroup.Name == Properties.Resources.CasPolicyName)
machinePolicy.RootCodeGroup.RemoveChild(codeGroup);
}
SecurityManager.SavePolicy();
}
private static PolicyLevel GetMachinePolicyLevel()
{
System.Collections.IEnumerator policyHierarchy = SecurityManager.PolicyHierarchy();
while (policyHierarchy.MoveNext())
{
PolicyLevel level = (PolicyLevel)policyHierarchy.Current;
if (level.Type == PolicyLevelType.Machine)
return level;
}
throw new ApplicationException("Could not find Machine Policy level. Code Access Security is not configured for this application.");
}
}
}
이 메소드는 웹보기를 설정합니다.
private void CreateWebViewFolders()
{
MSOutlook.MAPIFolder root = Folder.GetRootFolder(Application.Session);
MSOutlook.MAPIFolder webViewFolder = Folder.CreateFolder(root, Properties.Resources.WebViewFolderName);
webViewFolder.WebViewURL = FolderHomePage.RegisterType(typeof(WebViewControl));
webViewFolder.WebViewOn = true;
}
다른 팁
a를 만들어야 할 것 같습니다 런타임 보안 정책 어셈블리를 위해. 비주얼 스튜디오 / VSTO 이것을 자동으로 설정하십시오. Visual Studio에서 프로젝트를 실행 한 다음 Microsoft .NET Framework 2.0 관리 도구에서 구성 응용 프로그램을 열어서 확인할 수 있습니다. 런타임 보안 정책을 탐색하고 코드 그룹을 확인하십시오. VSTO 프로젝트는 사용자> 코드 그룹> all_code> vstoprojects에 있습니다.
다음은 내 노트입니다.
코드 액세스 보안 정책 (CASPOL) 클래스
- Windows Installer 버전 3을 사용하여 Office 솔루션 배포에서 생성되었습니다.
- CaspolsecurityPolicyInstaller로 SetSecurity 클래스로 이름을 바꿨습니다.
코드 액세스 보안 정책 도구 (caspol.exe)
코드 액세스 보안 정책 도구를 사용하면 사용자와 관리자가 기계 정책 수준, 사용자 정책 수준 및 엔터프라이즈 정책 수준의 보안 정책을 수정할 수 있습니다.
배포
Windows Installer를 사용하여 사무실 시스템 SE 솔루션을위한 Visual Studio 2005 도구 배포 (2/2)
- 기사: http://msdn.microsoft.com/en-us/library/bb332051.aspx
- 다운로드 : http://go.microsoft.com/fwlink/?linkid=83721
- Visual Studio 2005 Office Second Edition 샘플을위한 도구 : Windows Installer 버전 3 (OfficevSTO2005SewindowsInstallerv3.msi)을 사용하여 사무실 솔루션 배포