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