Saturday, October 03, 2009
Since I spent so many hours on this, I figured I'll post this to remember...
When copying SPFiles from one doc library to another, a few things to keep in mind:
- SPFileVersion will not let you get a reference to the SPFile (per MSDN) so don't do this: SPWeb.GetFile(SPFileVersion.Url) because SPFile.Item will be null
- SPFileVersionCollection (SPFile.Versions) is not in sync with SPListItemVersionCollection. SPFile.Versions actually does NOT return the current version. So, iterate through all SPFileVersions and use SPFile.Versions.GetVersionFromLabel(SPListItemVersion.VersionLabel)
- To keep the check in comments with each version, use the following method to add a file to the target library: SPList.RootFolder.Files.Add(url,bytes,true,SPFileVersion.CheckInComments,false)
- Iterate through versions via a SortedDictionary by Created date property -- the goal is to use SPListItemVersion information to update the newly created SPFile meta data.
- SPFile.Item.Update() will create a new version; UpdateOverwriteVersion() will not; use the latter with SPFileVersions; use the former when adding a new SPListItem, to set values and incremenet versions.
- Upload the current version of SPFile outside the SPListItemVersions loop
- Be mindful that SPListItemVersion returns Modified and Created values as non-local time, so convert it.
Consider disabling item events during copy.
A good reference:
http://www.k2distillery.com/2007/10/copy-version-history-with_5.html
Wednesday, September 30, 2009
SubText is my choice blogging app for this Blog. It's .Net based, open source, and just nifty. Yesterday I had a cow with it though. The contact form refused to send notification e-mails. No error was generated. That was confusing, discouraging and frustrating -- since potential clients contact me via this blog.
There were only two places that I knew of where changes could be made to the e-mail delivery mechanism. web.config file to set the smtp server and the contact form code to execute the delivery.
The mystery deepened when I could setup SubText on a couple of spare servers. Contact form worked just fine. What gives?
Well apparently during setup SubText requests an OPTIONAL e-mail address when setting up a user account for a blog. That e-mail address is used to deliver e-mail messages to from the contact form. Here all this time I was thinking it was the HostEmailAddress in web.config that these messages would be routed to.
After setting the e-mail address in the subtext_Config table in SQL. Messages started to work. Oh how magical!
All this to say, as a developer, I was just given a glimpse at what users may sometimes experience when I fail to clearly establish expectations for the operation of a system. Lesson learned!
Friday, September 18, 2009
So what happens when you change your ONLY admin password for one of your critical VMware images at 2am during a caffeine induced and chocolate supported coding nights? And then forget it?
Enter:CD-konboot-v1.1-2in1 [site] [ISO]
A. Download the CD-ISO
B. Assign the ISO as a CD ROM to the troubled VMWare instance, boot.
C. Hit ESC during Vmware boot, choose to boot from CD
D. Let it do its thing
E. Login with administrator user -- password can be anything -- but once logged in reset the administrator account password
Continue coding.
Tuesday, May 26, 2009
When changed through the API or ONET.XML, the following is true:
Site Master Page is set via SPWeb.CustomMasterUrl (Publishing Pages use this)
System Master Page is set via SPWeb.MasterUrl (Forms and Views pages use this)
Try it at home (the code below doesn't work with sub sites):
In Visual Studio, create a new C# Windows Project, Console Application. Add a reference to the Microsoft.SharePoint namespace. In the Program.cs file, paste this just inside the static void Main(string[] args):
try
{
string siteURL = "http://changethistoyoursite";
string newCustomMasterUrl = "/_catalogs/masterpage/???.master"; //replace ??? with your master
string newMasterUrl = "/_catalogs/masterpage/???.master"; //replace ??? with your master
using (SPSite site = new SPSite(siteURL))
{
using (SPWeb web = site.OpenWeb())
{
string relativeUrl = (site.ServerRelativeUrl);
if (relativeUrl == @"/")
relativeUrl = "";
Console.WriteLine("Current settings: ");
Console.WriteLine("MasterUrl:" + web.MasterUrl);
Console.WriteLine("CustomMasterUrl: " + web.CustomMasterUrl);
Console.WriteLine();
Console.WriteLine("Changing to: ");
Console.WriteLine("MasterUrl:" + relativeUrl + newMasterUrl);
Console.WriteLine("CustomMasterUrl: " + relativeUrl + newCustomMasterUrl);
web.MasterUrl = relativeUrl + newMasterUrl;
web.CustomMasterUrl = relativeUrl + newCustomMasterUrl;
web.Update();
Console.WriteLine("Changed.");
Console.WriteLine();
Console.WriteLine("Changed to: ");
Console.WriteLine("MasterUrl:" + web.MasterUrl);
Console.WriteLine("CustomMasterUrl:" + web.CustomMasterUrl);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine();
Console.WriteLine("Press ENTER to exit.");
Console.ReadKey();
Reference:
http://msdn.microsoft.com/en-us/library/bb687712.aspx
Saturday, May 09, 2009
"The crawler could not communicate with the server. Check that the server is available and that the firewall access is configured correctly.."
This error sometimes shows up in the Crawl Log in the SSP.
The issue in my case was a custom database that the crawler account did not have access to. Of course an easy way to figure this out is to login to the website as the crawler account -- to see what it sees... It worked. A quick adjustment of SQL permissions and voila, we're crawling again.
Pesky little thing. MS introduced a loopback security check for websites accessed locally on the server.
To fix:http://support.microsoft.com/kb/896861
Click Start, click Run, type regedit, and then click OK.
In Registry Editor, locate and then click the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
Right-click Lsa, point to New, and then click DWORD Value.
Type DisableLoopbackCheck, and then press ENTER.
Right-click DisableLoopbackCheck, and then click Modify.
In the Value data box, type 1, and then click OK.
Quit Registry Editor, and then restart your computer.
Monday, April 27, 2009
Here is an error that is somewhat puzzling. But the solution was simple enough.
When converting an existing Microsoft Virtual PC instance to WMWare, I got this error:
Unable to load the source virtual machine or image. The file might be corrupt, or of an unsupported format.

The Log Info link directed me to C:\Windows\Temp\vmware-temp\
Opened vmware-converter-0.log file to find this:
[#3] [2009-04-27 19:28:38.626 'App' 5696 verbose] [,0] DISKLIB-LIB : Failed to open 'D:\VPC\MOSSDEV\CommonStore.vhd' with flags 0x15 (The system cannot find the file specified).
The VPC to be converted references a VHD file in a different folder than where the .VMC file is. Apparently the wizard is looking for .VHD files in the same folder, regardless of the actual setting...
A quick edit of the VPC settings (remove or move the VHD file) and all is well.
Sunday, November 02, 2008
Wednesday, October 29, 2008
When deploying custom SPOneTimeSchedule job definitions sometimes the timer service (OWSTIMER.EXE) just sorta sits there. Your job definition is created, but isn't executed. It will most likely eventually run, but I have better things to do than sit around wait for it. Setting the time for the job in the past seems to move things along faster.
// Create new job
CustomJob MyJob = new CustomJob(Constants.JOB_NAME, webApp, properties.Definition.DisplayName);
MyJob.Title = Constants.JOB_TITLE;
// Set up the job to run once
MyJob.Schedule = new SPOneTimeSchedule(DateTime.Now.AddHours(-4));
MyJob.Update();
Monday, September 29, 2008
Do you know the difference between .Net CLR versions? Is 2.0.50727.1433 newere than 2.0.50727.42? What's the difference?
Here is a nice reference:
http://alt.pluralsight.com/wiki/default.aspx/Keith/DotnetVersionWiki.html