I have been really slow to start using Generics and I have been even slow about writing my own methods that make use of Generics in C# (.NET 2.0 or newer). Today I realized exactly how easy it is to write a very generic method and have it use any type you want it to. This is of course the beauty of Generics. Without rambling anymore about my reluctance, here is how you do it.
Let's assume that you are writing a bunch of methods that are all the same except they take different type of objects or even primitives as parameters.
Here is a simple example of what you could write for each type you want:
public static void AreEqual(int a, int b)
{
return a.Equals(b);
}
public static void AreEqual(string a, string b)
{
return a.Equals(b);
}
This is trivial example where the logic of the code is VERY simple. Imagine if that was a complex algorithm like searching or sorting. Would you really want to have that logic duplicated for each type that you want to work with. Of course not. Again, the prime reason for using Generics.
Here is what you could write using Generics (Write once for ALL types):
public static void AreEqual<T>(T a, T b)
{
return a.Equals(b);
}
You'll notice it looks very similar to the non-generic code except that it uses T instead of a type that you are used to. T is a special placeholder for what type the calling code wants it to be.
Here is how you would call the non-generic code:
bool retval = AreEqual(1, 0);
bool retval = AreEqual("xxx", "yyy");
Here is how you could call the generic code:
bool retval = AreEqual<int>(1,0);
bool retval = AreEqual<string>("xxx", "yyy");
The syntax is a little strange at first in the end I find it very easy to use. It helped me to think of it as a runtime search and replace of 'T' with the type I currently want to use.
Friday, July 18, 2008
Can't publish Visual Studio 2005 Web Site because access denied error
If you get an error like "Access to the path 'C:\Documents and Settings\username\Local Settings\Temp\~6d4\bin\App_WebReferences.compiled' is denied." when you use the VS2005 | Build menu | Publish Web Site and your site impersonates a user this may help.
Open up Windows Explorer and navigate to the Temp directory specified in the path. In this example, go to "C:\Documents and Settings\usb00528\Local Settings\Temp". Now right-click on the Temp directory and go to the security tab. Add the user that you are impersonating (usually specified in you web.config) and give the user Read and Write permissions. Now re-try the Publish Web Site menu item and it should publish successfully now. Yeah!
Wednesday, July 16, 2008
Check Version of OVSD web-api.jar
When you use the HP OpenView Service Desk (OVSD) web-api.jar to write programs that access the OVSD server you should use the same version that the server is using. The obvious question soon becomes, how do I know what version of the web-api.jar do I have.
To determine the version of your web-api.jar do the following:
1. Locate the web-api.jar file you are compiling against in your program.
2. Open a command prompt and cd to the directory that contains your web-api.jar, so that it is your current directory.
3. Now type (or copy and paste) java -classpath web-api.jar com.hp.ifc.sys.AppVersionInfo
This should return something like:
Acronym: SD
Version: 4.5.0588.1706 (SP17)
Company: hp OpenView Copyright:
Copyright (c) 2004 Hewlett-Packard Development Company, L.P. All Rights Reserved. Description: service desk is a family member of the hp OpenView suite. ProductID: B4321 ProductName: hp OpenView service desk
If you don't know what version your server is running the easiest way to tell is to open your client software and look at the start up splash page.
If you want a more detailed answer like the above info, you can do the following:
1. Execute C:\Program Files\Hewlett-Packard\OpenView\service desk 4.5\client\bin\sd_version.bat by double clicking it.
This should return the same thing as you got for the web-api.jar info.
Tuesday, July 15, 2008
Lookout for Outlook 2007
For those of you that have used Lookout for Outlook 2003 and earlier and have upgraded to Outlook 2007, you have no doubt figured out that Lookout 1.3 does not run or if you are running Lookout 1.2 that it doesn't even load. The reason is that Lookout is looking for a particular COM file that is now the wrong name even though it does actually work with it.
First thing I recommend is downloading the latest release (there will not be anymore because technically MS owns it now and this software is not longer supported by either the original author or MS). One place you can download Lookout 1.3 from is:
http://www.majorgeeks.com/Lookout_d4808.html
To the rescue comes a couple of people. The author says you can just rename the dll it is looking for so that it can find it. That runs the chance of messing up other things if you ask me. However, you can try it if you prefer that solution:
http://www.belshe.com/2007/12/06/how-to-install-lookout-on-outlook-2007/
Another techie figured out the dll that does the dll check and tricked into always being true. Pretty clever. You can download the patched file and replace the one that is installed with Lookout 1.3.
http://www.wirwar.com/blog/2008/01/22/search-e-mail-at-lightspeed-using-lookout-with-outlook-2007/
Apparently there is an issue with dates when .NET Framework 2.0 is installed. Here is a description and fix to the issue.
http://ewbi.blogs.com/develops/2006/04/outlook_lookout.html
You can fix this by checking out the following link on how to patch it Lookout for this issue.
http://www.scw.us/win/FixingLookout/
If you want more background on the issues, etc there is actually a lot of good stuff on the issues at:
http://www.lockergnome.com/windows/2004/07/26/microsoft-lookout-for-outlook/
As you can see Lookout is limited life left in it. Though I imagine clever folks will continue to patch it until a product that is good enough comes along.
First thing I recommend is downloading the latest release (there will not be anymore because technically MS owns it now and this software is not longer supported by either the original author or MS). One place you can download Lookout 1.3 from is:
http://www.majorgeeks.com/Lookout_d4808.html
To the rescue comes a couple of people. The author says you can just rename the dll it is looking for so that it can find it. That runs the chance of messing up other things if you ask me. However, you can try it if you prefer that solution:
http://www.belshe.com/2007/12/06/how-to-install-lookout-on-outlook-2007/
Another techie figured out the dll that does the dll check and tricked into always being true. Pretty clever. You can download the patched file and replace the one that is installed with Lookout 1.3.
http://www.wirwar.com/blog/2008/01/22/search-e-mail-at-lightspeed-using-lookout-with-outlook-2007/
Apparently there is an issue with dates when .NET Framework 2.0 is installed. Here is a description and fix to the issue.
http://ewbi.blogs.com/develops/2006/04/outlook_lookout.html
You can fix this by checking out the following link on how to patch it Lookout for this issue.
http://www.scw.us/win/FixingLookout/
If you want more background on the issues, etc there is actually a lot of good stuff on the issues at:
http://www.lockergnome.com/windows/2004/07/26/microsoft-lookout-for-outlook/
As you can see Lookout is limited life left in it. Though I imagine clever folks will continue to patch it until a product that is good enough comes along.
Outlook launch error regarding MSOC.DLL
I just upgraded from Outlook 2003 to Outlook 2007. I opened Outlook 2007 and I get a message that says
"MAPI was unable to load the information service msoc.dll. Be sure the service is correctly installed and configured."
I had to be quick to get it because it oddly disappears and it is not logged to the Windows event log.
If you are getting this message it is likely I would say that you are using "Microsoft Office Outlook Connector for IBM Lotus Domino" plug-in for Outlook 2003. When you upgrade to Outlook 2007, the plug-in stays installed. When you open Outlook it tries to connect to the Domino server as it has always, and in Outlook 2007 this plug-in no longer works and appears to not be supported or have a likely shot of being upgraded to work with Outlook 2007.
Make sure Outlook 2007 is quit and not hidden process is running (can use Task Manager to check for process called OUTLOOK.EXE). Do yourself a favor, go to Add / Remove Programs and remove "Microsoft Office Outlook Connector for IBM Lotus Domino". It does NOT work in Outlook 2007.This should uninstall the plug-in from Outlook I think.
If that doesn't work you can do what I did before I uninstalled it. I just removed the plug-in from Outlook 2007 using Start Menu | Control Panel | Mail and then click the Email Accounts... button. This will take you to a tabbed window. Make sure the E-mail tab is selected. In the list of connections you should see something that indicates the Domino connection (sorry already deleted it so I can't reference the exact text). Highlight it and click the Remove button. Close the Windows and restart Outlook.
This is in no way part of the solution, but I wanted to share it anyway. Here is some sample code that I toyed with to attempt to write my own .PST reader, but ended up with the same error when my code ran, and forced me to figure out what the real problem was (see above of course).
using System.Runtime.InteropServices;
using Outlook = Microsoft.Office.Interop.Outlook;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Outlook.Application app = new Outlook.ApplicationClass();
Outlook.NameSpace NS = app.GetNamespace("MAPI");
Outlook.MAPIFolder objFolder =
NS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.MailItem objMail;
Outlook.Items oItems;
oItems = objFolder.Items;
try
{
for (int i = 1; i < objFolder.Items.Count; i++)
{
objMail = (Outlook.MailItem)oItems[i];
MessageBox.Show(objMail.Body.ToString());
}
}
catch (COMException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
NS.Logoff();
objFolder = null;
objMail = null;
app = null;
}
}
}
Monday, July 14, 2008
Unlocking Windows Desktop Search
If you have Windows Desktop Search installed by your corporate IT or the like, they may have locked it so that you can't tell Windows Desktop Search where (file system paths) and what (file extensions) to index. Thanks to one of my sys admin friends (I won't name any names in case he wasn't supposed to tell me this) I can now tell Windows Desktop Search to search where and what I want it to, and thus make it a little more useful.
The restriction is created using a group policy. The group policy can be removed by deleting two keys from the registry found at:
HKLM\Software\Policies\Microsoft\Windows\Windows Search
This should make the group policy for these items to not configured. You should also be able to just set the values to 0 to have a similar effect.
In case you need to restore, or just want to know what you are deleting a head of time, here is an export of the registry entries prior to the change.
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search]
"PreventUsingAdvancedIndexingOptions"=dword:00000001
"PreventModifyingIndexedLocations"=dword:00000001
The restriction is created using a group policy. The group policy can be removed by deleting two keys from the registry found at:
HKLM\Software\Policies\Microsoft\Windows\Windows Search
This should make the group policy for these items to not configured. You should also be able to just set the values to 0 to have a similar effect.
In case you need to restore, or just want to know what you are deleting a head of time, here is an export of the registry entries prior to the change.
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search]
"PreventUsingAdvancedIndexingOptions"=dword:00000001
"PreventModifyingIndexedLocations"=dword:00000001
Format GridView column header text automatically
Here is a snippet of code that I use for with GridViews to convert Database column names to User friendly text. This comes in handy when I am too lazy or not enough time to go through and change the names of the automatically generated column names that are shown as the column headers in a GridView. This also makes it easy to keep the text looking nice even when the columns change and the columns get regenerated. I realize there are some downsides, like slight performance hit, etc, but for departmental solutions were development time is the most precious thing I have, this is a time saver.
This method assumes that your column names are in Pascal Case. This means that all columns start with a capital letter, and that each word in the column name starts with a capital as well. Everything else in between should be lowercase. An example of this is FirstName or LastName or or ZipCode or DisplayName.
// assumes that source text is in PascalCase and that it
// should be changed to more human readable capitalization.
// i.e. BrentVermilion is in pascal case and a more human
// readable form is Brent Vermilion
public static string MakeUserFriendly(string text)
{
This method assumes that your column names are in Pascal Case. This means that all columns start with a capital letter, and that each word in the column name starts with a capital as well. Everything else in between should be lowercase. An example of this is FirstName or LastName or or ZipCode or DisplayName.
// assumes that source text is in PascalCase and that it
// should be changed to more human readable capitalization.
// i.e. BrentVermilion is in pascal case and a more human
// readable form is Brent Vermilion
public static string MakeUserFriendly(string text)
{
StringBuilder sb = new StringBuilder(text);
int insertAdjustment=0;
char ch;
for (int i = 0; i < text.Length; i++ )
{
// AND the previous letter wasn't an Uppercase letter
if (!char.IsUpper(text[i - 1]))
{
// insert a space before the uppercase letter
sb.Insert(i + insertAdjustment, ' ');
char ch;
for (int i = 0; i < text.Length; i++ )
{
// AND the previous letter wasn't an Uppercase letter
if (!char.IsUpper(text[i - 1]))
{
// insert a space before the uppercase letter
sb.Insert(i + insertAdjustment, ' ');
// we need to keep track of how many space we have added
// so we know what the adjusted index to insert at will be
insertAdjustment++;
}
// so we know what the adjusted index to insert at will be
insertAdjustment++;
}
}
return sb.ToString();
}
return sb.ToString();
}
One place you can call this method is in the PageLoad event.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// convert cryptic Pascal Case header column text
// (what the user sees) to User friendly readable text
for (int i = 0; i < myGridView.Columns.Count; i++)
{
myGridView.Columns[i].HeaderText =
MakeUserFriendly(myGridView.Columns[i].HeaderText);
}
}
}
// (what the user sees) to User friendly readable text
for (int i = 0; i < myGridView.Columns.Count; i++)
{
myGridView.Columns[i].HeaderText =
MakeUserFriendly(myGridView.Columns[i].HeaderText);
}
}
}
Subscribe to:
Posts (Atom)