Dell Latitude D830 laptops have 4GB memory cap, but I’ve found a way to squeeze 8GB of RAM in there (thanks to some helpful comments from others on the web). This is an unsupported configuration, but its working great!
8GB gives me lots more breathing room for running virtual machines, especially useful for testing SharePoint 2010 in a virtual environment. My old laptop may be around a while yet!
If you have a D830 and want to try this, here’s how I did it:
- You must be running an OS that supports more than 4GB. 64-bit Vista, 64-bit Windows 7, 64-bit Windows Server 2008 or Windows Server 2008 R2.
- Upgrade the BIOS to A13 (download it from Dell). I haven’t tried A14 (the latest BIOS version), but I read reports that this only works with A13.
- Install a matching pair of 4GB SODIMM DDR2 667 chips. I’m using GSKILL chips I picked up from NewEgg for around $265.
- When you reboot the first time, the BIOS will take a while to run through, checking out the new memory. Verify the new memory, and your system should recognize 8GB when it comes up. After the first boot, BIOS boots quickly.
I’m running Windows 7 64-bit and Windows Server 2008 R2, booting to a VHD. No host OS on my PC, just a VHD on my C: drive. Sweet!!
Here’s the memory I ordered from NewEgg:
http://www.newegg.com/Product/Product.aspx?Item=N82E16820231210
Enjoy!
Categories: Uncategorized
There are some sample .Net functions out there to pull a list of distinct items from an ADO.Net DataTable, but none of them I found take advantage of LINQ. So I thought I would post something I came up with to fill the gap.
In the code sample below, the goal is to pull a list of distinct values from a single column in a DataTable. There are a few ways to approach this, depending on the end-game. I listed 4 options, 2 with LINQ syntax and their Lambda expression twins.
// —————————————————————–
// Build a list DataTable to test
// —————————————————————–
DataTable tbl = new DataTable();
tbl.Columns.Add(“Title”, typeof(string));
for (int i = 1; i <= 100; i++)
{
// Add 1 row
DataRow row1 = tbl.NewRow();
row1["Title"] = string.Format(“Title {0}”, i);
tbl.Rows.Add(row1);
// Add duplicate row
DataRow row2 = tbl.NewRow();
row2["Title"] = string.Format(“Title {0}”, i);
tbl.Rows.Add(row2);
// Add null row for testing
DataRow row3 = tbl.NewRow();
row3["Title"] = DBNull.Value;
tbl.Rows.Add(row3);
}
// —————————————————————–
// All four of these examples yield the same results
// Each returns a list of 100 distinct rows
// Pick your poison!
// —————————————————————–
// Sample 1
// —————————————————————–
// Get a distinct list of titles
// Linq syntax against the DataTable using
// This is functionally the same as the 2nd example
List<string> distinctTitles2 =
(from r in
(IEnumerable<DataRow>)tbl.AsEnumerable()
where !string.IsNullOrEmpty(r.Field<string>(“Title”))
select r.Field<string>(“Title”)).Distinct().ToList();
// Sample 2
// —————————————————————–
// Get a distinct list of titles
// Lambda expression against the DataTable
// This is functionally the same as the 1st example
List<string> distinctTitles1 = ((IEnumerable<DataRow>)tbl.AsEnumerable())
.Select<DataRow, string>(r => r.Field<string>(“Title”))
.Where(title => !string.IsNullOrEmpty(title))
.Distinct().ToList();
// Sample 3
// —————————————————————–
// Get a distinct list of titles
// On this one, I’m using the tbl.Select() method to get an array of DataRows matching filter criteria
// Linq expression is then used against the DataRow array to get distinct titles
// This is functionally the same as the 4th example
List<string> distinctTitles4 =
(from r in
tbl.Select(“Title IS NOT NULL And TRIM(Title) <> ””)
select r.Field<string>(“Title”))
.Distinct().ToList();
// Sample 4
// —————————————————————–
// Get a distinct list of title
// On this one, I’m using the tbl.Select() method to get an array of DataRows matching filter criteria
// Lambda expression against the DataRow array to get distinct titles
// This is functionally the same as the 3rd example
List<string> distinctTitles3 = tbl.Select(“Title IS NOT NULL And TRIM(Title) <> ””)
.Select(r => r.Field<string>(“Title”))
.Distinct().ToList();
Enjoy!
Categories: .Net · ADO.Net · C# · Linq
Problem
Encountering an error when trying to instantiate COM objects through Primarary Interop Assemblies (PIA’s) or Runtime Callable Wrappers (RCW’s) created using the TLBIMP.exe tool.
When calling the object for the first time, you encounter the following COM exception:
Unable to cast COM object of type ‘xxx to interface type ‘xxx’. This operation failed because the QueryInterface call on the COM component for the interface with IID ‘{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}’ failed due to the following error: No such interface supported (Exception from HRESULT: 0×80004002 (E_NOINTERFACE)).
You are likely to encounter this problem when developing ASP.Net applications, Windows Console applications, or Windows Services. You are unlikely to experience this issue when developing Windows Forms applications.
Solution
The problem is that you are attempting to call Single-Threaded Apartment (STA) model COM components from an Multi-Threaded Apartment (MTA) thread. The primary thread of Windows Forms applications are STA threads, so the components work fine there. Most other project types, including Console applications and Windows Service applications are run on an MTA thread by default. When you attempt to instantiate the an STA component, you will get the ubiquitous error described above.
You might try calling System.Threading.Thread.CurrentThread.SetApartmentState(ApartmentState.STA), but this won’t work. You cannot change the thread execution model on a running thread.
To fix the problem, you can set the thread execution type on the main application thread before it is started, but this is not optimal. It is better to set the threading model specifically for the portion of code that needs it.
A better solution is to spin up a new thread for the job at hand, and set the thread execution state on the new thread before executing it. There are a few different methods to accomplish this depending on what you’re trying to accomplish. Here’s one to get you started:
using System.Threading;
...
// Setup an object to host the thread entry point
// Start a process on an MTA thread
MyThreadedJob jobHost = new MyThreadedJob(jobId);
Thread t = new Thread(new ThreadStart(MyThreadedJob.Execute));
t.SetApartmentState(ApartmentState.MTA);
// Start the thread
t.Start();
// Wait for thread to complete (optional)
t.Join();
More Gory Details
For more of the gory details and differences between threading models in Windows and COM, you can start here.
Categories: .Net · C# · COM Interop · Threading
I want to get a reference to a SPList object associated with a given list url. This method works with any of the url’s associated with the list, including view page url’s, or list form url’s.
This should be much easier to achieve by using the object model, in my opinion. String parsing of the url is not my favorite, but I couldn’t find a better way to accomplish it.
If you know of an easier way to accomplish this, please leave me a comment. Otherwise, you can steal this from me, if you want it!
/// <summary>
/// Gets an SPList based on the url to the list
/// </summary>
/// <param name="listUrl">Full url to the list</param>
/// <returns>SPList object, null if list is not found</returns>
public SPList GetListByUrl(string listUrl)
{
SPList list = null;
try
{
using (SPSite site = new SPSite(listUrl))
{
if (site != null)
{
// Strip off the site url, leaving the rest
// We'll use this to open the web
string webUrl = listUrl.Substring(site.Url.Length);
// Strip off anything after /forms/
int formsPos = webUrl.IndexOf("/forms/", 0, StringComparison.InvariantCultureIgnoreCase);
if (formsPos >= 0)
{
webUrl = webUrl.Substring(0, webUrl.LastIndexOf('/', formsPos));
}
// Strip off anything after /lists/
int listPos = webUrl.IndexOf("/lists/", 0, StringComparison.InvariantCultureIgnoreCase);
if (listPos >= 0)
{
// Must be a custom list
// Strip off anything after /lists/
webUrl = webUrl.Substring(0, webUrl.LastIndexOf('/', listPos));
}
else
{
// No lists, must be a document library.
// Strip off the document library name
webUrl = webUrl.Substring(0, webUrl.LastIndexOf('/'));
}
// Get the web site
using (SPWeb web = site.OpenWeb(webUrl))
{
if (web != null)
{
// Initialize the web (avoids COM exceptions)
string title = web.Title;
// Strip off the relative list Url
// Form the full path to the list
//string relativeListUrl = listUrl.Substring(web.Url.Length);
//string url = SPUrlUtility.CombineUrl(web.Url, relativeListUrl);
// Get the list
list = web.GetList(listUrl);
}
}
}
}
}
catch { }
return list;
}
Enjoy!
Categories: .Net · C# · MOSS 2007 · SharePoint
I want to thank everyone who attended my session on SharePoint Workflow with Visual Studio at our TechFest event yesterday. Please feel free to post any comments (good or bad) about my presentation or the event.
Demo source code is posted on Nakido until the Techfest site is updated with session content.
SharePoint WorkFlow with Visual Studio – Downloads
SharePoint WorkFlow with Visual Studio – References
Categories: .Net · C# · MOSS 2007 · Microsoft Office · SharePoint · Visual Studio · WSS 3.0 · Workflow
Problem
SharePoint 2007 Web Front End (WFE) servers crashing repeatedly. Environment is SharePoint 2007 (MOSS Enterprise) 64-bit running on Windows Server 2008 Standard. Server was crashing repeatedly with CPU spiking to 100%, blue screen, and server rebooting itself. System log showing BugCheck event (1000) entry with code 0×0000001d:
The computer has rebooted from a bugcheck. The bugcheck was: 0×000000d1 (0xfffff9802ea0ef50, 0×0000000000000002, 0×0000000000000000, 0xfffffa6004e06ed9). A dump was saved in: C:\Windows\MEMORY.DMP.
Resolution
After a lot of troubleshooting, it turns out it was Trend Micro Common Firewall Driver (Trend Micro OfficeScan Client 8.0). When we disabled the firewall, problem resolved.
Categories: MOSS 2007 · SharePoint · WSS 3.0 · Windows Server 2008
Problem:
I’m creating a SharePoint Sequential Workflow using Visual Studio 2008 (SP1) with .Net 3.5 SP1 installed. This is on a Windows 2003 R2 VPC with SharePoint 2007 (MOSS Enterprise) installed on the local machine for development. A Collaboration Portal is installed on a web site with host headers (portal) assigned to port 80.
When I create a new workflow project, the wizard asks for a path to the SharePoint site. I type in my url (http://portal in my case), and the project wizard fails, saying “SharePoint server not installed. Please run Microsoft Office SharePoint Server 2007 setup.“
I’m logged in as the farm administrator. I thought it might be a permissions issue (my farm admin doesn’t have full rights on the domain), so I went back and gave it full Domain Admin rights in case that was the problem. Still failing!!
What the hell?
Resolution:
It turns out that the wizard does some funny business behind the scenes, calling the database directly. When I give my development account (farm admin) account full rights (dbo) to the SharePoint content database for my portal site, bingo! Works like a champ.
After only an hour or two spinning my wheels. Sigh….
Categories: .Net · C# · MOSS 2007 · SharePoint · Visual Studio · Workflow
Building a SharePoint 2007 workflow using WSPBuilder and Visual Studio 2008. Love, love, love the WSPBuilder tool, but the workflow templates could use some work. Ran into this one today…
Problem
I was receiving “Failed on Start (retrying)” errors. SharePoint logs showed “The workflow failed validation” exceptions. This usually means a problem with the .rules files associated with a Declarative Rule Condition.
I changed my While activities to use code conditions instead, and the problem went away. But I really wanted to find the source of the issue. After much trial and error and fruitless searches on the web, I finally found it. Turns out, it was a missing import target declaration in the .csproj file created by WSPBuilder when I created a workflow project using the “WSPBuilder Workflow with Workflow” project template.
Resolution
To fix the problem, opened up the project file and added the missing import target line (in green), below. Evidently, this line tells studio to include the .rules in the assembly.
<Import Project=”$(MSBuildBinPath)\Microsoft.CSharp.targets” />
<Import Project=”$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.5\Workflow.Targets” />
Reopened the project, recompile, build wsp, redeploy. Bingo! Now my workflow works with Declarative Rule Conditions, as it should!
Credits
Thanks to Greg G’s post here that pointed me in the right direction.
Categories: SharePoint · Visual Studio · WSPBuilder · Workflow
Ok, this is painfully easy. Setup a Network Place in Windows Explorer, browse to the web site or folder in question, right-click -> Properties.
Duh!! Sometimes the solution is literally staring you in the face! Thanks to Kelly Ballard for pointing this one out.
Categories: SharePoint
The hardest part about this (by far) is figuring out how to publish the page after you’ve made your changes. Every time I need to do it, I have to dig up some old code.
Thought I’d blog it this time, to make it easier on myself next time around.
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
...
using (SPSite site = new SPSite("http://portal"))
{
SPWeb web = site.RootWeb;
// Check to ensure the web has publishing turned on
if (!PublishingWeb.IsPublishingWeb(web))
{
throw new ApplicationException("Web does not have publishing enabled");
}
// Get a reference to the publishing web and publishing site
PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(web);
PublishingSite pubSite = new PublishingSite(web.Site);
// Get page layout from the page layouts collection
PageLayoutCollection siteLayouts = pubSite.GetPageLayouts(false);
PageLayout myLayout = siteLayouts["/_catalogs/masterpage/MyLayout.aspx"];
// Get a reference to a publishing page
PublishingPageCollection pages = pubWeb.GetPublishingPages();
PublishingPage page = pages["pages/default.aspx"];
// Check out the list item as needed
bool forceCheckout = page.ListItem.ParentList.ForceCheckout;
if (forceCheckout)
{
// Is the page checked out?
if (page.ListItem.File.CheckedOutBy != null)
{
// Throw an exception if the page is checked out
string pageCheckedOut = string.Format("Page {0} is checked out by {1}", page.Url, page.ListItem.File.CheckedOutBy);
throw new SPException(pageCheckedOut);
}
// Check out the page
page.CheckOut();
}
// Change the page layout
page.Layout= myLayout;
// Update the page and check in changes
page.Update();
// Publish the page
// This handles the page checkin and publishing the draft
ApprovePublishingPage(page, "Modified page layout");
}
/// <summary>
/// Approves changes to a publishing page
/// </summary>
/// <param name="page">PublishingPage with changes to be published</param>
/// <param name="comment">Comment associated with the change</param>
public void ApprovePublishingPage(PublishingPage page, string comment)
{
// Check in the page if required
SPFile pageFile = page.ListItem.File;
if (pageFile.Level == SPFileLevel.Checkout)
{
pageFile.CheckIn(comment, SPCheckinType.MajorCheckIn);
}
// Skip these steps if the parent list doesn't support moderation
if (page.ListItem.ParentList.EnableModeration)
{
// If page is in "pending" status, approve it
SPModerationInformation modInfo = page.ListItem.ModerationInformation;
if (modInfo.Status == SPModerationStatusType.Pending)
{
pageFile.Approve(comment);
}
// If page is in draft status, publish it
if (modInfo.Status == SPModerationStatusType.Draft)
{
pageFile.Publish(comment);
}
}
}
Enjoy!
Categories: C# · MOSS 2007 · SharePoint