# Sunday, 02 August 2009
I hate SharePoint sometimes. It's powerful, and strong, and free(ish) and does an amazing job. If you just want to install it and use it, there's really nothing to complain about. But it's greatest strength, and my greatest user-upper of swearwords, is that you can program against it. With each release, whatever I swore about last time is magically fixed (RunWithElevatedPrivileges FTW) but a whole pile of new misery sneaks in out of nowhere. (Well, and CAML remains, but I guess we can't do anything about that.) It's usually related to security, but not always, and the thing is that debugging it is always like surgery with oven mitts on.

I had a situation where I wanted to find the item you just added. Took a little searching, but I found it:

query.Query = "<Where><Eq><FieldRef Name='" & list.Fields.Item("Created By").InternalName & _
                "'/><Value Type='User'>" & SPContext.Current.Web.CurrentUser.Name & "</Value></Eq></Where>" & _
            "<OrderBy><FieldRef Name='Created' Ascending='FALSE' /></OrderBy>"
items = list.GetItems(query)
The first entry in items is the thing you most recently added. OK, fine. But we have event receivers on these lists, and they go off asynchronously. That means that right after you saved an item, while the receiver is still processing, the item isn't returned by the query.

Well that made me grumpy but I understood, so I made a loop, and if the first entry in items wasn't recent enough (say, in the last two minutes) I would have a little sleep and then ask again. But no matter how long I waited (even 20 minutes!) this code never would find the item. Oh, there was swearing, you can be sure of that.

I decided that SharePoint must be caching the query results. But searching for things like "SPListItemCollection cache" just got me helpful tips on caching these results myself, some thread safety issues, and the like. For example, this MSDN article says

You might try to increase performance and memory usage by caching SPListItemCollection objects that are returned from queries. In general, this is a good practice; however, the SPListItemCollection object contains an embedded SPWeb object that is not thread safe and should not be cached.

Does that match up well with what I am seeing - always the identical results from this query-in-a-loop even though I know the underlying list has changed while the loop was running? It does not.

Then I found two blog entries by Jeff Crossett: first the complaint, and then the solution. He's right. And when I implemented his hack:

' use a random value in query so we don't get cached.
randomValue = generator.Next(100, 1000000000)
query.Query = "<Where><And><Eq><FieldRef Name='" & list.Fields.Item("Created By").InternalName & _
                "'/><Value Type='User'>" & SPContext.Current.Web.CurrentUser.Name & "</Value></Eq><Neq>" & _
                "<FieldRef Name='Title' /><Value Type='Text'>" & randomValue.ToString & "</Value>" & _
                "</Neq></And></Where>" & _
            "<OrderBy><FieldRef Name='Created' Ascending='FALSE' /></OrderBy>"
items = list.GetItems(query)

We all lived happily ever after. Well, until the next WTF that SharePoint throws my way. I am doing amazing things with this product. My customers would pay more for their software if SharePoint didn't exist. But man, sometimes it is HARD.

Kate

Sunday, 02 August 2009 08:26:35 (Eastern Daylight Time, UTC-04:00)  #    
# Friday, 31 July 2009
It's time to start talking about TechDays (because among other things, I'm talking at TechDays :-).)



Joey has the details including a list of sessions. I'm in the Core Fundamentals and Best Practices track in Toronto, delivering these two talks:

Day 1, Session 1:
Tips and Tricks for Visual Studio

This session enhances your experience with Visual Studio. Keyboard shortcuts, macros, layouts, fonts, tools, and external utilities are all very powerful and underused features of Visual Studio. This session makes you more productive in Visual Studio. Bring your pen and pad because you'll definitely want to take notes!

Day 2, Session 4:
Database Change Management with Team System

If you develop database enabled applications on top of SQL Server, you owe it to yourself to considering doing it better with Visual Studio Team System. In this session, you’ll learn about changes to how the product works under the covers and what that means to you. Then, you’ll learn how to use the product to design, build, and deploy your databases to development, test, and production environments -- all with purpose and method instead of the more traditional madness that can be found in many shops in the wild.

I am a huge Data Dude fan, which makes the second session a natural, and as for the first one, I'm one of those people. When I present I'm nice and careful with lots of mouse clicking so everyone can see what I'm doing. But when I'm sitting down to code, I get a pretty constant chorus of "hey, how did you do that so fast?". Come and see how :-).

Kate

Friday, 31 July 2009 22:15:47 (Eastern Daylight Time, UTC-04:00)  #    
# Wednesday, 29 July 2009
I didn't even know there was a Visual Studio Project Team blog, but the entries lately sure have been C++ relevant:
Brian Tyler says "Our areas of responsibility are those surrounding projects and solutions in Visual Studio - specifically the C++, C# and VB project systems - but we're involved in other code bases in those areas as well." and explains that he's going to start the blog with these C++ topics because the conversion of the VC++ project system from VCBuild to MSBuild was a major effort in VS 2010.

I'm really happy about the VC directories thing. It made moving projects from one machine to another very brittle that things like which version of a header file you got were machine-specific instead of project specific. The blog as a whole is a must-read if you're going to do any C++ work in Dev10.

Kate

Wednesday, 29 July 2009 22:05:26 (Eastern Daylight Time, UTC-04:00)  #    
# Monday, 27 July 2009
If you want to start talking to developers about your technology, you're hardly the first. Whether you want to talk about the tech your company builds, or just tech that you like to use, or something a little in between (I don't make Microsoft software, or sell it, but since it's the platform I consult and mentor on, I have a financial interest in people using the tech I talk about) there is someone out there who is in the same boat as you.

Chris Heilmann, a web developer evangelist working for the Yahoo Developer Network, has written a handbook for developer evangelists. Trust me, what this handbook has to say is not Yahoo-specific, or web-specific, at all. It is developer-specific in parts, since demos and such are vital to us. Definitely worth a read - and if you want to speak on our tech, start doing some of this.

Kate

Monday, 27 July 2009 17:32:24 (Eastern Daylight Time, UTC-04:00)  #    
# Saturday, 25 July 2009
A client asked me to help recently with a small mystery. They had a database provided by a customer and they'd been asked to import the contents into the tables used by their own product. One of the tables had a BLOB column and from context they were quite sure it was used to hold scans of documents. There was even a "filename" column and a "filetype" column that suggested very strongly the scans were stored as TIFFs.

It had taken a while to find code to read the blobs, and when they ran it, the resulting file was rejected as not being a valid TIFF. They weren't sure if they were handling the blobs wrongly, if the data was encrypted, or if it was some other image format (they had tried PDF and GIF already.) In a highly enjoyable two hours, here's what I did:
  • Found short (ten lines including initialization and cleanup) code to read one blob in VB6 and save it to disk.
  • Found the TIFF format details, looked in the resulting file with notepad and confirmed it didn't start either II or MM and so wasn't a TIFF.
  • Looked at a few other file formats but wasn't really gaining any knowledge, just ruling things out that you could rule out by renaming and double clicking, then having the file rejected by the app that tried to open it.
  • Discovered Marco Pontello's absolutely cool File Identifier, TrID, and downloaded it
  • Removed the extension from what had been test.tif, pointed TrID at it, and was told 100% it was a zip file. Duh, the file started PK, I might have guessed that one.
  • Renamed it to test.zip, unzipped it by hand -- ooh, it IS a zip! -- and was rewarded with file.txt for my trouble
  • Looked at file.txt in notepad and noticed that it was full of binary-looking gibberish, but it DID start with II
  • Hand renamed file.txt to file.tif and double-clicked it
  • Presto! A scan of a document!
I left my client to write the code that did all the blobs, including unzipping them and renaming (every single blog contained a zip which  contained a TIFF renamed to file.txt and no, I don't know why) from within a quickly written importer application. The big mystery was solved. Thanks, Marco!

Kate

Saturday, 25 July 2009 12:13:01 (Eastern Daylight Time, UTC-04:00)  #    
# Thursday, 23 July 2009

I admit it, I read my referrer logs. I want to see what kinds of searches bring people here, or who is linking to me. I think a lot of the single word searches (women, or shirt, or december) are blog spammers looking for posts to spam on. And some are clearly my name, names of my friends or folks I blog about, conferences I'm speaking at. The majority is things I know about, things for which I want to be your expert source: /clr:pure, windows 7 taskbar, uac manifest file, marshal_as and so on. Yay.

But this one was just plain odd: c++ standard limerick. Really? So I repeated the search, and found this:

When writing a specialization,
be careful about its location;
or to make it compile
will be such a trial
as to kindle its self-immolation.

OK, it's not spaced like that in the standard. But who'da thunk it?

Kate

Thursday, 23 July 2009 19:48:20 (Eastern Daylight Time, UTC-04:00)  #    
# Tuesday, 21 July 2009

Want to go to PDC but not sure you can afford it? How would this work for you: a trip to PDC including flights, hotel, and conference admission?

That's the grand prize in the INETA Component Code Challenge. Write an app (web, client, whatever) that uses at least two different components (a grid and a chart? a PDF creator and a calendar? a report and a spreadsheet? You decide.) from the sponsors.

Try it! And maybe see you in LA!

Kate

Tuesday, 21 July 2009 19:40:35 (Eastern Daylight Time, UTC-04:00)  #    
# Sunday, 19 July 2009

Here's another tip from Habib on debugging. If you have a particular screen you want to bring up, and it takes a lot of clicking and selecting to bring it up, why not just set a breakpoint and then bring it up by constructing and calling it with the immediate window?

Habib's video features a WPF application, and the constructor takes no parameters, but you could use this for Windows Forms and you could pass through whatever parameters you needed to. A very handy tip - any language, any kind of client application.

Sunday, 19 July 2009 19:35:20 (Eastern Daylight Time, UTC-04:00)  #