Aug 282014
 
What’s DEVPATH

Being a .net developer you might have wondered if at all there is a way to tell .net assembly binding and loading mechanism (fusion) to look for your assemblies in your shared assembly folder as well. This will be really helpful if your assembly is used with multiple applications so that if they fail to locate an assembly in the appbase or privatepath’s then they start looking for it in your ‘bin’ folder. This prevents you from frequently installing and uninstalling the assembly to GAC for testing purpose.

This is exactly what DEVPATH environment variable does.

How to set DEVPATH

Following example shows you how to setup just need to set assembly look up path to this variable. For e.g.

set DEVPATH=”c:\sharedassemblies\”

To enable DEVPATH look up you’ll also need to modify machine.config file, in my case its located here: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config

<configuration>

<runtime>
<developmentMode developerInstallation=”true”/>
</runtime>

</configuration>

Verify DEVPATH is used

So next time when application runs and starts looking for your assembly it will for sure look in the above path. If fusion logger is enabled and if you open the log file for your assembly you should see something like this…

===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\myapp.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Found assembly in DEVOVERRIDE path C:\sharedassemblies\Test.DLL

Recently had a customer who asked this question and this looks like to have helped them so thought of sharing this out with you folks as well.

Watch outs
  1. Please be very aware that you’ve set this feature on. You could end up having erratic behavior if somehow DEVPATH has a path containing unsupported path chars like parentheses or if DEVPATH is set to empty.
  2. Please only use this feature in development environments as this feature by passes all normal assembly lookup features as fusion looks up DEVPATH first if enabled.
  3. Please note fusion will look up DEVPATH as if its an AppBase folder so be aware that it will look up subdirectories as well in this DEVPATH. Also all valid assembly name look ups will be done, for e.g. .dll, .exe etc.
Aug 052014
 

Do you run into following error when trying to run a VS2013 .net application on Windows XP?

Error: Not a valid Win32 application!

This happens because the application is targeting .net framework 4.5 which is not supported on Windows XP. Target a lower framework to get your application working on XP.

Aug 052014
 

What are DateTime Custom Formatters?

A date and time format string defines the text representation of a DateTime or DateTimeOffset value that results from a formatting operation . It can also define the representation of a date and time value that is required in a parsing operation in order to successfully convert the string to a date and time. A custom format string consists of one or more custom date and time format specifiers. Any string that is not a standard date and time format string is interpreted as a custom date and time format string.

Custom date and time format strings can be used with both DateTime and DateTimeOffset values.

Issue with DateTime Custom Formatters?

Recently a customer opened a ticket thinking that there is an issue with the DateTime Custom Formatters. They had following piece of code.

namespace DateTimeDefect
{
 class Test
 {
   static void Main(string[] args)
   {
     DateTime dt = DateTime.Now;

     Console.WriteLine(dt.ToString("f"));
     Console.WriteLine(dt.ToString("ff"));
     Console.WriteLine(dt.ToString("fff"));

     Console.ReadLine();
   }
 }
}

Except for dt.ToString(“f”) the other two ToString calls were returning correct results. Here’s the output…

Friday, May 30, 2014 12:53 AM (Here’s the issue, customer expects a numeric value as shown below)
53
534

Here’s what MSDN says about custom formatter ‘f’, ‘ff’, ‘fff’.

“f”: The tenths of a second in a date and time value. More information: The “f” Custom Format Specifier.

Sample:
6/15/2009 13:45:30.617 -> 6
6/15/2009 13:45:30.050 -> 0

“ff”: The hundredths of a second in a date and time value. More information: The “ff” Custom Format Specifier.

Sample:
6/15/2009 13:45:30.617 -> 61
6/15/2009 13:45:30.005 -> 00

“fff”: The milliseconds in a date and time value. More information: The “fff” Custom Format Specifier.

Sample:
6/15/2009 13:45:30.617 -> 617
6/15/2009 13:45:30.0005 –> 000

 So what’s going wrong here with DateTime Custom Formatters

The issue here is that dt.ToString(“f”) is not recognized as a custom format specifier. Please read below documentation from MSDN…

A custom date and time format string consists of two or more characters. Date and time formatting methods interpret any single-character string as a standard date and time format string. If they do not recognize the character as a valid format specifier, they throw a FormatException. For example, a format string that consists only of the specifier “h” is interpreted as a standard date and time format string. However, in this particular case, an exception is thrown because there is no “h” standard date and time format specifier.

To use any of the custom date and time format specifiers as the only specifier in a format string (that is, to use the “d”, “f”, “F”, “g”, “h”, “H”, “K”, “m”, “M”, “s”, “t”, “y”, “z”, “:”, or “/” custom format specifier by itself), include a space before or after the specifier, or include a percent (“%”) format specifier before the single custom date and time specifier.

For example, “%h” is interpreted as a custom date and time format string that displays the hour represented by the current date and time value. You can also use the ” h” or “h ” format string, although this includes a space in the result string along with the hour. The following example illustrates these three format strings.

Resolution

So in this case the date time formatting method is interpreting this single character string as a standard date and time format string. To work around this, following are the options that you have…

1. Use dt.ToString(“%f”)
2. Use dt.ToString(“ f”);// add a space before ‘f’
3. Use dt.ToString(“f ”);// add a space after ‘f’

So if we change above code to…

static void Main(string[] args)
{
  DateTime dt = DateTime.Now;
  Console.WriteLine(dt.ToString("%f"));
  Console.WriteLine(dt.ToString("ff"));
  Console.WriteLine(dt.ToString("fff"));
  Console.ReadLine();
}

Now program output looks as follows…

8
87
873

Based on last value output you can verify the first two. Issue resolved.

Feb 032014
 

DataRepeater is great control to display data from a table/view, as the name says repeats bunch of fields from a dataset on every row. Follow these simple steps to get started working with this control…

Step 1:

Add a reference to the PowerPack library as shown here: http://ntcoder.com/bab/2013/12/20/visualbasic-powerpack-missing-from-visual-studio-2013/

Step 2:

Make sure you’ve got the datasets in place: Press Shift + Alt + D or View –> Other Windows –> Data Sources. See below screenshots of my Northwind dataset…

image

Step 3:

Drag and drop an instance of data repeater onto your win forms or a container control. Resultant form will look as follows…

image

Please note you’ve got to have the right version of DataRepeater in order for it to get displayed on the form designer surface.

Step 4:

Drag and drop fields from your data set onto this data repeater’s surface. Note that every field dropped on to data repeater will be a pair of control (Label followed by text field or any other control if the option is provided, in my case picture control). I’ve got the following fields dropped on to the control…

image

The size of the control at runtime will be the same as the one you’ve given on the designer, unless you’ve docked the control. Scrollbar’s will be provided by the control to scroll through the rows of data.

Step 5:

Now if I run the form this is what I see. You can scroll through as well. Quick way to display data on a form.

image

Step 6:

DataRepeater supports some other features as well, please go through the documentation to know more. Enjoy!

Jan 282014
 
Introduction

I’ve got a native console application which would like to interop into a piece of managed code written in C#. This is the how the C# function “Sum” looks like…

image

My solution explorer looks as follows…

image

CSharpModule is a CSharp library while TestManagedCall is a native/unmanaged project. My requirement is as follows: call Class1.Sum from TestManagedCall project.

Adding Reference for Interop

To do this we’ll need to first add a reference of CSharpModule to TestManagedCall project. Go to project properties of TestManagedCall project and add a reference to CSharpModule project, see below screenshot…

image

So the reference of CSharpModule is now added to TestManagedCall project.

Project changes for enabling Interop

Next step is to add a new C++ file to TestManagedCall project. I’ll call the file: CSharpModuleWrapper.cpp, this class will act as a wrapper to our managed library: CSharpModule. This is how my solution will explorer look now…

image

Right click on CSharpModuleWrapper.cpp in the solution explorer, select properties, and enable CLR for just this one file

image

Fixing incompatibilities

Click “Ok”. Now do a full rebuild. You should see following errors pop up, fix them one by one since adding CLR support results in these incompatibilities… (you’ll see these errors popup one by one, so fixing one will lead to another. Keep fixing them and you’ll see the next error).

  1. cl : Command line error D8016: ‘/ZI’ and ‘/clr’ command-line options are incompatible. Open the file’s(CSharpModuleWrapper.cpp) properties and go to “All Options” under C/C++ node. This is a cool feature to quickly search for an option the properties dialog. Search for /ZI as given in the above error message. CLR compilation doesn’t support /ZI change it to /Zi.
    image
  2. cl : Command line error D8016: ‘/clr’ and ‘/Gm’ command-line options are incompatible. Again open file’s properties and goto “All Options” under C/C++ node. Search for /Gm as given in the above message… (disable minimal rebuild). Change to /Gm-
    image
  3. cl : Command line error D8016: ‘/clr’ and ‘/EHs’ command-line options are incompatible. In file’s properties search for /EHs. Switch to /EHa.
    image
  4. cl : Command line error D8016: ‘/clr’ and ‘/RTC1’ command-line options are incompatible. Change to Default as shown below…
    image
  5. Disable pre-compiled headers as shown below, search for /Yu under “C/C++->All options”…
    image

With these changes your code will compile. I get following output…

image

Code Changes for Interop

Now add code to use the CSharpModule’s namespace and add a function to CSharpModuleWrapper class. Eventually this is how my code will look like with all the modifications…

image

The CSharpModuleWrapper.h has only one change, I added a declaration for Call_Sum().

Don’t forget to call Call_Sum(). This is how the calling code looks like…

image

Output…

image

This is a reliable way to make calls into managed world from native world. Of course there are #pragma’s (managed/unmanaged) that you can use but I’m not so confident about using them. This is clean!

Conclusion

The sample I’ve shown is a ‘very’ simple one, I’m sure you’ll have a variety of requirements, let me know if I can help.

Sep 232013
 
What is fusion

Fusion is the module in .net which manages binding of .net assemblies. So the question here is why do we need to setup fusion logs. Since we know that fusion is module which is responsible for assembly bindings, its good to know that it also emits verbose logs known as fusion logs. These log entries lists out the activities that fusion does for loading an Assembly. The logs will also show us why a particular Assembly failed to load: this is why most folks enable fusion logger.

Fusion logging is not turned on by default. We’ll have to turn it on via registry entry or use fuslogvw.exe to set verbosity of fusion logging: for e.g. what needs to be logged, bind failures?

The fusion module comes into play during Assembly binding phase. We can request binding via automatic references in project or via explicit code requests etc.

What is an Assembly

An Assembly in .net is made of the following components…

image

In short Assembly is made up of a manifest file (the main module) and can also have other module files as well. The manifest metadata will have references to the other modules that an Assembly has.

How to enable fusion logging
Using FusLogVw tool

Please follow these steps to enable fusion logging.

1. Run Visual studio 2010 command prompt as admin.
2. Run fusion log tool: fuslogvw.exe. Fuslogvw should be there in your SDK folder, in my case…
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\FUSLogvw.exe. You can as well run it directly from your Visual Studio command prompt.
fusionlogvw
If fusion log viewer is not installed on your machine, then add the registry entries given below manually and check out the log folder for output.
3. Open the settings dialog as shown in above image by clicking on the “Settings” button.
4. Enable “Log all binds to disk”.
5. Check “Enable custom log path”.
a. Enter a custom fusion log path, in my case I used “C:\FusionLog”.
6. Say “Ok”.
7. Go ahead with execution of your application. If you restart/refresh the log viewer you should see log entries as shown in the above screenshot.

If FusLogVw is missing…

Following registry entries get added to the registry when you enable options via above settings dialog of fuslogvw.exe. Just in case if you don’t have fuslogvw.exe installed on your box add the relevant one manually into the registry or you can create a .reg file which does this consistently.

  • Log all binds to disk
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion\ForceLog = 1
  • Log bind failures to disk
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion\LogFailures = 1
  • Log in exception text
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion\EnableLog = 1
  • Log Disabled
    • No entry.
  • Enable custom log path
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion\LogPath = c:\fusionlog
Viewing logs in the fusion folder

Click on any of the log entries in the above log viewer, entries are saved to disk in html format, the corresponding html file will open in your default browser. You can also view the entries directly by opening the log folder contents directly, in my case c:\fusionlog.

image

The last line mostly says whether the assembly loaded successfully or not. The lines before that will tell why the loading failed. Instead of “Log:” you’ll see something like “WRN:”/”ERR:” etc.

Fusion log viewing is the best way to figure out Assembly load issue.

May 022013
 

Thought I will share some interesting differences between a .net class and a struct.

Class Struct
Allocated on the heap. Allocated on the stack. They are value types and don’t require heap allocation.
A variable of a class type stores a reference to a dynamically allocated object. A variable of a struct type directly stores the data of the struct.
Supports user-specified inheritance. Does not support user-specified inheritance and all struct types implicitly inherit from type object.
An array of, class Point instances of, size 100 implies 101 separate objects are instantiated. One for the array and one each for the 100 elements. An array, of struct Point instances, of size 100 implies only one object i.e. the array is instantiated and the struct Point instances are stored inline in the array.
Dynamic allocation done via ‘new’ call. Struct constructors are invoked with the new operator but that does not imply that memory is being allocated. Instead of dynamically allocating an object and returning a reference to it, a struct constructor simply returns the struct value itself (typically in a temporary location on the stack), and this value is then copied as necessary.
With classes, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. With structs, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. For example, the output produced by the following code fragment depends on whether Point is a class or a struct.
Classes are kind of faster as only their references are copied around. Structs are copied by value unless we specify ref, out parameters hence the copying overhead is there.

 

Structs are particularly useful for small data structures that have value semantics. Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. The use of structs rather than classes for small data structures can make a large difference in the number of memory allocations an application performs.

These differences are picked up from the C# 4.0 language specification.

Jan 062012
 

You have a managed application crash dump and you would like to load sos.dll, to use the powerful commands it provides to help with managed debugging, but the load of sos.dll always fails. The command that you are executing for loading sos.dll is… 0:015> .loadby sos clr Unable to find module ‘clr’ On enter you see the above error and you are not sure what is going on. So in order to understand the error message it is important to understand what .loadby command does. “.loadby sos clr” means load sos.dll from where clr.dll is loaded. So as you might have guessed by now if clr.dll is not loaded then sos.dll cannot be found. This is what the error means when it says “Unable to find module ‘clr’”. All it means is clr.dll is not in the loaded module list which means there is no path to locate clr.dll. So how can I fix this error? In order to fix this error you must understand that clr.dll has been introduced into .net applications from .net 4.0 and prior to that we used to have mscorwks.dll. So if your .net application is not a 4.0 app then clr.dll won’t be loaded, yes you will have to use mscorwks.dll instead… 0:015> .loadby sos mscorwks But you are damn sure that the application that crashed is a .net 4.0 application but you still see the error! All I can say is clr.dll is not loaded. Wait for it to load or break on its load and then execute .loadby sos clr. So how to break on a module load… 0:015> sxe ld clr This will for sure help!

Sep 062011
 

Enable or Disable Just In Time Debugging

Read the following article in MSDN:

http://msdn.microsoft.com/en-us/library/5hs4b7a6.aspx

The easiest way to disable JIT debugger is via the Tools->Options dialog in Visual Studio. For other options read the article.

Enable/Disable Just in Time Debugger in Visual Studio Options dialog

Enable/Disable Just in Time Debugger in Visual Studio Options dialog