使用CDOEX修改定期约会的问题 [英] Problem on modifying recurring appointments with CDOEX

查看:94
本文介绍了使用CDOEX修改定期约会的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<! - @page {margin:2cm} P {margin-bottom:0.21cm} - >

大家好,



我有以下问题。我试图将日历数据从一个系统复制到MS Exchange。为此,我与C#合作,直接在Exchange 2003服务器上使用CDOEX。通过创建定期约会,我无法避免发生错误。



如果我在Exchange上创建一个新约会,它似乎正确显示在Outlook上。现在我想更改现有的约会,但是通过执行此操作在Exchange上保存的内容存在问题。 RecurrencePattern和已删除的异常都已正确保存,但修改后的异常似乎未保存。 .NET没有抛出任何错误。



对于测试目的我使用了以下代码片段:

 / * 
*创建和更改具有重复和例外的约会的示例。
* /
命名空间CDOTests
{
class WriteSeries
{
static void Main(string [] args)
{
尝试
{
CDO.Appointment cdoAppointment = new CDO.Appointment();

//确定您是要创建新约会,还是使用位于'strSource'位置的约会
bool isNewApp = true;

//必须更改为您要使用的约会的URL(应在保存新的约会后写入控制台)
string strSource =" file://。 /backofficestorage/example.com/MBX/user.name/Calendar/{F8406423-D969-4BC8-899F-E250BFDBB2B0}.EML" ;;

string strAccount =" user";
string strAccPass =" password" ;;

//用于在异常中更改此数据的字段标识符
string fieldSubj =" urn:schemas:mailheader:subject" ;; // CdoMailHeader.cdoSummary
string fieldDisc =" urn:schemas:httpmail:textdescription" ;; // CdoHTTPMail.cdoTextDescription
string fieldLoc =" urn:schemas:calendar:location" ;; // CdoCalendar.cdoLocation

string strUserMail =" user.name@example.com" ;;

string strCalendarUrl = CdoUtils.getCalendarFolderPath(strUserMail);

// ---------------
//创建连接
// ----------- ----
ADODB.Connection adoConnection = new ADODB.Connection();

adoConnection.Provider =" exoledb.datasource" ;;
adoConnection.Open(strCalendarUrl,strAccount,strAccPass,0);

// ---------------
//加载约会如果存在
// ------- --------
if(!isNewApp)
{
cdoAppointment.DataSource.Open(strSource,adoConnection,
ADODB.ConnectModeEnum.adModeReadWrite,
ADODB.RecordCreateOptionsEnum.adFailIfNotExists,
ADODB.RecordOpenOptionsEnum.adOpenSource,
strAccount,strAccPass);
cdoAppointment = cdoAppointment.GetRecurringMaster(strCalendarUrl,strAccount,strAccPass);
}

// ---------------
//删除模式和例外,如果有些已经存在
// ---------------
if(!isNewApp)
{
while(cdoAppointment.Exceptions.Count> 0)
{
cdoAppointment.Exceptions.Delete(1);
}
while(cdoAppointment.RecurrencePatterns.Count> 0)
{
cdoAppointment.RecurrencePatterns.Delete(1);
}
}

// ---------------
//设定约会数据
// ---------------
cdoAppointment.StartTime = System.Convert.ToDateTime(" 27/07/2009 05:00:00 PM");
cdoAppointment.EndTime = System.Convert.ToDateTime(" 27/07/2009 05:30:00 PM");
cdoAppointment.Location =" Somewhere" ;;
cdoAppointment.Subject =" Normal Subject" ;;
cdoAppointment.TextBody =" some body text" ;;

// ---------------
//添加重复模式
// ---------- -----
CDO.IRecurrencePatterns cdoPatterns = cdoAppointment.RecurrencePatterns;
CDO.IRecurrencePattern cdoPattern = cdoPatterns.Add(" Add");
cdoPattern.Frequency = CDO.CdoFrequency.cdoDaily;
cdoPattern.PatternEndDate = System.Convert.ToDateTime(" 30/07/2009 05:30:00 PM");

// ---------------
//添加例外
// ----------- ----
CDO.IExceptions cdoExceptions = cdoAppointment.Exceptions;
CDO.IException cdoException = null;

//删除一个实例
cdoException = cdoExceptions.Add(" Delete");
cdoException.RecurrenceID = System.Convert.ToDateTime(" 28/07/2009 05:00:00 PM");

//修改一个实例
cdoException = cdoExceptions.Add(" Modify");
cdoException.RecurrenceID = System.Convert.ToDateTime(" 29/07/2009 05:00:00 PM");
cdoException.StartTime = System.Convert.ToDateTime(" 29/07/2009 07:00:00 PM");
cdoException.EndTime = System.Convert.ToDateTime(" 29/07/2009 08:00:00 PM");

cdoException.Fields [fieldSubj] .Value =" Changed Subject" ;;
cdoException.Fields.Update(); //更改字段值后必须完成

// ---------------
//保存到日历
// ---------------
if(isNewApp)
{
cdoAppointment.DataSource.SaveToContainer(strCalendarUrl,null,
ADODB.ConnectModeEnum.adModeReadWrite,
ADODB.RecordCreateOptionsEnum.adCreateNonCollection,
ADODB.RecordOpenOptionsEnum.adOpenSource,
strAccount,strAccPass);
System.Console.Out.WriteLine(cdoAppointment.DataSource.SourceURL);
}
else
cdoAppointment.DataSource.Save();

// ---------------
//将详细信息写入控制台
// -------- -------
CDO.Appointment oCurrent = cdoAppointment.GetFirstInstance(
System.Convert.ToDateTime(" 01/07/2009 05:30:00 PM"),
System.Convert.ToDateTime(" 30/08/2009 05:30:00 PM"));

尝试
{
而(true)
{
int counter = 1;
System.Console.Out.WriteLine(counter +":" + oCurrent.StartTime +" ||" + oCurrent.Subject);
counter ++;
oCurrent = cdoAppointment.GetNextInstance();
}
}
catch(System.Runtime.InteropServices.COMException comExc)
{
if(comExc.ErrorCode == unchecked((int)0x8002000A))
{
//如果你试图从最后的
//现有实例中获取下一个实例,则抛出此异常,因此这是
//的某种中断条件环。
}
否则抛出comExc;
}

// ---------------
//关闭连接
// ----- ----------
adoConnection.Close();

cdoAppointment = null;
adoConnection = null;
}
catch(System.Exception e)
{
System.Console.WriteLine(" {0}异常捕获。",e);
}
}
}
}


为什么约会时会保存一些东西是新的,只有在改变后才能保存?有人知道如何避免这个问题吗?


解决方案

您好,

您能确认这是一个独立的应用程序还是基于服务的应用程序?原因是在代码片段中,您将ADO与.Net框架一起使用。当我们同时使用这两种组合时,我们需要小心谨慎 - 它们可能会导致间歇性问题,尤其是在基于服务的应用程序或多线程应用程序中。

如果我们处理经常性的预约例外,那么我们需要对此进行一点点关注。有两种方法可以在定期会议中处理异常。如果会议不包含 RecurrenceIDRange ThisAndFuture或ThisAndPrior的属性值,您可以只处理一次异常。这是处理异常的有效方法。如果会议包含ThisAndFuture或ThisAndPrior异常,则必须多次遍历异常。这效率较低。这个定义如下: http://msdn.microsoft.com/en-us/library/ aa563315.aspx

另外,如果您想更新现有约会,我建议您查看文章: http://msdn.microsoft.com/en-us/library/aa563036.aspx

希望这有帮助。

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

Hello everybody,

 

I have the following problem. I am trying to replicate calendaring data from one system to MS Exchange. For doing that I use CDOEX directly on Exchange 2003 server in collaboration with C#. By creating recurring appointments an error occurred that I am not able to avoid.

 

If I create a new appointment on Exchange, it seems to be shown by Outlook correctly. Now I would like to change an existing appointment, but there is a problem in what is saved on Exchange by doing this. The RecurrencePattern and the deleted exceptions are saved correctly, but the modified exceptions seems to be not saved. There is no error thrown by .NET.

 

For testing purpose I used the following code snippet:

/*
 * Example for creating and changing an appointment with recurrences and exceptions.
 */
namespace CDOTests
{
    class WriteSeries
    {
        static void Main(string[] args)
        {
            try
            {
                CDO.Appointment cdoAppointment = new CDO.Appointment();
                
                // determines if you want to create a new appointment, or use the one, that is located on 'strSource' location
                bool isNewApp = true; 
                
                // have to be changed to the URL of the appointment you want to use (should be written in console after saving a new one)
                string strSource = "file://./backofficestorage/example.com/MBX/user.name/Calendar/{F8406423-D969-4BC8-899F-E250BFDBB2B0}.EML";

                string strAccount = "user";
                string strAccPass = "password";

                // field identifier for changing this data in exceptions
                string fieldSubj = "urn:schemas:mailheader:subject"; // CdoMailHeader.cdoSummary
                string fieldDisc = "urn:schemas:httpmail:textdescription"; // CdoHTTPMail.cdoTextDescription
                string fieldLoc = "urn:schemas:calendar:location"; // CdoCalendar.cdoLocation

                string strUserMail = "user.name@example.com";

                string strCalendarUrl = CdoUtils.getCalendarFolderPath(strUserMail);

                //---------------
                // create connection
                //---------------
                ADODB.Connection adoConnection = new ADODB.Connection();

                adoConnection.Provider = "exoledb.datasource";
                adoConnection.Open(strCalendarUrl, strAccount, strAccPass, 0);

                //---------------
                // load appointment if it is existing
                //---------------
                if (!isNewApp)
                {
                    cdoAppointment.DataSource.Open(strSource, adoConnection,
                        ADODB.ConnectModeEnum.adModeReadWrite,
                        ADODB.RecordCreateOptionsEnum.adFailIfNotExists,
                        ADODB.RecordOpenOptionsEnum.adOpenSource,
                        strAccount, strAccPass);
                    cdoAppointment = cdoAppointment.GetRecurringMaster(strCalendarUrl, strAccount, strAccPass);
                }

                //---------------
                // delete patterns and exceptions, if some are already existing
                //---------------
                if (!isNewApp)
                {
                    while (cdoAppointment.Exceptions.Count > 0)
                    {
                        cdoAppointment.Exceptions.Delete(1);
                    }
                    while (cdoAppointment.RecurrencePatterns.Count > 0)
                    {
                        cdoAppointment.RecurrencePatterns.Delete(1);
                    }
                }

                //---------------
                // set appointment data
                //---------------
                cdoAppointment.StartTime = System.Convert.ToDateTime("27/07/2009 05:00:00 PM");
                cdoAppointment.EndTime = System.Convert.ToDateTime("27/07/2009 05:30:00 PM");
                cdoAppointment.Location = "Somewhere";
                cdoAppointment.Subject = "Normal Subject";
                cdoAppointment.TextBody = "Some body text";

                //---------------
                // add recurring pattern
                //---------------
                CDO.IRecurrencePatterns cdoPatterns = cdoAppointment.RecurrencePatterns;
                CDO.IRecurrencePattern cdoPattern = cdoPatterns.Add("Add");
                cdoPattern.Frequency = CDO.CdoFrequency.cdoDaily;
                cdoPattern.PatternEndDate = System.Convert.ToDateTime("30/07/2009 05:30:00 PM");

                //---------------
                // add exceptions
                //---------------
                CDO.IExceptions cdoExceptions = cdoAppointment.Exceptions;
                CDO.IException cdoException = null;
                
                // deleting one instance
                cdoException = cdoExceptions.Add("Delete");
                cdoException.RecurrenceID = System.Convert.ToDateTime("28/07/2009 05:00:00 PM");

                // modifying one instance
                cdoException = cdoExceptions.Add("Modify");
                cdoException.RecurrenceID = System.Convert.ToDateTime("29/07/2009 05:00:00 PM");
                cdoException.StartTime = System.Convert.ToDateTime("29/07/2009 07:00:00 PM");
                cdoException.EndTime = System.Convert.ToDateTime("29/07/2009 08:00:00 PM");

                cdoException.Fields[fieldSubj].Value = "Changed Subject";
                cdoException.Fields.Update(); // Have to be done after changing the value of a field

                //---------------
                // save to the calendar
                //---------------
                if (isNewApp)
                {
                    cdoAppointment.DataSource.SaveToContainer(strCalendarUrl, null,
                        ADODB.ConnectModeEnum.adModeReadWrite,
                        ADODB.RecordCreateOptionsEnum.adCreateNonCollection,
                        ADODB.RecordOpenOptionsEnum.adOpenSource,
                        strAccount, strAccPass);
                    System.Console.Out.WriteLine(cdoAppointment.DataSource.SourceURL);
                }
                else
                    cdoAppointment.DataSource.Save();

                //---------------
                // write the details to console
                //---------------
                CDO.Appointment oCurrent = cdoAppointment.GetFirstInstance(
                    System.Convert.ToDateTime("01/07/2009 05:30:00 PM"),
                    System.Convert.ToDateTime("30/08/2009 05:30:00 PM"));

                try
                {
                    while (true)
                    {
                        int counter = 1;
                        System.Console.Out.WriteLine(counter + ": " + oCurrent.StartTime + " || " + oCurrent.Subject);
                        counter++;
                        oCurrent = cdoAppointment.GetNextInstance();
                    }
                }
                catch (System.Runtime.InteropServices.COMException comExc)
                {
                    if (comExc.ErrorCode == unchecked((int)0x8002000A))
                    {
                        // This exception is thrown if you try to get next instance from the last 
                        // existing instance, so this is some kind of break condition for the 
                        // while loop.
                    }
                    else throw comExc;
                }

                //---------------
                // Close the connection
                //---------------
                adoConnection.Close();

                cdoAppointment = null;
                adoConnection = null;
            }
            catch (System.Exception e)
            {
                System.Console.WriteLine("{0} Exception caught.", e);
            }
        }
    }
}

Why is something saved when the appointment is new, and not saved when it is only changed? Do someone have an idea on how to avoid this problem?

 

解决方案

Hi,

Can you confirm whether this is a standalone application or service based application? The reason is in the code snippet, you use ADO with .Net framework. We need to bit care when we use both the combination - they may cause intermittent issues, especially in service-based applications or in multithreaded applications.

If we process recurring appointment exception, then we need to be bit care on this. There are two ways to process exceptions in recurring meetings. If the meeting does not contain exceptions with a RecurrenceIDRange property value of ThisAndFuture or ThisAndPrior, you can process each exception exactly once. This is an efficient way to process exceptions. If the meeting contains ThisAndFuture or ThisAndPrior exceptions, you must loop through the exceptions multiple times. This is less efficient. This is well defined the following sample: http://msdn.microsoft.com/en-us/library/aa563315.aspx


Also when you want to update existing appointments, i recommend you to have look on the article: http://msdn.microsoft.com/en-us/library/aa563036.aspx

Hope this helps.


这篇关于使用CDOEX修改定期约会的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆