【问题标题】:default class for an outlook item(specificaly a calendar)Outlook 项目的默认类(特别是日历)
【发布时间】:2018-12-10 14:37:05
【问题描述】:

嗨,上周一直在阅读有关表单区域的信息。我终于设法使用 Windows 控件创建了一个新的交互表单(我不推荐使用 vbscript 的表单)。最后,尽管我必须将新的单独表单与特定的来自 C# 代码的日历...

但让我们开始编写代码...这就是我使用 Outlook-vbscript 表单的方式。(使用 ofts):

    private bool CreateCustomCalendar(string registryname, string newCalendarName, string outlookformpathandfilename)
    {

        app = this.Application;
        Outlook.MAPIFolder primaryCalendar = (Outlook.MAPIFolder)
            this.Application.ActiveExplorer().Session.GetDefaultFolder
             (Outlook.OlDefaultFolders.olFolderCalendar);
        bool needFolder = true;

        if (debugmode) writer.WriteToLog("RootCalendar :" + primaryCalendar.Name + " found");



            Outlook.MAPIFolder personalCalendar = primaryCalendar
                .Folders.Add(newCalendarName,
                    Outlook.OlDefaultFolders.olFolderCalendar);
            personalCalendar.Name = newCalendarName;
            if (debugmode) writer.WriteToLog("Creating Calendar stage1 complete");

            //Access new calendar by its name that has the habit to append this computer only
            bool notfound1 = true; bool notfound2 = true;
            try
            {
                string mName = primaryCalendar.Folders[newCalendarName].Name;
                if (debugmode) writer.WriteToLog("calendar accesible by name:" + mName);
                notfound1 = false;
            }
            catch (SystemException sex)
            {
                throw;
            }


            Outlook.MAPIFolder setcalendar = primaryCalendar.Folders[newCalendarName];
            if (debugmode) writer.WriteToLog("calendar is set");
            PublishFormToPersonalFormsLibrary(setcalendar, outlookformpathandfilename, registryname, registryname, registryname, registryname + "version 1.0.0.1", "1.0.0.1", Application);
            if (debugmode) writer.WriteToLog("Creating Calendar stage2 complete");

            SetFolderDefaultForm_forappointments(setcalendar, "IPM.Appointment." + registryname, newCalendarName);
            if (debugmode) writer.WriteToLog("Creating Calendar stage3 complete");

        return needFolder;

    }

    void SetFolderDefaultForm_forappointments(Outlook.MAPIFolder fld, string msgClass, string displayname)
    {

        Outlook.PropertyAccessor objPA = fld.PropertyAccessor;
        string strBaseType;
        string strMsg;
        int intLoc;
        bool blnBadForm;
        int i;
        string PR_DEF_POST_MSGCLASS =
          "http://schemas.microsoft.com/mapi/proptag/0x36E5001E";
        string PR_DEF_POST_DISPLAYNAME =
          "http://schemas.microsoft.com/mapi/proptag/0x36E6001E";

        string[] arrSchema = { PR_DEF_POST_MSGCLASS, PR_DEF_POST_DISPLAYNAME };
        string[] arrValues = { msgClass, displayname };
        string[] arrErrors;
        if (debugmode) writer.WriteToLog("prepared for setting default item");
        try
        {
            objPA = fld.PropertyAccessor;
            objPA.SetProperty(PR_DEF_POST_MSGCLASS, msgClass);
            objPA.SetProperty(PR_DEF_POST_DISPLAYNAME, displayname);
            if (debugmode) writer.WriteToLog("default folder set");
            //  arrErrors = objPA.SetProperties(arrSchema, arrValues);
        }
        catch (SystemException sex)
        {
            Console.WriteLine("This is catch with system exception : {0}", sex.ToString());
        }


    }


    public void PublishFormToPersonalFormsLibrary(Outlook.MAPIFolder calendarfolder, string oftFilePath, string messageClass, string name, string displayName, string description, string version, Outlook.Application application)
    {
        object missing = System.Reflection.Missing.Value;

        string existingVersion = "";

        // try to create an existing Instance of the Form to check the current installed Version
        try
        {
            // create atemplatefolder object
            Outlook.MAPIFolder templateFolder = application.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderDrafts);
            if (debugmode) writer.WriteToLog("templateFolder is set");

            // we add our new object here
            object existingItem = templateFolder.Items.Add(messageClass);
            if (debugmode) writer.WriteToLog("added form " + messageClass + " as templates");
            // did we installed the form
            if (existingItem != null)
            {
                // yes, we did it before
                // get the formdescription with latebinding
                Type existingItemType = existingItem.GetType();
                Outlook.FormDescription existingFormDescription = (Outlook.FormDescription)existingItemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, existingItem, null);
                if (debugmode) writer.WriteToLog("formdescription allocated to existingformdescription");

                // get the installed version
                existingVersion = existingFormDescription.Version;

                // discard the temporary item
                object[] args = { Outlook.OlInspectorClose.olDiscard };
                existingItemType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, existingItem, args);
                if (debugmode) writer.WriteToLog("GarbageCollection");

            }
        }
        catch (System.Exception ex)
        {

        }

        // if the existing Version is equal, no need for publishing the form
        // if (version == existingVersion) return;

        // check, if the templatefile exists
        if (!System.IO.File.Exists(oftFilePath)) throw new System.IO.FileNotFoundException("Form template could not be found!", oftFilePath);

        // create the item from TemplateFile
        object item = application.CreateItemFromTemplate(oftFilePath, missing);
        if (debugmode) writer.WriteToLog("created item from template");
        // get the FormDescription Property using LateBinding
        Type itemType = item.GetType();
        Outlook.FormDescription formDescription = (Outlook.FormDescription)itemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, item, null);

        // Apply some Parameters to the Formdescription
        formDescription.Name = name;
        formDescription.DisplayName = displayName;
        formDescription.Category = "uncategorized";
        formDescription.Comment = description;
        formDescription.Version = version;
        if (debugmode) writer.WriteToLog("Set custom form and its properties");

        // Publish Form to Personal Froms Library
        //formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olPersonalRegistry );
        formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olFolderRegistry, calendarfolder);
        if (debugmode) writer.WriteToLog("associating complete");



    }

问题是如何使用 form-regions(using .ofs)

欢迎任何解决方案\文档。 非常感谢 stack-overflow 的创建者为这个伟大的资源和所有无私地为我们的问题做出贡献的开发人员

【问题讨论】:

  • 在 .ofs 方面可能占主导地位的一个关键因素 - .oft 替代路径将是为同一日历创建两个表单的选项。这到底是如何工作的?如果有人知道请贡献.. .thnx

标签: c# outlook-addin winforms-interop


【解决方案1】:

我终于做到了!!! outlook.addin 项的替换代码如下:

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        Outlook.Folder taskList =Application.Session.GetDefaultFolder(
   Outlook.OlDefaultFolders.olFolderTasks)
   as Outlook.Folder;

        Outlook.TaskItem taskItem = taskList.Items.Add(
          "IPM.Task.twoformMssges") as Outlook.TaskItem;

        taskItem.Subject = "IPM.Task.twoformMssges Created On " +
          System.DateTime.Now.ToLongDateString();

        taskItem.Save();

        Outlook.MAPIFolder primarytaskfolder = (Outlook.MAPIFolder)
          this.Application.ActiveExplorer().Session.GetDefaultFolder
           (Outlook.OlDefaultFolders.olFolderTasks);
        Outlook.MAPIFolder settaskfolder = primarytaskfolder.Folders["testassociation"];
          Outlook.Application app = this.Application;
        string formpropstring= "twotabs";
       // PublishFormToPersonalFormsLibrary(taskItem,settaskfolder, "c:\\" , "IPM.Task.twoformMssges",registryname, registryname,registryname + "version 0.0.0.1", "0.0.0.1", Application);
        object missing = System.Reflection.Missing.Value;

        string existingVersion = "";
         try
         {

            if (taskItem != null)
            {

                Type existingItemType = taskItem.GetType();
                Outlook.FormDescription existingFormDescription = (Outlook.FormDescription)existingItemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, taskItem, null);
                //if (debugmode) writer.WriteToLog("formdescription allocated to existingformdescription");

                // get the installed version
                existingVersion = existingFormDescription.Version;

                // discard the temporary item
                object[] args = { Outlook.OlInspectorClose.olDiscard };
                existingItemType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, taskItem, args);
                //if (debugmode) writer.WriteToLog("GarbageCollection");

            }
        }
        catch (System.Exception ex)
        {

        }

        Type itemType = taskItem.GetType();
        Outlook.FormDescription formDescription = (Outlook.FormDescription)itemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, taskItem, null);

        // Apply some Parameters to the Formdescription
        formDescription.Name = formpropstring;
        formDescription.DisplayName = formpropstring;
        formDescription.Category = "uncategorized";
        formDescription.Comment = formpropstring;
        formDescription.Version = "0.0.0.1";

        //formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olPersonalRegistry );
        formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olFolderRegistry, settaskfolder);
        //if (debugmode) writer.WriteToLog("associating complete");

        Outlook.PropertyAccessor objPA = settaskfolder.PropertyAccessor;
        string strBaseType;
        string strMsg;
        int intLoc;
        bool blnBadForm;
        int i;
        string PR_DEF_POST_MSGCLASS =
          "http://schemas.microsoft.com/mapi/proptag/0x36E5001E";
        string PR_DEF_POST_DISPLAYNAME =
          "http://schemas.microsoft.com/mapi/proptag/0x36E6001E";

        \\string[] arrSchema = { PR_DEF_POST_MSGCLASS, PR_DEF_POST_DISPLAYNAME };
        \\string[] arrValues = { "IPM.Task.twoformMssges" , "testassociation" };
        \\string[] arrErrors;

        try
        {
            objPA = settaskfolder.PropertyAccessor;
            objPA.SetProperty(PR_DEF_POST_MSGCLASS, "IPM.Task.twoformMssges");
            objPA.SetProperty(PR_DEF_POST_DISPLAYNAME, "testassociation");
            //   if (debugmode) writer.WriteToLog("default folder set");
            //  arrErrors = objPA.SetProperties(arrSchema, arrValues);
        }
        catch (SystemException sex)
        {
            Console.WriteLine("This is catch with system exception : {0}", sex.ToString());
        }






    }

还需要添加几个属性(括号中的代码)

[Microsoft.Office.Tools.Outlook.FormRegionMessageClass("IPM.Task.twoformMssges")]
[Microsoft.Office.Tools.Outlook.FormRegionName("FormInVsto20136.msgclassregion1")]
    public partial class msgclassregion1Factory{ blah blah blah ...

...这样就可以了

(我现在想知道如何区分保存和更新)

【讨论】:

  • 当向导向您询问formregion的类型时,实际添加上面描述的两条线通过在两个表单区域中声明相同的自定义消息(“IPM.Task.twoformMssges”)到任务文件夹。如果表单区域在任务窗口表单中显示为区域,则通用属性(在括号中)说明此配置。你也不要不必将消息类分配给文件夹(任务-约会-邮件等),因为它出现在相同类型(任务)的所有文件夹中。
  • 您可能已经注意到我的问题与约会有关,但答案与任务有关。发生这种情况是因为我不想在我的项目起作用的地方创建虚拟解决方案\试验。无论如何,一旦您检索一个 Outlook 项目以定义一个消息类,这几乎是相同的......为了使所描述的 Q&A 适合您可能希望在以下位置探索一个完整的教程:informit.com/articles/article.aspx?p=1327185
猜你喜欢
  • 1970-01-01
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多