Tuesday 16 November 2010

Using CDO to write to Exchange from a Windows Service

Not strictly a Delphi-post this one, but still a programming issue nonetheless.

We have several Windows Services that have the ability to add an entry to people's Outlook Calendars or Task Lists. This cannot be done using Outlook Automation, because that requires Outlook to be accessible to run which it cannot be from a Windows Service. Furthermore, it mandates that Outlook is installed on the PC or Server which is not something we can guarantee.

The alternative I started using years ago was Collaboration Data Objects, CDO, a Microsoft library that basically gives you a great deal of access to the Exchange Server, without ever having to know anything about Outlook, which is, after all, just a client for Exchange Server.

CDO is available in Delphi by simply importing the "Microsoft CDO 1.21 Library" type library.

Despite being complicated to set up (necessarily so due to mailbox security), this works very well, and is what Microsoft use for their Outlook Web Access software. Reading on the subject, I see that Symantec and Blackberry are also users of this API.

Now, Microsoft being Microsoft, CDO has not been on-developed for quite some time, although it continues to work just fine. It is no longer installed as standard on the OS when Outlook (2007 onwards) is installed, but they now allow you to install it yourself by releasing an MSI that installs the CDO and MAPI DLLs.

Microsoft state in their Knowledgebase Article 2028411 that:

Programs that use CDO should be re-designed to use other Application Programming Interfaces (APIs) instead of CDO. Starting with Outlook 2007, the Outlook object model was greatly expanded to provide functionality that was previously available only by using CDO 1.2.1. The Outlook 2010 object model includes some new features to expand on this more...The Outlook object model also works for both 32-bit and 64-bit versions of Outlook. Developers should use the Outlook 2010 object model instead of CDO 1.2.1. Also, developers can still use Extended MAPI (which requires unmanaged C++) in some scenarios where CDO was required. However, if it is possible, we generally recommend that the Outlook object model be used instead of Extended MAPI.

The question is, what are developers supposed to use instead of CDO? It fills a gap that the Outlook Object Model cannot fill, namely, use in web applications and Windows Services. It appears they are not providing an alternative, and yet are encouraging developers away from it towards a tool that cannot work unless running as a standard Windows application.

Monday 6 September 2010

Open Letter to Digital Metaphors


I am currently rewriting our standard Crystal Reports (over 250) in ReportBuilder, so that we can standardise on one report writer. I have been so impressed by ReportBuilder during this development process that I felt compelled to write to Digital Metaphors and let them know.



I just wanted to drop you a line to say how continually impressed I am with ReportBuilder. We have been a customer since RB version 4, when we chose it as the report writer that we wanted to embed in our software for end users. This decision came some time after we had already started the software, and so the standard reports we provide are written with Crystal Reports.

I am currently undergoing a 2 month project to eliminate Crystal Reports from our system, which involves rewriting over 250 reports in ReportBuilder. I am about 85% of the way through this project now, and I can only say it has actually been a pleasure, rather than the chore I was expecting it to be. There hasn't been one thing that I haven't been able to reproduce in ReportBuilder, and in the majority of cases, the RB method of doing something is far better.

Of particular importance to us have been RAP, the SQLBuilder class and Autosearch Parameters. The aim has been to totally design these reports so that they are self-sufficient, i.e. there is no Delphi form or code behind them as individual reports. These 3 features have enabled this transition, and I believe that, thanks to your product, we now have superior reports.

We also have the need to modify the query of every report when it runs, in order to add security so that the users only see the subset of data they're allowed to see. This is made so easy by the TdaSQLBuilder class.

With the email and PDF export built-in, we will also be able to achieve one area of functionality we have long strived for: automated, or scheduled, reports. I will now be able to allow users to select a report, set a time for it to run on a regular basis, and ask them to supply any parameters in advance. It can then be printed or emailed overnight, or as required.

Not to mention how powerful the RB Server edition has been; we have been able to offer user-defined web-based reports for our intranet software which has been one of our most successful features to date.

As a software developer, I know that praise is hard to come by and it can be dejecting to just see a long list of problems, such as if you look at the newsgroups. This is why I felt compelled to write and let you know that we regard ReportBuilder as our most valuable third-party add-on for Delphi.

Friday 13 August 2010

Still alive and still on Delphi 6

I hadn't realised that my last post was January, 6 months has just disappeared. 6 being the magic number, in that we still have not found the time to stop development on our products in order to migrate up to Delphi 2009 that we bought a while back.

Since then, Delphi 2010 passed me by without a great deal of interest, and now I find myself with even less enthusiasm for Delphi 2011 XE, there is simply nothing in it that encourages me to upgrade.

(I also can't understand the naming convention. Although David I explained it last week, it isn't a convention that will scale. "X" for heterogeneous, and "E" for Embarcadero. What happens to the next version? It's like Microsoft coming up with Windows 95, 98, ME, 2000, XP, Vista, 7 - absolutely no consistency in the naming convention and if you didn't know which was which, you wouldn't know what order they came in. Maybe that only matters to me.)

In any case, we have taken one decision that will make the Unicode transition to Delphi 2009 easier, and that is to drop our support for Crystal Reports in the next release of our product. We are currently tied to using Crystal Reports 7 (yes, really!) because it was the last version that a stable Crystal VCL for Delphi component was written for. Besides, the latest versions of Crystal Reports have dropped any support for native software developers, only now supporting VS.Net and Eclipse developers.

It does mean that I am having to rewrite over 250 standard reports in our preferred report designer, ReportBuilder from Digital Metaphors. But this product is now well embedded into our software, we provide the designer for users to write their own reports and we can access any part of the report at run-time in order to inject data security before the user sees the final report.

So one less unsupported component out of the way, and with ReportBuilder 12, we can also drop yet another third-party component that did some things that ReportBuilder wasn't able to do previously, but can now.

As a side note, over the past 6 months, I've come to totally rely on the Raize and TMS component sets, to the point now where I use them more than the standard VCL controls. The Raize ones just work well and look so good, and the TMS ones have so much functionality crammed into them; our users are really starting to see the benefit of good interface design.

Our company recently put out a call to customers for product testimonials in order that we could be considered for a software award; one word out of all of the responses pleased me the most about our software: robust.

Tuesday 26 January 2010

The road to Delphi 2009 - Part 1 (v) revisited

Well that was judicious timing (for once)! Just as we decided to take the plunge and do away with ODBCExpress in favour of dbGo, I had an email from Pieter Myburgh at Korbitec. In it, he stated that the management had rejected the proposal to make ODBCExpress open-source and instead have "end-of-lifed" the project.

Now, Pieter has been nothing but helpful and this decision was out of his hands. But what a strange decision. After his personal email to me, another one followed to other developers which was a bit more definitive:


As you know a few of us here at Korbitec have been pushing to get ODBCExpress open-sourced, since there is no ongoing development, and recent changes in Delphi 2009 of the char & string types to Unicode have made ODBCExpress unusable in its current form in this version of Delphi. The bad news is that open-sourcing ODBCExpress has been rejected by management for various reasons. However the good news is that the latest source code is available for download by all of the existing registered users of ODBCExpress. Furthermore you are allowed to modify the source code in any way for your own purposes, or collaborate with other registered ODBCExpress users to port it to newer versions of Delphi if needed. So unfortunately this is the end of the road of Korbitec’s involvement with maintaining ODBCExpress.


Pretty much the same message is available on the ODBCExpress website.

It's an odd decision not to open-source it, as TurboPower did so successfully with its VCL component sets all those years ago. They can't make any more money out of it, they're encouraging developers to collaborate and help each other, they're giving away the source code to registered developers who don't already have the source - yet they won't make the source code available to everyone so that the project might live on.

Bit of a two-fingers up to Delphi really. Pretty sad ending to a good set of components.

Thursday 21 January 2010

The curious case of dead Delphi

You don't have to look very far for people asking the question "Is Delphi Dead?". StackOverflow had a recent question on it, and Delphi developer JamieI recently created a website to answer the question succinctly.

OK, so it was a darling of the 90s and these days it isn't as high profile as it used to be - .NET hurt Delphi badly because it took Delphi's edge away. However, isn't it part of the job of software professionals to keep up to date with what programming languages and tools and available?

I use Delphi exclusively, yet I still know all about the recent versions of Ruby on Rails, C#, PHP, Java, VB.Net, ASP.Net (etc etc) because I make it my job to know about them. I don't read in technical detail about the merits of each and what the new versions provide, but I'm aware of the other tools available in my industry because they are important to the future of software development.

So if I wasn't a Delphi developer, I'd still know that Delphi 2010 was recently launched, that Delphi had a new owner and that the future wasn't over.

Tim Anderson recently posted a blog about the future of Microsoft Access, and he was asked in a comment what development platform he uses, to which he answered "Visual Studio or Delphi". The reply astounded me:

I used Delphi many years ago, I did not realise it was still going.

Now, this was from someone who called themselves "Freelance Access Developer" which may explain a lot about his or her scope of knowledge of the software industry, but surely if you used to use Delphi, you'd notice in passing a headline about the new version coming out or a recent buyout of the company.

Or maybe I just read too much.

Tuesday 19 January 2010

The road to Delphi 2009 - Part 1 (v)

A new year and time to make a decision about how we are going to move our ten year old codebase from Delphi 6 up to Delphi 2009. If you've followed my other posts in this "road to Delphi 2009" thread then you'll know that I hit a stumbling block when migrating a third-party component, ODBCExpress. This is a third-party database connectivity component that was well written, well documented and had good reviews and articles in Delphi Informant (which dates it a bit for those who remember that magazine).

At the time we chose it, our product was based on the Access database and we were looking to add SQL Server support, so we chose it as a good option to handle any database type. I explained this back in June 2007.

Unfortunately, the product was no longer actively developed from Delphi 2006 and despite help from its main developer to at least get it compiled into Delphi 2009, it didn't work properly thanks to all the Unicode changes.

Seeing as we bought Delphi 2009 in June 2009 and haven't migrated to it yet, a decision has been made. We are going to move all the code away from ODBCExpress, and to the dbGo ADO components provided as standard with Delphi (from Delphi 5 through to the current Delphi 2010).

Presciently, in June 2007, I also said this:

I've thought about moving to one of those bundled Delphi offerings in order to save myself the worry should ODBCExpress go tilt. But I haven't...because the database architectures offered with Delphi keep changing and I'm not sure I want to run the risk of changing everything over only to have it "deprecated" like the BDE.

Well the dbGo components are still going strong and they made the effort to Unicode-enable them for Delphi 2009, so I'm classing this as a low-risk option.

I wrote some test programs using the ODBCExpress components and then migrated it to ADO to see what conversion issues I'd have. I made notes and it wasn't as bad as I thought. I can now do everything I could do with the ODBCExpress components, even if I have had to write a function that does what a component used to do. If anything, it has been an interesting exercise in the back-end of SQL Server.

What was particularly pleasurable was doing all the work in Delphi 6 and then simply recompiling it in Delphi 2009 to see what happened. The answer: it compiled and ran just as it did in Delphi 6 (give or take a few string cast warnings in my own code which is part of the Unicode migration, and expected). Perfect.

For those who may ask why I'm not going for dbExpress instead (which is also standard with Delphi and developed by CodeGear/Embarcadero), it was a couple of things. It was initially my preferred choice but the extra DataSetProvider/ClientDataSet layer required to use it visually gave me the creeps, and I've been reading some frightening problems that people are having with it with Delphi 2010 and SQL Server. Plus the architecture of dbGo more closely matches that of ODBCExpress, facilitating the migration.

So now we have a path, a light at the end of the tunnel. It's not going to be pretty, and I know it will be tedious, but it will be another third-party component set that I can drop which, as I said in another posting in June 2007:

that the less third-party tools I can get away with using the better, purely for future-proofing purposes. If Delphi then provides that same component as standard in its next version, I'll use that one and thus reduce my dependency.

I'm now looking forward to the journey again.