ActiveSync编程总结(四)

来源:互联网 发布:董方卓 知乎 编辑:程序博客网 时间:2024/06/05 21:58

Question & Answer

问题1ActiveSync manager如何识别出由来自设备的数据创建出来的一个新桌面端对象?

回答:IReplObjHandler::SetPacket一定创建一个新的HREPLITEM句柄,并把结构REPLSETUP的成员hItem设置成它,传入IReplObjHandler::Setup调用。典型的,ActiveSync provider在调用IReplObjHandler::Setup过程中把指针(HREPLITEM?)存入REPLSETUP。注意读取和写入这个store可以同时发生。另外,在IReplObjHandler::Reset被调用之前,IReplObjHandler::Setup会被调用两次。一个IReplObjHandler::Setup调用也许用于读取,另一个用于写入。因此ActiveSync provider必须保持REPLSETUP指针指向IReplObjHandler::Setup

问题2ActiveSync manager如何表示出由来自桌面的数据创建出的新的设备对象?

回答:设备端IReplObjHandler::SetPacket的实现一定会在REPLSETUP::oidNew中签署新对象的object ID,这个ID被发送到桌面和ActiveSync manager使用桌面对象来维持它的映射

问题3:你如何自动处理冲突和避免冲突处理对话框的显示?

IReplStore::GetConflictInfo能够返回一个指定的错误代码,寻求细节请参考章节“冲突处理”

问题4:设备端的一个改变有可能造成桌面端的一个删除,这是怎么实现的?

IReplObjHandler::SetPacket能够返回一个指定的错误码,寻求细节请参考发送和接收对象一章

问题5ActiveSync manager如何知道桌面store实时的变化呢?

回答:某些情况下,当设备正在连接时,对于用户来说切换到桌面store是可能的。例如:在Stock Protfolio例子中,用户能够用包含了一个不同数据设置的文件来覆盖原有的数据文件。这些情况下,提示用户作一个压缩/交换,因为新的store不再映射到任何设备端的对象。这能够在IReplStore::IsFolderChanged函数中通过返回RERR_STORE_REPLACED来被实现

问题6:对桌面端store的同时读写是可能的吗?

是的,一个ActiveSync provider必须维护俩指针指向不同的REPLSETUP结构,而且,同一时间,只有一个对象能够被读,而另一个对象能够被写。如果有多个读或写动作将会导致问题

问题7:你能够使用transaction来写多个对象吗?(transaction:事务,数据库可以用这个来同时读写一批操作)

是的,如果多个设备对象需要同步到桌面,而且如果桌面应用程序支持事务处理,有时会让人满意的(照顾到性能和可靠性)来在一个事务处理中写多个对象。ActiveSync provider能够通过实现IReplStore::ReportStatus来实现这个。这个事务处理在RSC_BEGIN_BATCH_WRITE开始,在RSC_END_BATCH_WRITE处结束

问题8:你是如何阻止一个对象被标记为改变,在它作为一个同步的结果,被写入到桌面store之后?

当一个设备对象被完全写入到桌面store时,ActiveSync manager调用IReplStore::UpdateItemActive Provider将打开这个对象并(使用IReplStore::IsItemChanged中它使用的,典型的是一个时间戳或一个改变序列号)更新这个给定的HREPLITEM句柄,这阻止了在桌面端对象被标记为改变

问题9如果一个桌面对象在它被同步之后又一次被快速改变了,该怎么办

当一个对象被发送到设备,ActiveSync manager等待来自设备的确认,这个对象在清除桌面端标记为被改变标志之前,已经被成功同步了。因此,如果设备在写入对象时出现问题,这个对象的同步在下一次同步时会再次尝试。而且,可能一个对象会被再次改变在确定到达桌面之前。这种情况下,ActiveSync管理器需要保持这个对象“脏”的,这在IReplStore::IsItemChanged方法中被实现。上面这个例子中传入这个函数的最后一个参数需要设置为NULLActiveSync provider将会打开当前的对象并且比较时间戳,如果当前对象已经被改变,返回true

问题10。如果由一个ActiveSync provider定义的同步过滤器和当前日期有关,那么当日期改变了过滤器如何被再次应用呢?

回答:一个这类过滤器的典型例子是这样的:同步仅同步三天之内的appointments。如果设备被连接并且日期已经改变,比如凌晨或者用户改变了当前日期和时间,所有的appointment必须在过滤器中被重新评估,无论何时这样的日期改变发生,ActiveSync manager为每个和所有对象使用参数RSC_DATE_CHANGED调用IReplStore::ReportStatus。一个ActiveSync provider典型地会在给定的HREPLITEM中重置一个位描述符,以便当IReplStore::IsItemReplicated迟些时候被调用时,这个法则将会被重新评估...

问题11你如何关闭和重新启动ActiveSync manager

运行:syncmgr.exe/quit,优雅地关闭ActiveSync manager。运行“syncmgr.exe/show”重新启动ActiveSync manager并且让ActiveSync状态窗口可见。运行“syncmgr.exe”简单地启动ActiveSync manager,但不显示ActiveSync状态窗口

问题12:为什么选项按钮,在ActiveSync选项对话框中,对于断开连接的设备失效?

回答:一个普通的错误将会让IReplStore::GetStoreInfo返回任何错误码,当IReplStore::Initialize没被调用的情况下。正确的实现会返回NOERRORSTOREINFO的每个成员中,除非Store ID被设置,一个ActiveSync provider典型地会在IReplStore::Initialize中设置一个标记位,并且在IReplStore::GetStoreInfo中检查它

问题13:如果ActiveSync provider支持实时通知,为什么objects不在ActiveSync状态窗口中接着就显示变化或删除?

你也许已经实现了IReplStore::IsFolderChanged来设置*pfChangedFALSE,你需要设置它为*pfChangedIReplStore::IsFOlderChanged第一次被调用的时候,参考章节“列举对象”来获得更多细节

问题14:如果ActiveSync provider不支持实时通知,对象的变化和删除是如何被探测到的?

变化和删除是在列举所有存储中的对象时并且检查每个来看是否它被改变被探测到的,这个检查过程将在同步开始之前就启动或者它可以在每个指定时间间隙执行一次。这个间隙在STOREINFO::uTimerRes中被设置为毫秒级别,这个过程使用和应用程序相同的资源?并且不会在应用程序忙的时候被启动。一个ActiveSync provider能够设置STOREINFO::uTimerRes-1,那么无论何时当ActiveSync状态窗口被激活,例如:当用户点击状态窗口时,他就合理地假定使用这些数据的应用程序不忙,并且ActiveSync管理器能够调用这个列举动作(看来就是说 manager通过两种方法:非实时状态下靠列举和实时状态下靠通知)

问题15.一个对象在设备端被删除,并且用户删除了对应的桌面端对象,为什么对象保持了显示的最新状态?

一定有一种非正常的状态:当一个设备连接时,ActiveSync manager不能探测到删除。ActiveSync provider将实现IREplStore::IsValidObject来检查通过给定的句柄来表示的对象,如果这个对象不再存在了,返回RERR_OBJECT_DELETED,它也可以返回RERR_CORRUPT来显示一个错误的根本不代表任何对象的句柄

问题16.IReplStore::RemoveDuplicates被调用,那么ActiveSync provider会删除一些桌面端的store中的对象。它是如何询问ActiveSync manager来重新启动同步动作来发现那个探测的呢?

IReplStore::RemoveDuplicates中返回RERR_RESTART导致ActiveSync manager再次去启动同步处理,返回任何其他错误码会导致ActiveSync manager在下一个同步动作完成后去调用IReplStore::RemoveDuplicates

问题17,你如何阻止ActiveSync管理者来展示标准的“初始化了%s,同步服务没有成功,错误:%x,错误消息对话框的

问题18你是如何标记,当读取一个对象时的最后(或仅有的)的包的

返回RWRN_LAST_PACKETIReplObjHandler::GetPacket

问题19一个ActiveSync provider是怎样知道同步动作的启动和结束的?

IReplStore::ReportStatus带着RSC_BEGIN_SYNC被调用,当同步结束时它会被使用RSC_END_SYNC参数调用

问题20当一个设备上的对象在被写入或者删除的时候失败时,你如何获取一个错误代码

IReplStore::ReportStatus使用RSC_WRITE_OBJ_FAILED参数被调用,在一个对象写入设备失败时;...

问题21一个ActiveSync provider如何知道是否它需要处理一个连接的还是选中的设备?(注意设备的两种状态:连接和选中)

IReplStore::Initialize被调用时,uFlags被设置为ISF_SELECTED_DEVICE如果并且只有设备没有连接(那表示,用户选择了一个非连接的设备profile在移动设备文件夹中的),如果这个标记没有被设置,设备必须被连接。一个ActiveSync provider也能够调用IReplNotify::QueryDeviceQDC_CON_DEVICE_KEY,&hKey),如果这个调用成功,那就是一个连接的设备,否则就是不连接的

问题22你如何获取那些注册表值(在这些值中存储了一个ActiveSync provider的选项)

调用IReplNotify::QueryDevice(QDC_CON_DEVICE_KEY,&hKey)用于一个连接的设备或者调用IReplNotify::QueryDevice(QDC_SEL_DEVICE_KEY,&hKey)用于一个选中的或者非连接的设备

问题23你如何获取一个设备名

调用IReplNotify::QueryDevice(QDC_CON_DEVICE,&devInfo)用于一个连接的设备,或者调用IReplNotify::QUeryDevice(QDC_SEL_DEVICE,&devInfo)用于一个选中或者非连接的设备DEVINFO::szName是这个设备的名称

问题24桌面ActiveSync provider需要做什么来支持多个设备的同步...

问题25设备ActiveSync provider需要做什么来支持两个桌面计算机的同步?

设备ActiveSync provider需要把uPartnetBit传入InitObjType并且使用它来设置或重置一个同步对象的dirty

问题26 IReplStore的参考计数没有到达0,那么 provider不能被释放,为什么?

问题27IReplObjHandler::SetPacket中,桌面ActiveSync provider如何知道是否它是一个新对象或者不是?

IReplObjHandler::Setup调用时RSF_NEW_OBJECT将会被设置在REPLSETUP::dwFlags

问题29 IReplObjHandler::SetPacket中,设备ActiveSyncgognzheruhe知道一个对象是否是新的?

它可以调用CeGetOidInfoREPLSETUP::oid参数,如果是新的设备对象会导致失败

问题30 在桌面端的IReplObjHandler::SetPacket被调用时,一个不同的对象也许改变或者创建了,你怎么告诉ActiveSync管理者去再次同步,因此这个对象将被发现?

作为一个例子,当一个新的使用生日的连接被写入到桌面store,一个重现的约会也许自动创建了,如果ActiveSync provider支持实时通知,这个变化将会被自动发现。否则,ActiveSync provider需要调用

IReplNotify::OnItemNotify使用storeProgID和改变了或者刚创建的对象类型。HREPLITEM能够被传递一个NULL

问题31,当设备端ActiveSync provider将被结束时,它如何通知ActiveSync manager后来再试呢?

如果ActiveSync provider不能立刻结束它自己,当InitObjType(NULL,NULL,0)被调用,他能够返回

False,ActiveSync manager将尝试在两秒钟内去结束 provider,它将保持最多15分钟之内。这对于某种ActiveSync provider来说很有必要,它们必须标记并等待一个工作者线程的结束

问题32 ActiveSync provider支持多个对象类型的同步,如何让IReplStore::Initialize知道哪种类型被激活了,因此它就不必浪费时间去让对象类型失效了

在调用IReplStore::Initialize之前,ActiveSync用参数RSC_OBJ_TYPE_ENABLED调用IReplStore::ReportStatus,...

问题33 在安装ActiveSync模块的程序中,如何关闭ActiveSync manager,让他不再加载模块?

当你安装程序要去安装或更新ActiveSync模块的时候,需要先关闭ActiveSync manager来让他释放掉已经存在于内存中的ActiveSync模块,然后你才能覆盖你需要更新的模块。你能通过运行“syncmgr.exe/quit”关闭ActiveSync manager,你通过“syncmgr.exe /quit,你可以通过运行“syncmgr.exe /show”来重新启动ActiveSync manager,以带着窗口的方式。或者使用sysncmgr.exe启动一个不带状态窗口的ActiveSync manager,详细参考附录中的“syncmgr.exe允许的命令行参数”

问题34 CE文件ActiveSync provider支持挂载的卷标吗?比如闪存?

目前不支持

附录

微软ActiveSync服务 provider列表

微软winCE服务2.1版提供了一系列的ActiveSync provider

provider名称 桌面provider   桌面provider基地址 设备 provider   支持的对象类型

Outlook同步  outstore.dll       0x22000000           pegobj.dll          Appointment

                                                                                               Contacts

                                                                                                Inbox

                                                                                                Task

Schedule+同步 scdstore.dll    0x20000000          pegobj.dll          Appointment

                                                                                                Contackts

                                                                                                Task

WinCE文件同步cefstore.dll  0x23000000            cefobj.dll         File

移动通道同步  aafstore.dll   0x24000000           aafobj.dll           Channel

Syncmgr.exe的合法命令行参数

syncmgr.exe是一个ActiveSync manager的执行体,它包含了一系列参数,你能够传入这个程序不止一个参数,你甚至在它已经运行的情况下携带参数运行syncmgr.exe。下面是参数列表

参数                                            含义

/quit                  当设备连接处于激活状态时关闭ActiveSync manager,这对于调试很重要,因为所有的ActiveSync模块都将被卸载,你不需要物理上断开设备

/show               

/synconcon       在需要的时候启动ActiveSync manager,并检查“连接中的同步”设置,如果该设置开启了,在同设备连接的时候立即启动同步,没有这个参数...

/syncmgr           启动ActiveSync时显示选项对话框

/syncnow         启动ActiveSync并立刻同步数据

原创粉丝点击