Pregunta

Quiero incrustar un formulario de Windows de encargo c (o WPF) control de usuario en una vista de perspectiva. Se utiliza Outlook 2003 y Visual Studio 2008.

Lo hice descargar un ejemplo para Outlook 2007 aquí:

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

y también aquí:

http://msdn.microsoft.com/en-us/library /aa479345.aspx

Lo he comprobado y en 2007 se está trabajando, pero para 2003 que estoy recibiendo el siguiente error cuando quiero abrir la vista:

No se pudo completar la operación debido a un error 80131509

puedo iniciarlo desde Visual Studio, que es el registro de la carpeta bien, la depuración de obras y todo eso. Se crea una página HTML que contiene mi tipo como un parámetro del objeto -. Pero el método de inicialización que debe ser llamado no está presente (no se muestra a través de JS) o tiene algunos errores

Los puntos de corte para RegisterSafeForScripting están también Nunca golpee -. Tal vez relacionada con ese

¿Fue útil?

Solución 2

En primer lugar gracias AMissico - y voy a mirar en la descripción y enlaces que ya ha proporcionado también. El código follwinng hizo por mí el truco (pero los botones de control y otros han roto diseño - pero el PMA trabaja así que voy a utilizar WPF). Tengo que refactorizar el código pero era la versión de trabajo para mí ...

El ejemplo que finalmente encontré que trabajó después de ajustar un poco para mí: http://www.microsoft. com / descargas / details.aspx? familyid = 078124E9-1E88-4F51-8C98-3C1999CFE743 y displaylang = es

El archivo siguiente está más o menos tomada del ejemplo anterior

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);
    }

}

junto a este archivo:

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.");
        }
    }
}

Este método establece la vista web:

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;
}

Otros consejos

Parece que usted necesita para crear una Política de Seguridad Tiempo de ejecución para el montaje. Visual Studio / VSTO set esto automáticamente. Esto se puede comprobar mediante la ejecución de su proyecto de Visual Studio y luego abrir la aplicación 2.0 Configuración de Microsoft .NET Framework en Herramientas de administración. Vaya a la Política de Seguridad en tiempo de ejecución y comprobar los grupos de códigos. proyectos de VSTO están bajo usuario> Grupos de Códigos> All_Code> VSTOProjects.

Los siguientes son mis notas.

Política de Seguridad Código de acceso (caspol) Las clases

  • Creado a partir de la implementación de soluciones de oficina usando el instalador de Windows Versión 3.
  • Renombrado clase SetSecurity a CaspolSecurityPolicyInstaller.

Herramienta Política de Código de Acceso de Seguridad (Caspol.exe)

La herramienta Directiva de seguridad Código de acceso permite a los usuarios y administradores de modificar la política de seguridad para el nivel de directiva de equipo, nivel de políticas de usuario, y el nivel de la política de empresa.

Implementación

La implementación de Visual Studio 2005 Tools para las soluciones de Office System SE uso de Windows Installer (Parte 1 de 2)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top