Saturday, November 22, 2008

Tile Fill Addin

I just finished up a second Paint.NET addin. The first is available here.














This addin fills the current image with a tiled version of another image.Just copy an image to the clipboard, create a new image that is larger than the first, and run the addin.
For example, start with something like this:
And the tiled version could look like this:





It can be useful for creating textures, or patterned backgrounds.

Downloads:

Friday, November 21, 2008

Radius Fill Corners Update

I have gotten some feedback from the Paint.NET addin that I recently created. Most of the feedback has been positive, except for strange results occuring when a large radius is selected. This issue is related to how the code determines how to color each pixel for the image. Basically my calculations fall apart if the radius greater than a quarter of the height or width of the image. I knew this would be an issue, but decided not to restrict the radius size because I did not want to limit users who were working with large images.

I now realize that it is better to restrict the radius, but base it on the current image's size. This way you should always get the desired results.

Here are updated links:
source code
addin dll

Sunday, November 9, 2008

New Paint.NET Effect Addin for rounding the corners of an image

After searching through existing Paint.NET effect plugins, I did not find exactly what I was looking for (quick and easy way to round off the corners of an image, like the one below), so I decided to create one.


























With the help of Sepcot's template and tips from BoltBait’s site, the process was not too difficult, and it was an interesting learning experience. Most of the code is pretty similar to other examples, except that I decided to use some WPF libraries to help make the math calculations easier. The source code is available here, or you can just download the DLL for your personal use. Due to the WPF use, the .NET framework 3.5 is required for the effect addin to function. If you need help deploying the addin, there are tips here. Once you have got the addin working, just select the entire image and run the effect with the desired settings.

Tuesday, November 4, 2008

Paint.NET community

I used to spend a lot of time in Adobe Photoshop, but as the years have progressed I have spent more time coding, and less time performing graphics work. This eventually led the purchase price of Photoshop to be unjustifiable considering the limited amount of time I would spend using it. However, I still had a need for the occasional image manipulation, re-sizing, or touch-up. This is when I discovered Paint.NET. It is a great tool for the price (free!) and is very popular (so, you probably already know about it)...


What I had not realized until this week, is how great the community support for Paint.NET is. The application always just did what I wanted, so I had not taken the time to search for tips, tutorials, addins, etc. This week, I had a need to perform some more advanced task in Paint.NET, and found myself missing Photoshop’s capabilities. This lead me to search for some better ideas on how to accomplish the tasks I was working on. I quickly found out that there is a great community surrounding Paint.NET. There are tons of helpful blog posts on the net, and the Paint.NET forums are full of helpful users, tutorials, and free effect addins by developers such as Michael Sepcot, BoltBait, and Ed Harvey. This makes Paint.NET an even more useful product, and I’m looking forward to diving deeper into some of these community resources.

Wednesday, October 1, 2008

Remote Desktop Copy & Paste problem

I am consistently amazed by the wealth of information available in the blogosphere. Here is an example:

I spend a lot of time working in Remote Desktop sessions, and lately I had noticed that quite often I would lose the ability to copy and paste text between my local machine and the Remote Desktop session. This finally became annoying enough that I decided to research the issue. After a quick Google search, the first link took me to a blog post by Pinal Dave that explained how to solve my exact problem. The summary is that the problem can be solved by following these steps in the Remote Desktop session:

1. Open Task Manager
2. Kill the “rdpclip.exe” process
3. Restart the process by using Start >> Run >> rdpclip.exe

This simple solution has saved me a lot of aggravation.

Wednesday, September 24, 2008

XNA Tutorials

I have wanted to experiment with XNA ever since Microsoft released it. Well, over the last few weeks I have finally had enough semi-free time to dive into some of the code. My eventual goal is to create a racing game, so when I discovered that there is a Racing Game Starter Kit I could not help but start by hopping straight into its code. However, I quickly found out that the Starter Kit was going to be overwhelming without picking up some fundamental gaming code knowledge first. The next step was to check out the 2D and 3D Game tutorials. This turned out to be a much better starting point, and I now feel prepared to move on to some more advanced learning. Now, I just have to hope that Xboxs are still available for retail sale by the time I actually complete a real game. :-)





Tuesday, September 9, 2008

The elusive Orca download

Recently, I was having problems with a Windows Installer Merge Module and turned to the web for help. Upon searching, I found a suggestion to use Orca to edit the .msm file. The site simply stated to download Orca from Microsoft, so I searched MSDN for Orca and found that it is only available in the “Windows SDK Components for Windows Installer Developers”. This sounded simple enough, so I downloaded the SDK. After a brief download, I began the installation process and was horrified to find that it was going to require another 2GB+ download for a full installation. I was in a hurry, so I de-deselected the samples and documentation, which brought the install down to a more manageable size.

After the install completed, I happily navigated to Start->Microsoft Windows SDK -> Tools. Hmmm, no Orca in sight... I was just about to bite the bullet and run the full installer when I came across Aaron Stebner's blog post explaining how to get Orca, complete with a direct link for the software.

This saved me a lot of wasted time waiting on the download, just to use one small tool.

Monday, September 8, 2008

Browser shortcuts

Lately I have found myself searching for deals on used parts for our Jeep. As part of this routine, there are several sites that I navigate to, typically opening them in multiple browser tabs. As lazy as it may sound, I got tired of right-clicking items in my favorites list to open the site in a new tab. I decided it would be easier if I had a shortcut for opening all of the sites at once. I know that IE allows you to set multiple home page tabs, but this was not what I wanted because I don’t want the sites to load every time I open a browser.

I decided that a batch file might be an easy solution, and began researching IE’s command line options. While IE, does have a nice selection of options, unfortunately I could not get IE7 or IE8 to yield the results I wanted (the sites were opened in new windows instead of tabs). However, I got exactly what I wanted with Firefox (not a big issue because I routinely switch between the two browsers anyway). I just created the batch file in Notepad and saved it as a .bat file on my desktop. Here are example contents of the file:

cd\"Program Files (x86)\mozilla firefox\"
start firefox.exe http://www.cnn.com http://www.msn.com http://www.yahoo.com


After creating the batch file, it dawned on me that it would be easier to create a copy of my Firefox desktop shortcut, rename it appropriately, and then simply modify the shortcut’s target with the desired sites, as shown here:


Both methods are a great way to quickly navigate to a group of sites.

Thursday, September 4, 2008

Strings....

Today I was doing some research on the performance of strings in .NET, and as I started a Google search, I noticed in the dynamic search results that there are over a million more results for String Theory than String Bikini. There are obviously too many people using the web for serious work, and not enough using it for more perverse reasons. :-) Just some humor, to start the day.

Friday, August 29, 2008

Internet Explorer operation aborted


For several weeks now, I had been experiencing a problem in Internet Explorer (and just had not had time to research, or correct it). Almost every time I navigated to a page on MSDN, the page would display briefly, I would get an “Internet Explorer cannot open the Internet site http://msdn.microsoft.com/xxxx. Operation aborted” message, and then the page would be switched to a navigation error screen. I quickly discovered that pressing the back button would allow the page to display correctly.

Since I work with a lot of Microsoft products, and spend a lot of time on MSDN, this was becoming very annoying. So, today became the today to try and solve the problem. It was occurring on my work PC, but not my home PC. Both are running Windows Vista and IE7. Since one was ok, and the other was not, I thought the problem probably caused by an IE security setting. Rather than digging through IE’s huge list of security options for possible culprits, I decided to search the web to see if anyone else was experiencing the problem.

First, I found this discussion listing a bug in sitemeter.com that had caused issues on a lot of sites; but this bug had already been corrected. The thread also suggested IE addins as a possible cause, but this was not the cause for my issue, either. Another suggestion in the thread was to Reset IE’s options, but this did not fix it for me either. There was also a link to a blog post describing how this error is typically caused by JavaScript manipulation of the HTML DOM. The post stated the problem has been corrected in IE8. Soooooo, I am now running a beta of IE8, which seems to have corrected the problem. Hopefully, it does not introduce new problems!

On my next visit to MSDN, I was promptly greeted with a JavaScript popup message that Microsoft was taking a survey(which was not appearing previously). So, it looks like the survey was the root of my problem, but I have not determined why it occurred on one PC and not the other. At least IE8 seems to have solved it, for now.

Tuesday, August 26, 2008

VMWare Beeps

The other day I was doing some testing in a VMWare virtual machine, and kept getting an annoying beep every time a dialog box was displayed. I changed every sound setting I could find, but could not get rid of the beep. So, it was time to begin google’ing. I found several recommend solutions that involved adding “mks.noBeep = TRUE” to a .ini file, but it seems that the file name, location, and syntax vary slightly depending on your OS and version of VMWare. Ultimately, the easy solution that worked for me was to:

Open Windows Device Manager on the virtual machine.
Go to the View menu and pick “Show hidden devices”.
Go to Non Plug and Play Devices; there is now a Beep item that can be disabled.

Problem solved.

Experts Exchange and Google Cache

I really hate the site experts-exchange.com. It seems that no matter what I am searching for, this site appears in the results list. Just when you think you have found the page with an answer to your question, you find out that you have to buy a membership to see the details of the page. Most of the time, I just skip the search result if it is on experts-exchange, but I occasionally overlook the domain name and find myself frustrated again by the site. I suppose that I should just “suck it up” and buy a membership to the site, but I just can’t bring myself to do it, considering how much information is freely available on the web.

Today, a co-worker shared an interesting trick with me. It doesn’t always work, but most of the time, you can click on Google’s cached version of the page and the answers will appear. Nice!

XML Comments and Nullable data types

I had not worked with XML comments until joining my current employer.  The syntax is pretty simple, and Visual Studio Intellisense handles most of it, but I occasionally find cases where the correct syntax is not obvious.  For example, I needed to change an int variable to a nullable int.  I updated the variable definition to int?, and changed the XML comment <see cref="int"/> to <see cref="int?"/>. This resulted in a compiler warning: “syntactically incorrect cref attribute 'int?'”.  I searched, but could not find a complete listing of the correct syntax for all data types.  Eventually, I found enough examples to learn that nullable data types are listed as Nullable{type name}, like <see cref="Nullable{DateTime}"/>, <see cref="Nullable{Int32}"/>, <see cref="Nullable{Bool}"/>, etc.

Thursday, August 14, 2008

Shortcuts revisited

Two days ago, I posted about some of my favorite keyboard shortcuts. Coincidentally, yesterday I was catching up on my podcast listening, and Hanselminutes #125 is an interview with Saqib Shaikh, a blind developer with Microsoft Consulting Services in the UK. Without sight, Saqib is unable to use the mouse, so he must make extensive use of keyboard shortcuts. I have trouble remembering twenty, or so, shortcuts and can’t imagine what it must be like to need to remember them for almost every task. If you haven’t heard the podcast, check it out. It makes you think about the overall development experience, and you might even pick up a few new shortcuts (how many people knew that Ctrl+Shift+Esc opened the task manager?).

Tuesday, August 12, 2008

Favorite Shortcut Keys

Like most developers, I make extensive use of shortcut keys. However, I seem to only have the mental capacity to remember 20-30 at one time. So, I have a tendency switch them in and out of my regular rotation depending upon what type of project I am working on. Here are the ones that I get the most use out of:

Visual Studio
(Note: some of these are different dependent upon your installation settings)
Control + g : Goto line number
Shift + Alt + Enter : Toggle full screen mode
Control + Space : Launch intellisense
Tab : Accept intellisense selection
F5 : Start debugging
F6 : Build
F10 : Step Over
F11 : Step Into

Windows
Windows Key + f : Search for documents
Windows Key + r : Run
Windows Key + m : Show the desktop (minimize all applications)
Alt + Tab : Toggle between applications

Most applications
Control + s : Save
Control + c : Copy
Control + v : Paste
Control + z : Undo
Control + n : New document
Control + x : Cut
Control + a : Select all
Control + h : Replace
Control + f : Find
Control + Tab - Toggle between documents

Thursday, August 7, 2008

iPhone-a-licious

Up until now, I hadn’t jumped on the iPhone bandwagon. However, yesterday I was listening to an automotive podcast, and they mentioned a new iPhone app called Dynolicious. You install the software on your iPhone, and then place the phone in your car while driving. The software can then be used to calculate the car’s performance statistics, such as 1/4 mile ET’s, 0-60 times, horsepower, etc. While, there are devices (such as the G-Tech) that can calculate these statistics, they can’t be used to make calls, take pictures, play music, surf the web, etc., etc., etc.

Hearing about this software was one of those “blow your mind” moments for me. It is an amazing application of the iPhone’s technology, and also made me think about just how powerful the iPhone is. It will be interesting to see what other creative applications will become available for the phone. Gaming possibilities could be a huge use of the technology. While it’s not exactly a Nintendo Wii, tapping into the accelerometers could lead to some exciting gaming on the small screen. After a quick look at the iPhone app store, and it looks like there are already a few games that utilize the accelerometers, but it could be fascinating to see what else is available in the upcoming months.

It might be time to go phone shopping this weekend….

Tuesday, August 5, 2008

Quantity leads to Quality…

A few days ago Jeff Atwood wrote a blog post about the parallels between software development and the advice for artists in the book “Art & fear”. This quote sums up the basic idea:

“When it comes to software, the same rule applies. If you aren't building, you aren't learning. Rather than agonizing over whether you're building the right thing, just build it. And if that one doesn't work, keep building until you get one that does.”

I found this to be an interesting post because I had recently came to the same conclusion. At my current employer there is a senior developer who is effectively my mentor (we’ll just call him Frank). He insists that all code should follow his standards, which is ok because they are typically good standards; but the whole thing can be a little intimidating. During my first few weeks at the employer, I had a difficult time completing any work because I was constantly worrying about “how would Frank handle this task?”. Once I overcame this, and just let the code flow, I have been much more productive and have learned more by writing the code as opposed to trying to over-analyze the existing code base.

Jeff suggests that the same idea of “Quantity always trumps quality” applies to blogging as well. As an aspiring blogger, I guess I should take that message to heart….

Accessing the Office Ribbon from VBA

Yesterday I received this email from a co-worker (who shall remain anonymous):

1. Open an instance of Word 2007 to find the msoId of the button you’d like to press. You can find this by going to Office Button Word Options Customize to view a list of commands which correspond to buttons.

2. Hover over the name of the command and you’ll see a tooltip; for example, the tooltip for the Save command when selected from the “Popular Commands” list says “Popular Commands Save (FileSave)”. The part in parentheses is the msoId. (Note: You may have to select the name of a tab in the “Choose commands from:” list box to find the button you’re looking for.)

3. In your code, call Word.Application.CommandBars.ExecuteMso with the msoId and you can invoke the button.

Note: The steps above also apply to Excel.

Code Example to demonstrate how to press FileSave in Word 2007

[VBA]
Sub PressThisRibbonBarButton()
On Error Resume Next
If Word.Application.Documents.Count = 0 Then Exit Sub
' Press the Save button Word.Application.CommandBars.ExecuteMso "FileSave"
End Sub


I haven’t worked with the Office 2007 API yet, but I thought this seemed like a good tip that was worth posting here. However, today I was researching something else, and discovered a post on the Interwoven Devnet forums by someone named jny. It looks like the previously mentioned co-worker was trying to pull a fast one, and borrow jny’s post. Anyway, I still thought this was helpful, so thanks to jny from the Interwoven forums for the helpful tip.

Tuesday, July 22, 2008

2010 Camaro

Yesterday Chevrolet revealed the production 2010 Camaro to the public. Video of the event can be seen here. I've been a long time fan of the Camaro, and have had high expectations of the new model ever since the concept was released. Based on the information so far, it appears that the car is going to live up to my high hopes, and beyond. Looks like it's time to start making room in my garage for a new addition!


Thursday, July 3, 2008

Troubleshooting Datasets

Lately I have been working a lot with strongly typed datasets, and have found that they can be difficult to troubleshoot when faced with the dreaded error message:

"Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints."

After some research, I found a blog post by Roy Osherove where he had faced the same problem. In this post, Sanjay lists the following suggestion:

"Essentially, when I see the message above, I check the HasErrors property for each DataTable in the data set and then invoke the GetErrors method on the tables reporting errors. The GetErrors returns a collection of DataRows and you can invoke the .RowError property on the each of the error-stricken rows to find out just exactly what the problem is... "

His suggestion has made troubleshooting much easier. Just disable constraints on the dataset, and then write code to catch the problem once contraints are enabled. Here is a snippet of the version that I came up with:

try


{


    this.EnforceConstraints = true;


}


catch


{


     foreach(DataTable dt in this.Tables)


    {


        if (dt.HasErrors)


        {


            DataRow[] rowErrors = dt.GetErrors();


 


            for (int i = 0; i < rowErrors.GetLength(0); i++)


            {


                System.Windows.Forms.MessageBox.Show(dt.TableName + ": " + rowErrors[i].RowError.ToString());  


            }


        }


    }


}

Tuesday, June 3, 2008

Disabling Word as Outlook's email editor

By default, Microsoft Outlook uses Word to edit email messages. This is a nice feature because it offers enhanced editing capabilities over the basic email editor. However, if you are using an under-powered machine like I had at my last employer, you really want to cut down on memory usage and don’t want Word running just so you can send a quick email. When this is the case, you can stop Outlook from using Word to edit emails, by opening Tools -> Options, clicking the “Mail Format” tab, and deselecting the option “Use Microsoft Office Word 2003 to edit e-mail messages”.

This isn’t a revolutionary tip, but it’s something that I hadn’t thought to look for and would have been very useful when I was stuck on an old machine.

Formatting my MP3 player

My current MP3 player is a SanDisk Sansa c250. It’s not a fancy as some of the more expensive units, but overall it’s very nice unit for the price. Recently I needed to transfer 1GB of data between to pc’s and didn’t have a flash drive handy; so I just copied the data to my Sansa and used it for the transfer. This seemed like a good idea at the time, but when I tried to delete the data from the MP3 player, I was faced the the error message “Folder cannot be deleted because it is protected.”. After some experimenting, it looks like the Sansa will not let you delete a folder if it contains data. This wouldn’t be a big deal, except that the data I had transferred contained hundreds of folders. There was no way I was going to dig through all of these folders to delete the files. Being a developer, I decided to automate the process and write a .NET application that would traverse the folder structure of the unit, and delete all of the files.

I threw together a quick app, tested it on some other folders, and was off to the races (or so I thought). I attempted to select the folder on the device (using the .NET FolderBrowserDialog), and Windows Vista gave me the error message “The folder cannot be used”.

I had never tried to access a portable device programmatically, so I wasn’t sure what the cause might be. Google’ing didn’t help. Next, I did some debugging to find out what the referenced file path was so I could just hard code it. The path turned out to be in Temporary Internet Files. I’m not quite sure what this means, but obviously Windows doesn’t treat this device like a normal drive.

It was time to take a step back and think about what I was trying to accomplish. I wanted everything deleted from the device, except for my music. But, all my MP3’s are backed up on several devices. I took a quick look at the options on the Sansa, and it turns on there was a format device. This quickly wiped out everything, and then I simply copied the music back to the device.

I guess sometimes, it pays to approach a problem from a different perspective.

Thursday, May 22, 2008

Saving money on gas

Like a lot of people, I have a lengthy commute to work. As the price of gasoline continues to rise I have been thinking a lot about ways to save money on fuel. My wife and I have been carpooling to work, which means we can drive either her vehicle or mine. Hers is an SUV, and mine is something a little sportier. Mine gets better MPG, but runs on premium so it costs more to fill up. Neither one is cheap to drive, so we have thought about buying a third vehicle to be our work commuter. But, what would be the best option? We have considered buying a new compact, a new hybrid, a used sedan, or possibly buying a used diesel car and converting it to run on waste vegetable oil. Each of these choices has a wide variety of costs involved and offers different benefits. To weigh out the options, I put together an Excel spreadsheet that compares the cost of fuel for each vehicle, and how long it would take to recoup the costs of purchasing another vehicle. I thought spreadsheet might be helpful for others, so it is available for download here.




Just fill in the shaded cells with your vehicle choices, and compare the results. The other cells contain formulas that can be edited if you want to make the calculations based on different assumptions.


There are other expenses to consider such as insurance, and maintenance, but I think this is a good start.

Monday, May 5, 2008

C# Code snippets

While making the transition from a VB.NET developer to C#, I noticed that there are far fewer out of the box code snippets for C# than VB.NET in Visual Studio 2005. A quick Google search for C# snippets revealed that Microsoft offers a separate download for C# snippets which matches all of the ones available for VB.NET. This was great news, but unfortunately the download link appears to be broken at the moment. I'm sure this will be fixed soon but in case it's not, Jeff Atwood has posted the snippets and helpful install info here.

Friday, May 2, 2008

New Job!

This week I started a new job with a software devlopment company (as opposed to the previous financial services company). This means that I will be working less with Microsft CRM, so there will be less blog posts about it, but I will continue to post information about other technologies. This week has been spent becoming more proficient in C# (instead of VB.NET which I had been focusing on) and learning about custom controls from Developer Express. There will be more posts once I get into the groove of the job.

Wednesday, April 16, 2008

Helpful CRM links for developers

Here is a list of helpful sites if you are new to customizing Microsoft CRM. There are tons more, but these are the ones that I find myself referencing most often.

The Microsoft CRM Dev center @ MSDN:
http://msdn2.microsoft.com/en-us/dynamics/crm/default.aspx
Tons of great info here, especially in the forums.

Microsoft Dynamics CustomerSource
http://www.microsoft.com/dynamics/customersource.mspx
This is the place for technical support (assuming you have an active subscription).

Microsoft Dynamics CRM Team Blog
http://blogs.msdn.com/crm/
Posts on new features and functionality from the CRM developers themselves. There are also guest bloggers offering up their expertise.

Sonoma Partners
http://www.sonomapartners.com/
These guys literally wrote the bookon CRM customization.

The MscrmGuy’s blog
http://blogs.msdn.com/jstraumann/
This blog has a lot of good info. If you search it for HOL (hands on lab) there are several good tutorials that cover the basics of CRM customization.

SSW’s Rules to better Microsoft CRM
http://www.ssw.com.au/ssw/Standards/Rules/RulestoBetterMicrosoftCRM.aspx
SSW is an Australian consulting service. Their Rules are always helpful, and there are other technologies in the series (such as Reporting Services).

Stunnware
http://www.stunnware.com/
This site has been very helpful. The Javascript library (found in the blog section) is especially useful.

Ronald Lemmen’s blog
http://ronaldlemmen.blogspot.com/
Ronald is a CRM consultant who really knows his stuff. His blog is full of valuable information and he also posts frequently on the Microsoft forums.

Friday, April 11, 2008

Using JavaScript to access the CRM offline database

The stunnware site has lots of great CRM JavaScript examples. One of them shows how to use JavaScript to access the CRM database. The same technique can be used to access the local offline database by changing the connection string to: "Provider=SQLOLEDB;Server=.\\CRM;Database=MSCRM_MSDE;Integrated Security=sspi".

Here is an example:


var accountGuid;

accountGuid = document.getElementById("your fieldname here");


if (IsOnline())

{

// write code for online version here.

}

else

{

var iCount = 0;

var connection = new ActiveXObject("ADODB.Connection");

var connectionString = "Provider=SQLOLEDB;Server=.\\CRM;Database=MSCRM_MSDE;Integrated Security=sspi";

connection.Open(connectionString);

var query = "SELECT count(*) FROM AccountBase WHERE AccountID='" + accountGuid.value + "'";

var rs = new ActiveXObject("ADODB.Recordset");

rs.Open(query, connection, /*adOpenKeyset*/1, /*adLockPessimistic*/2);

rs.moveFirst();

while (!rs.eof) {

iCount = rs.Fields(0).Value;

rs.moveNext();

}

connection.Close();


if (iCount > 0 ) {

//do something useful here

}

else {

//do something else here

}

}

Restoring the CRM database

I’m a developer, not a DBA (even though my employer seems to think I should do both). So when it comes to something outside the realm of writing queries, creating tables, etc., I sometimes have to fumble my way through it. For example, I recently needed to do a point in time restore on our CRM database. I kept getting an error message about not being able to perform the task because the database was in use. This was on our dev version of CRM that I knew no one was using. Finally, I figured out that the IIS service (or just the related app pools) needed to be stopped on the CRM server because it was hitting the database.

Doh!

Thursday, April 10, 2008

Remote Desktop console session

Ever try to use Remote Desktop to access a Windows server, and have access denied because all available Terminal Server sessions were in use? Running RDP with the "/console" parameter will allow one more user to connect by using the console session. Just run "mstsc.exe /console" from the command prompt, or set up a shortcut.

Tuesday, April 8, 2008

Troubleshooting errors when going offline in CRM

Ever seen the error message, "The XML passed to the platform is not well-formed XML", when attempting to take the CRM Outlook client offline?

You can track down the problem by performing a platform trace on the PC that is receiving the error. Microsoft provides info on how to accomplish this here.

After enabling tracing, you can review the log file for the cause of the error. The log can be quite lengthy, so search for words such as “Error” or “Exception”. Often the cause is someone such as myself, has attempted to customize the system in an un-supported manner (one example can be seen here).

Monday, April 7, 2008

Enabling Activities on Custom Entities after they have been created.

This post relates to CRM 3.0 (haven’t been fortunate enough to upgrade yet). There is a great post here by Aaron Elder about how to enable Notes on custom entities. Activities also cannot be enabled after the entity is created, but the post does not explain how to add them.

I was able to take the procedure outlined by Aaron and modify it to enable Activities instead of Notes. Note – this is completely un-supported by Microsoft. The technique has not caused any problems on my test system, but results may vary. Use at your own risk!

The first step is to create a stored procedure using the following script.

Second, paste the name of your custom entity (where is says “placeEntityNameHere”) in the SQL script below, and execute it. This should create all of the needed system relationships between the custom entity and the Activity entities (Email, Task, etc.).


-- Define the Entity to Update


DECLARE @entityname varchar(64);


SET @entityname = 'placeEntityNameHere';


-- Define a GUID for the relationship

-- This is defined here and passed in so that we can access the relationship later


-- and apply special options if needed



DECLARE @TEMP_RelationshipId uniqueidentifier;


-- Add the ActivityPointer Relationship


SET @TEMP_RelationshipId = NEWID();


EXEC dbo.AddCrmRelationship @entityname, 'ActivityPointer', '_ActivityPointers', @TEMP_RelationshipId;


-- Add the Appointment Relationship



SET @TEMP_RelationshipId = NEWID();


EXEC dbo.AddCrmRelationship @entityname, 'Appointment', '_Appointments', @TEMP_RelationshipId;


-- Add the Email Relationship


SET @TEMP_RelationshipId = NEWID();


EXEC dbo.AddCrmRelationship @entityname, 'Email', '_Emails', @TEMP_RelationshipId;


-- Add the Fax Relationship


SET @TEMP_RelationshipId = NEWID();


EXEC dbo.AddCrmRelationship @entityname, 'Fax', '_Faxes', @TEMP_RelationshipId;


-- Add the Letter Relationship



SET @TEMP_RelationshipId = NEWID();


EXEC dbo.AddCrmRelationship @entityname, 'Letter', '_Letters', @TEMP_RelationshipId;


-- Add the PhoneCall Relationship


SET @TEMP_RelationshipId = NEWID();


EXEC dbo.AddCrmRelationship @entityname, 'PhoneCall', '_PhoneCalls', @TEMP_RelationshipId;


-- Add the ServiceAppointment Relationship


SET @TEMP_RelationshipId = NEWID();


EXEC dbo.AddCrmRelationship @entityname, 'ServiceAppointment', '_ServiceAppointments', @TEMP_RelationshipId;


-- Add the Task Relationship


SET @TEMP_RelationshipId = NEWID();


EXEC dbo.AddCrmRelationship @entityname, 'Task', '_Tasks', @TEMP_RelationshipId;

go


The final step is to add and delete a new custom entity (or use the app provided at Aaron’s post to handle the update). This step causes CRM to re-process all of its relationships, and forces our manual updates to take affect.

Aaron’s example for Notes also required exporting the entity’s customizations and modifying the XML. This is not required for Activities because no changes are made the entity’s form.

Friday, April 4, 2008

Increasing the length of a CRM 3.0 custom entity nvarchar field

Recently, our CRM users asked that the length of a custom field be increased. This seemed like a simple task, however, after a nvarchar field has been created, CRM gives you the ability to decrease the size, but not increase it. To add to the problem, the field was the entity’s primary attribute so it could not be deleted. So, we were left with a few options.
A. Create a new field with the new length, transfer all existing data to the new field, and hide the existing field from users.
B. Back up all data, delete the entity, create a new one, and import all of the archived data.
C. Hack the system by going around CRM’s user interface and modifying the field length.

Option C would give us what we were really looking for (and it sounded like the most fun), so I decided to give it a try.

Here are the steps that were attempted (Warning this is un-supported by Microsoft, and is listed here for educational purposes only! It could seriously harm your CRM installation.):

1. Export the entity’s customizations as an XML file.
2. Open the file in your favorite editor and search for the field’s name.
3. Assuming you only work in one language, there are two values that will need to be modified. They are Length and maxlength. Change maxlength to the new value and Length to two times the new value.

<attribute PhysicalName="Ffs_fieldtomodify">

<Type>nvarchar</Type>

<Length>150</Length>

<ValidForCreateApi>1</ValidForCreateApi>

<ValidForUpdateApi>1</ValidForUpdateApi>

<ValidForReadApi>1</ValidForReadApi>

<IsCustomField>1</IsCustomField>

<DisplayMask>PrimaryNameValidForAdvancedFindValidForFormValidForGrid</DisplayMask>

<Description>The name of the custom entity.</Description>

</attribute>


<field name="ffs_fieldtomodify" requiredlevel="required" maxlength="75" format="text">

<displaynames>

<displayname description="Field To Modify" languagecode="1033" />

</displaynames>

</field>


4. Save the XML, import it into CRM, and publish customizations. (At this point, CRM will show the new length but the SQL tables have not been updated. So, if you try to save a value that is too long you will get a SQL exception message. To solve this, continue on.)

5. Modify the field’s length in the ExtensionBase table of the _MSCRM database. Two views will also need to be updated. The views are and Filtered. You can script the view as “Alter to a New Query Editor window”, and then run the script un-modified. This will not change the definition of the view, but will cause it to be re-compiled and pick up the new field length.

6. To get the field length to display correctly in the CRM metadata browser, update the Attribute table in the _METABASE. You can find the correct row by searching for the field’s name. The length needs to be set to two times the new length (the same value as was entered in the XML file).

select * from attribute where [name] = 'ffs_fieldtomodify'



After all of these steps, everything appeared to be working perfectly. Until, I tried to take my CRM client offline. It gave the error message, “The XML passed to the platform is not well-formed XML”. A CRM client trace revealed this:

>Crm Exception Message: Updating Ffs_temp.ffs_fieldtomodify.Length but it's not valid for update. Original value:150. New value:250., ErrorCode: -2147220991

After thinking about this for awhile, I decided to cancel plan C and go back to plan B. It was an interesting challenge; but in the end it was safer and easier to just delete and re-create the entity. However, if you do not use the CRM offline client, you MIGHT be able modify the field lengths without any problems.

Monday, March 31, 2008

Team Foundation Server's workspace machine names

After the machine name change mentioned in an earlier post, I also found that Visual Studio could no longer find the projects saved in my local Team Foundation Server workspace. Thanks to Google and this post by Buck Hodges, I was able quickly correct the problem by updating the machine name stored by TFS.

Tuesday, March 25, 2008

CRM Offline Client Connection String

Recently I was getting a SQL connection error when attempting to go offline in the CRM Outlook client (3.0). After scratching my head for little bit trying to figure out a possible cause, it dawned on me. Earlier in the week, our network administrator had changed my pc's machine name (long story). The client must not be able to find the local database due to the machine name change. I popped open regedit and sure enough there were three references to local databases with the incorrect machine name. In the unlikely event that this happens to someone else, they are located in HKEY_CURRENT_USER\Software\Microsoft\MSCRMClient and the keys are:

database
Provider=SQLOLEDB;Data Source=machinename\CRM;Initial Catalog=MSCRM_MSDE;Integrated Security=SSPI

metabase
Provider=SQLOLEDB;Data Source=machinename\CRM;Initial Catalog=METABASE;Integrated Security=SSPI

OfflineQueueDBConnection
Provider=SQLOLEDB;Data Source=machinename\CRM;Initial Catalog=MSCRM_MSDE;Integrated Security=SSPI

Just correct the machine name for each, and everything should be back to normal.
Off course, the usual cautions apply about being careful when modifying the registry.

Tuesday, March 18, 2008

Welcome!

Hello and welcome to my new blog. I dabble in a variety of technologies ranging from ASP.NET, AJAX, SQL, Java, C#, VB.NET, Oracle, Sharepoint, Microsoft CRM, Photoshop, and 3D CAD software (such as SolidWorks). As you can see that is a long list. As such, I don’t consider myself an expert in any one area. This means that each day presents new challenges. My intention for this blog is to list the tidbits of useful information that I learn during daily activities, in hopes that it will be helpful to other developers out there. If nothing else, it gives me a place to refer back to when my brain runs out of storage space and I can’t remember how something was accomplished.

I may also occasionally post more personal information about my hobbies such as family, pets, music, nature, drag racing, and Jeep rides.

Stay tuned for more info in these areas.