January 22, 2008
vhshost.exe Mystery
Have you been wondering what the vshost.exe file is for? You'll notice this when you start working with Visual Studio 2005. Basically this is the file that is used by VS 2005 to optimise the debugging performance and should not be deployed in production environment.
dtemp has a good outline here:
http://blogs.msdn.com/dtemp/archive/2004/08/17/215764.aspx
Posted by vhadiant at 09:22 PM | Comments (0) | TrackBack
February 05, 2007
Battling VSTO's SerializationException: Type is not resolved for ...
I've just won half a day battle with VSTO's SerializationException. The actual error turned out to be a red-herring, that was what giving me such a grief (not to mention that this is my first day of cutting down my daily coffee intake)
This is the background of the problem as I posted in MSDN forum earlier today:
I'm currently at loss with this current problem. This is the scenario: I have several c# libraries (all strongly named) in my solution. This solution processes data and serialised the result into a MS SQL Server database.
From my VSTO project (using VB.NET) I tried to access the database and deserialise the result back into my object. Everything works until the moment of deserialisation where I get the SerializationException: Type is not resolved for member ...
I have a test project that accesses the database and deserialise my object and it is working perfectly fine, so I'm certain that the serialisation/deserialisation code is working, but just not within VSTO framework.
Now this error is suspiciously related to way VSTO is run by Excel. I spent ages trying to figure out what went wrong since all the assemblies are available and loaded properly. I even tried strong naming all the assemblies.
I almost gave up before fortunately helped arrived from this thread. Basically it gave me the idea of hooking to AppDomain's AssemblyResolve event to find out if there is a problem. Yes there was, but in a completely different assembly than the one that was in the exception message!
Apparently this is a common problem when .NET is hosted by an external application. Often the virtual machine has difficulties loading assemblies. For example your project requires assembly A and A requires assembly B, normally you only need to add reference to A and the virtual machine will be able to load assembly B automatically, but not with VSTO. The solution is to strong reference (add the reference from Visual Studio's add reference dialog box) the assemblies, and voila, everything works ... half a day later.
Posted by vhadiant at 08:53 PM | Comments (0) | TrackBack
October 12, 2006
BackgroundWorker class
This .NET 2.0 new class is one of the most usefull class in .NET 2.0 threading class library. This simplifies creating a new background thread from your WinForm application. Here you can safely update the GUI control without marshalling and it also provide you with built in cancellation method.
A good article about this class is available here. Don't I wish that this class is available in .NET 1.x, this would have saved me heaps of ground work in GUI projects.
Posted by vhadiant at 06:12 PM | Comments (0) | TrackBack
February 27, 2006
Removing PromptChar on Infragistics' cell based editing
If you are using Infragistics' UltraWinGrid and trying to fiddle with the cell based editor, you'll quickly find out that you can't remove the annoying default PromptChar ('_'). I don't know what the standard is in the US but here in Australia we never use that '_'.
So if you're thinking to use UltraMaskedEdit and remove the PromptChar you'll be sorely disappointed because it doesn't work. The trick is to set both the UltraMaskedEdit's PromptChar and the grid's column's PromptChar to '_'. Thanks to Infragistic's tech support, I probably wouldn't have found this solution myself.
For example:
ultraGrid1.DisplayLayout.Bands[0].Columns[0].PromptChar=' ';
and
this.ultraMaskedEdit1.Name = "ultraMaskedEdit1";
this.ultraMaskedEdit1.PromptChar = ' ';
Posted by vhadiant at 08:04 AM | Comments (0) | TrackBack
December 19, 2005
From DataReader to DataSet
Often you need to transform your DataReader into a DataSet. If that sounds weird or why should I just use SqlDataAdapter, the main problem is that I'm using strongly typed DataSet. SqlDataAdapter doesn't like the strongly typed data set. If your stored procedure is returning multiple tables, it will force it to be stored in Table1, Table2 ...So a quick play with SqlDataReader gives me what I wanted. Here is the code snippet:
public void ExecuteQuery(DataTable[] dataTables) { try { _cmd.Connection.Open(); SqlDataReader sdr = _cmd.ExecuteReader(); int tableNum = 0; while (sdr.Read()) { DataRow dr = dataTables[tableNum].NewRow(); for (int i = 0; i < sdr.FieldCount; i++) { string name = sdr.GetName(i); dr[name] = sdr.GetValue(i); } dataTables[tableNum].Rows.Add(dr); } while (sdr.NextResult()) { tableNum++; while (sdr.Read()) { DataRow dr = dataTables[tableNum].NewRow(); for (int i = 0; i < sdr.FieldCount; i++) { string name = sdr.GetName(i); dr[name] = sdr.GetValue(i); } dataTables[tableNum].Rows.Add(dr); } } } finally { _cmd.Connection.Close(); } }
To the method you simply pass the order of the DataTable with the order of the SELECT statement in your stored procedure.
Posted by vhadiant at 06:16 PM | TrackBack
November 06, 2005
Home Page in MSHelp 2
So I want to use MS Help 2 and I downloaded the really useful VSHIK 2003. This tool will help you create Microsoft Help 2.x within your Visual Studio IDE.
Now everything seems self explanatory, even defining index is nice and easy. However I got stumped in creating the "Home Page" for the help file. By default it uses whatever IE use as its homepage, so whenever I open the help file it opens SMH. It's not very intuitive but this is how you should do it.
1. Create a "Keyword Index" file and named it NamedURLIndex.HxK
2. Modify the content of the file so it should look like this:
<?xml version="1.0"?>
<!DOCTYPE HelpIndex SYSTEM "ms-help://hx/resources/HelpIndex.DTD">
<HelpIndex DTDVersion="1.0" Name="NamedURLIndex">
<!-- Insert keywords here -->
</HelpIndex>
3. The only change is the Name attribute.
4. Open the HTML file that we want to use as the Home Page
5. Add this tag inside the <HEAD> tag:
<xml>
<MSHelp:Keyword Index="NamedURLIndex" Term="HomePage"/>
<MSHelp:Keyword Index="NamedURLIndex" Term="DefaultPage"/>
</xml>
6. Open the Help project properties, go to the "Navigation" tab and select the correct Named URL Index file.
7. Build and run the project. That should work
Posted by vhadiant at 08:29 PM | TrackBack
October 29, 2005
Fixing ASP.NET
My ASP.NET bombed out yesterday. Despite rebooting my box several times (something that I really really ... really hate doing) it wouldn't start.
After a frustrating a couple of hours trying to fix it, a colleague mentioned that I probably should re-run the aspnet_regiis.exe tool, which pretty much re-install ASP.NET to IIS. Suffice to say it pretty much fixed the problem. Heh ...
This is also usefull if you are running multiple version of .NET and need to rebind different ASP.NET to IIS. This tool is located in your Framework directory ie: C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322
Posted by vhadiant at 09:14 AM | Comments (0) | TrackBack
October 17, 2005
Overflow checking in .NET
An interesting information that took me a while to find out. I had some overflow problem earlier today and I expected that .NET will throw an overflow exception (of some sort) whe this happen, but by default .NET does not turn on overflow checking for performance reasons. It will only throw an exception if it happen on constants expressions. So how do I turn on overflow checking? You can turn this on from Visual Studio.NET option or you can use the checked/unchecked keywords.
Posted by vhadiant at 10:29 PM | Comments (0) | TrackBack
October 06, 2005
XPath and default namespace in .NET
I've been having a problem with running XPath query on XML document with a default namespace. It has something to do with NamespaceManager and prefixing all your XPath with the prefix that you set in the NamespaceManager. For example, if you have XML document as follow:
<MyXml xmlns="http://tempuri.org/myxml">
<name>Victor Hadianto</name>
</MyXml>
When you run a simple XPath such as /MyXml/name it will fail. Why? Because of the default namespace, .NET doesn't seem to know that if you don't prefix your query just use the default namespace. For example:
XmlNode node = xmlDoc.SelectSingleNode(@"/MyXml/name");
// node is null
The way to fix this is as follow:
// First create the NamespaceManager
XmlNamespaceManager nm = new XmlNamespaceManager(xmlDoc.NameTable);
// You have to create a prefix with the same URI as your default xmlns
nm.AddNamespace("bc", "http://tempuri.org/myxml");
// Now you can run the query
XmlNode node = xmlDoc.SelectSingleNode(@"/MyXml/name", nm);
// node won't be null here
Posted by vhadiant at 06:07 PM | Comments (0) | TrackBack
September 05, 2005
View -> Tab Order
I just found this "Tab Order Wizard". I couldn't believe that I have been assigning my tab order manualy all this time!
Posted by vhadiant at 10:23 PM | Comments (0) | TrackBack
August 31, 2005
Hide methods/properties from IntelliSense
I can't really find a good reason why you would hide methods/properties from IntelliSense. Maybe you want to hide all the internal properties? Anyway I just found out a way to do this, use the EditorBrowsable attribute when defining your property.
However this apparently has a problem with the current Visual Studio .NET C# IDE where even if you set it to Never your property is still being picked up by IntelliSense. This should work fine with the Visual Basic IDE.
Posted by vhadiant at 10:00 PM | Comments (0) | TrackBack
August 30, 2005
Stop solution build when a project build fails
Visual Studio .NET always try to compile every single projects in it even though there's a problem in one of the project. If you are working with a small solution with a few projects that's not too bad, however I'm currently is working with a massive solution that has 45 projects in it. A full build takes over 5 minutes, I usually go nuts when there's a compilation problem and Visual Studio .NET just happily compile the rest of the projects. That really sucks, and I'm not the only one who think that it sucks. Enrico Sabbadin shows how to stop your solution building when there's a project compilation issue.
Just in case the original article disappear, this is the meat of the article. You need to do this in your MyMacros' Environment Events module:
Private Sub BuildEvents_OnBuildProjConfigDone( _
ByVal Project As String, _
ByVal ProjectConfig As String, _
ByVal Platform As String, _
ByVal SolutionConfig As String, _
ByVal Success As Boolean) Handles _
BuildEvents.OnBuildProjConfigDone
If Success = False Then
DTE.ExecuteCommand("Build.Cancel", "")
Dim win As Window = DTE.Windows.Item( _
EnvDTE.Constants.vsWindowKindOutput)
Dim OW As OutputWindow = CType( _
win.Object, OutputWindow)
OW.OutputWindowPanes.Item( _
"Build").OutputString( _
"ERROR IN " & Project & _
" Build Stopped" +
System.Environment.NewLine)
End If
End Sub
Posted by vhadiant at 07:47 AM | Comments (0) | TrackBack
August 18, 2005
Creating DataView
Interesting information about creating DataView (.NET) from MSDN:
Because the index for a DataView is built both when the DataView is created, and when any of the Sort, RowFilter, or RowStateFilter properties are modified, you will achieve best performance by supplying any initial sort order or filtering criteria as constructor arguments when you create the DataView. Creating a DataView without specifying sort or filter criteria and then setting the Sort, RowFilter, or RowStateFilter properties later results in the index being built at least twice: once when the DataView is created, and again when any of the sort or filter properties are modified.
Posted by vhadiant at 08:07 PM | Comments (0) | TrackBack
August 14, 2005
Static fields in generic classes
Guz Perez pointed out an interesting info about how static fields are going to be implemented in the upcoming C# 2.0
Posted by vhadiant at 10:52 PM | Comments (0) | TrackBack
August 04, 2005
Concerning enum and switch statement
So thanks to Peter Hallam to clear up one thing that always bother me but couldn't be bothered to look it up.
Posted by vhadiant at 11:23 PM | Comments (0) | TrackBack
July 09, 2005
More on DataRow deletion
I discovered another way for looping through a collection while removing the entries, thanks to a colleague, the trick is to loop through from the end of the collection. This way current item removed is always the last item, thus does not affect the current iteration, quite nifty really:
for (int i = dataSet.Table.Rows.Count - 1; i >= 0; i--)
{
DataRow row = dataSet.Table[i];
if (row ... )
{
row.Delete();
}
}
Update: Crap bad coding .. my bad :) Fixed now
Posted by vhadiant at 10:53 AM | Comments (0) | TrackBack
June 20, 2005
.NET spelling
It could be confusing, but the correct spelling of .NET is with all upper case. Not .Net, dotNet or .net.
However the logo is actually .net with all lower case:

So what does this mean? Well use .NET unless you're using the Microsoft's logo.
Posted by vhadiant at 08:10 PM | Comments (0) | TrackBack
June 18, 2005
DataRow deletion
Often you need to loop through the rows in a DataTable, pick up the invalid ones and delete them. This can be tciky because the Rows property in a DataTable is a collection and Delete() method actually removes the row from the collection, and this isn't good when you’re enumerating in a collection.
foreach (DataRow row in dataTable.Rows)
{
if (row.Id < 0)
row.Delete(); // Whoops not good, deleting the content of collection while enumerating it
}
This way also will cause problem:
for (int i = 0; i < dataTable.Rows.Count; i++)
{
if (dataTable.Rows[i].Id < 0)
dataTable.Rows[i].Delete();
}
This is because as soon as you call delete dataTable.Rows.Count will go down 1 as well since Rows is a collection. So how to do this? Well you can add all the rows that you want to delete into an ArrayList and delete it from there, but there's a better and more elegant solution for this problem. The key is the Select() method in the DataTable. The Select() method is very powerful and you can do pretty much almost any SQL constraints here and even some basic functions such as Trim().
DataRow[] rows = dataTable.Select("Id < 0");
foreach (DataRow row in rows)
{
row.Delete();
}
Posted by vhadiant at 12:13 PM | Comments (2)
June 14, 2005
How to add your own template on Visual Studio .NET
I've been wondering how to do this for a while, I know there's got to a be a way to add your own template in the "Add New Item" menu on Visual Studio .NET.
This CodeProject's article shows you how to do it:
http://www.codeproject.com/dotnet/Add_New_Item_Installer.asp
Posted by vhadiant at 09:31 PM | Comments (0) | TrackBack
June 06, 2005
Accessing DataRow after it has been deleted
Normally when you tried to access the Item property of a DataRow after it has been deleted it will throw a DeletedRowInaccessibleException. For example:
DataRow row = dataTable.Rows[0];
row.Delete();
// This will throw DeletedRowInaccessibleException
long id = row["Id"];
However what the documentation does not say is that if you use the DataRowVersion.Original when accessing the Item property it'll work. For example:
DataRow row = dataTable.Rows[0];
row.Delete();
// This is OK
long id = row["Id", DataRowVersion.Original];
Nice trick, I've only found this out today.
Posted by vhadiant at 10:14 PM | Comments (0)
June 05, 2005
System.Type.Missing
If you do a lot of COM interop with .NET, no doubt you'll find lots of methods with parameter that you don't really care. Have you ever come across this situation? Where you ended up reading opening up the doc and trying to set the default value one by one? It's annoying and cumbersome as hell, thank god .NET has System.Type.Missing that will automatically sets the default value for the parameters.
From the doco:
Use the Missing field for invocation through reflection to obtain the default value of a parameter. If the Missing field is passed in for a parameter value and there is no default value for that parameter, an ArgumentException is thrown.
Posted by vhadiant at 05:58 PM | Comments (0) | TrackBack
May 17, 2005
Annoying Visual Studio.Net error
Grrrgghh, for the past few days I've been plagued with the "The process cannot access the file because it is being used by another process" error during build. This often happen to your Visual Studio.Net solution if you have multiple assemblies in your solution as described here:
http://support.microsoft.com/default.aspx?scid=kb;en-us;313512
Whatever it is, I can't use the workaround described in the aforementioned KB. So to fix this just close your solution, go to the offending project, delete the debug directory in both Bin and Obj directory and then rebuild. If this doesn't work, you have to close Visual Studio.Net itself. If that still doesn't work, check that the problem assembly do not have a reference to itself, although the offending assembly will compile with no issue the other assembly that refer to this one may complain.
Posted by vhadiant at 10:08 PM | Comments (0) | TrackBack
