문제

사용자 정의 C# Windows 양식 (또는 WPF) 사용자 컨트롤을 Outlook보기에 포함 시키려고합니다. Outlook 2003 및 Visual Studio 2008을 사용하고 있습니다.

여기에 Outlook 2007의 예를 다운로드했습니다.

http://blogs.msdn.com/e2eblog/archive/2008/01/09/outlook-folder-homepage-hosting-wpf-activex-nforms-controls.aspx

또한 여기 :

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)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top