This is the last of the InterOp posts. Just a brief word on the “why”, since I keep getting that question
I would not recommend InterOp as a first choice for writing a feature, or probably even a second choice. However, there are certain IT shops that have a fear of 3rd party components (they’ve been burned before, or have NIH syndrome, etc) or a mandate against using OSS. Writing our own spell checker or rich text editor can be very time consuming, so if InterOp is on the table, it’s a viable alternative to writing it yourself. However, InterOp can be a deployment headache, unless you know that every user will have Office, and will have the same version. Okay, on with the show.
I was tasked with putting a rich text editor into a WinForms app, to handle the editing of email body templates. I was actually pretty shocked to find that there aren’t really any decent open source or free RTEs for WinForms (at least that I could find). I briefly toyed with putting TinyMCE into a webbrowser control, but after reading a few blog posts, I decided to give InterOp a whirl and use the Trident (MSHTML) engine to be a rich text editor.
The idea is basically to use a WebBrowser control, set the ‘document’ in that control to ‘edit mode’ and voila, HTML rich text editor. Then you can program buttons to send ‘commands’ to the document, such as ‘bold’, ‘italic’, ‘create link’, etc. I won’t post a code snippet here, because it’s a relatively big hunk of code. Instead, I created an open source project called YARTE, or “Yet Another Rich Text Editor”. I’ve tried to make it easy enough to use right out of the box, but extensible enough to add in custom functionality when necessary.
So that wraps it up for InterOp, for now. These InterOp posts were born out of necessity and experience. Not because I’m an InterOp nut or a WinForms fan (because I am neither), but in the hopes that I can help developers in similar situations to the one I was in.
If you’re like me and you don’t have an IT department for your home network with rigorous security standards, you need to be even more vigilant when it comes to security, because you have no one to blame but yourself.
I’ve been using Secunia PSI (Personal Software Inspector) for some time now, and I’ve found it to be an excellent product for identifying out-of-date and insecure programs. Not only does it identify programs that need updated, but also how to update them, how to patch them, and even specific forum threads if I have a problem getting the update to take. It handles insecure, end-of-life, and even browser security. In “advanced” mode, I can see at a glance what needs updating, how serious the threat is, links to patches/updates, and links to the forum thread:
(Note that screenshot was taken before I had run Windows Update on a new box).
It’s always surprising to me what Secunia is able to find that I wouldn’t have found on my own. For instance, PhpStorm (an excellent PHP IDE, by the way) comes with a copy of Java (JRE) for convenience, but the JRE gets updated frequently and PhpStorm doesn’t update the JRE on its own. I had no idea the JRE was there until Secunia found it and told me it was out of date and a 4/5 threat rating. Simple solution: delete the outdated JRE and PhpStorm was able to find the updated version on my system with no problem.
Problem 22 was pretty straightforward; the problem description lays out the algorithm. One elegant piece of Linq was: word.Sum(c => c – (‘A’ – 1)), which sums up each letter score of the word nice and compactly.
Problem 23 – given the upper and lower limits of all possible abundant sums, this problem was, again, straightforward given the algorithm description. The toughest part was getting it performant, which is why I used a lookup collection for the IsAbundant method. At this point, my MathHelper class is coming in very handy, so I may just release it as its own project one day (though I’m sure there are many other equally good Math libraries for .NET).
Problem 24 – I did solve this problem, but my solution was not fast enough. Once I got the answer, I looked to see how other Eulers were doing it. So, for this class, I have both my solution and the more correct, “Fast” solution in the code. I think later on, I eventually created a permutation class, so I may need to revisit this problem with that class.
Problem 25 – Another easy one with BigInteger. I used a KeyValuePair because I was curious to see the actual number in the sequence, not just the index.
Problem 26 – This one took a lot of research and thinking. I spent a lot time reading about Cyclic numbers and Primitive roots. The solution feels like kinda a cheat to me, but I really don’t see any way around it since “No simple general formula to compute primitive roots modulo n is known”. Fortunately, Wikipedia lists just enough of them for me to solve the problem.
Problem 27 – I came up with a handy Quadratic class for this problem. I think in this case, the problem sounds pretty complex, but I broke it down into individual parts the best I could, and everything fit pretty well together. This is also a good strategy if you are having performance issues, as it will be easier for a profiler to point out where exactly the bottleneck is (hint: it’s almost never where you think).
As always, you can view my code at CodePlex – feel free to submit criticisms/comments/patches there, or use the framework for your own Project Euler solution.
This is a much shorter example of using InterOp. In this case, the requirement was to send an email via Outlook so that the user would have the email in their “sent” folder, as well as receive any “replies” at their address.
Ultimately, I ended up using Exchange services, but here’s my first attempt to fulfill the requirements using InterOp:
Very, very simple. Just drop this class in and call the SendEmail method on it. Note that depending on security setup, the user may see a “warning” message with a skippable countdown. Also note that you really shouldn’t use this for sending more than 1 or 2 messages at a time, especially if that countdown appears, because it will be a very annoying user experience.