Developer's Dump

Alternate Data Streams

leave a comment »

NTFS has for a long time supported the concept of alternate data streams. The idea is  that you can store data under a file, not by inserting or appending into it but more like tagging it with data. Even if the feature is not widely know, it is used by Microsoft in many places e.g.  for storing the cached thumb nail images under each thumbs.db file and for marking downloaded files as blocked.

Not all shell commands support the feature, but this example should give you the idea:

echo "hello world" > test.txt
echo "hello you" > test.txt:hidden.txt
notepad test.txt:hidden.txt
dir *.txt

The first line just creates the parent for the alternate data stream created by the second command (<file or directory>:<stream name>). Note that the last dir command only shows the parent file.

Note that if you move a file,  the alternative data streams will only follow as long as the destination device also uses NTFS.

You can work with alternate data streams in C#, but only by using the Windows API as none of the standard .NET components support it directly. I made the following class to easily access the file handle (open/create) for creating and modifying an alternative data stream:

public static class AlternateDataStreams
{
    private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
    private const uint GENERIC_ALL = 0x10000000;
    private const uint FILE_SHARE_READ = 0x00000001;
    private const uint OPEN_ALWAYS = 4;
    public static SafeFileHandle GetHandle(string path, string name)
    {
        if (string.IsNullOrEmpty(path))
            throw new ArgumentException("Invalid path", "path");
        if (string.IsNullOrEmpty(name))
            throw new ArgumentException("Invalid name", "name");
        string streamPath = path + ":" + name;
        SafeFileHandle handle = CreateFile(streamPath,
        GENERIC_ALL, FILE_SHARE_READ, IntPtr.Zero, OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
        if (handle.IsInvalid)
            Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
        return handle;
    }
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
    uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
    uint dwFlagsAndAttributes, IntPtr hTemplateFile);
}

The handle can be passed to a FileStream for reading/writing.

I’m planning to use this for marking files in a way enabling my application to detect changes even if the file is left fully accessible to the users. I plan to achieve this by storing the file path+file hash data as a encrypted alternative data stream.

Written by Tom

June 28, 2010 at 11:33

Posted in .NET, Windows

Tagged with ,

Downloading Old Visual Basic 6 Libraries

leave a comment »

Migrating old Visual Basic 6 applications to work on Windows 7 can be hard work. Microsoft gives a “it just works” guarantee for the old run-time but not the common and custom control packages heavily used in the past.

The Visual Basic 6 common controls package including most of the old libraries is available for download from Microsoft, but it could not get it to install on my Windows 7. Many of the libraries are also available for download on various download sites, but these files cannot be fully trusted.

I took a closer look at my Visual Basic 6 IDE installation running on one of my virtual machines and noticed that many of the libraries had a dep file by the same name. The dep files are Visual Basic setup wizard dependency files used by the old installers to point the location from where the library could be downloaded. All of these dep files pointed to the following URL:

http://activex.microsoft.com/controls/vb6/

For my surprise the URL still worked! Using the address one can download any on the old libraries simply by adding the library name and the cab extension to the address, e.g. to retrieve the library dblist32.ocx I used the URL http://activex.microsoft.com/controls/vb6/dblist32.cab. All the common libraries like comdlg32.ocx and dblist32.ocx are there! The server returns a cab file containing the ocx file and an inf file. After downloading all you need to do is to extract the ocx file, put it in your windows\system32 directory and register it using regsvr32.

Unfortunately the more you play around with the old libraries the quicker you face the old dll hell. The ocx libraries often depend on other ocx and dll files that then in turn depend on even more files. None of these dependencies are included in the cab file returned by the server, so to find out what additional files you need, do the following:

  • Check the reference list in the vbp (Visual Basic project) file of the application
  • Google for the dep file of the library you need to use
  • Look into the vb6dep.ini for hints.

If you need to migrate even older applications starting from VB3, you can start by downloading the old run-times from here.

Written by Tom

April 7, 2010 at 16:10

Posted in Windows

Tagged with , ,

JDBC: SQL Server and Named Instances

with 2 comments

It’s been a while since I worked with Java and especially JDBC. Today I spent  a while trying to get the Oracle BI Publisher to connect to a SQL Server 2005 instance.

I found various examples of different ways to define the instance name in the connection string. After trying them all I could only conclude that defining the instance specific port number is the only way to get a connection established.

jdbc:hyperion:sqlserver://<server>:<port>;DatabaseName=<database>...

Reading the MSDN documentation a bit closer also revealed that it is the recommended way.

How do I know what the instance specific port number is? Easy!

  1. Fire Up the SQL Server Configuration Manager
  2. Expand the the SQL Server 2005 Network Configuration node
  3. Click on the instance you want
  4. Double click on the TCP/IP item
  5. Switch to the IP Addresses tab

The port number needed is the item named TCP Dynamic Ports.

Written by Tom

March 17, 2010 at 17:47

Posted in Databases, Java

Tagged with , ,

Server Error in ‘/tfs’ Application

leave a comment »

Setting up Team Foundation Server 2010 RC was easy, especially when selecting the Basic profile as it does not require you to setup SharePoint and the SQL Server Reporting Services. Everything on the Visual Studio and source control side worked well.

But when I fired up my browser the have a look at the Web Access now a partof the standards TFS, IIS prompted me with the following error:


I was not sure if the Basic profile included the Web Access as I could not find any info on it on the web.  The IIS diagnostic tools suggested the server had problems accessing the folder so I tried all sorts of things with the security settings. By googling I found some solutions for older IIS versions, but I didn’t want to do anything that would e.g. prevent me from updating my TFS setup later.

Finally I added a bug report to Microsoft Connect and as the solution they suggested was the same I had found earlier, so I tried it.

For some reason the installation of the web access web application had gone wrong. All I needed to do to fix the problem was to convert the web folder into an application:

Seconds later I could access projects using the browser!

Unfortunately my problems with the Web Access did not end there. At the moment I’m unable to create child work items using the web access interface:

Again, I’ve made a bug report on it. I will edit this post when I find a solution. If you are having any of these problems, give my bug reports your vote!

Written by Tom

March 12, 2010 at 18:00

Posted in Uncategorized

Tagged with , ,

SQL Server CE 3.5: ISNULL not supported

leave a comment »

Working with SQL Server CE 3.5 I noticed that it does not support the ISNULL function. Instead you have to use the COALESCE function to achive the same thing.

The coalesce function can be used much in the same way as the isnull function. The coalesce function returns the first none-null value in the parameter list.

This will give you all the rows where some_id_field is not null and equals the @filtering_id parameter:

SELECT some_value WHERE COALESCE(some_id_field, -1) = @filtering_id;

Written by Tom

March 2, 2010 at 15:05

Posted in Databases

Tagged with , ,

WPF: Cannot set Name attribute value errror

with 2 comments

When writing a custom user control you might at some point be tempted to use it as an item container. If you then try to name the nested control you will get the following error:

Cannot set Name attribute value 'myControl' on element 'SomeControl'. 'SomeControl' is under the scope of element 'ContentPanel', which already had a name registered when it was defined in another scope.

This is unfortunately a common problem caused solely by the XAML parser.

The easiest solution to overcome this is by constructing the control yourself. I did this by defining my XAML in a resource dictionary and then writing the lines required to load it at runtime. The only downside in this approach is that no designer preview is available.

Here are the 3 easy steps to write a simple container with a title on top:

1. Add a new class (ContentPanel.cs) and a Resource Dictionary (ContentPanel.xaml) to your WPF project.

2. Then write your XAML into the dictionary defining the style for your control:


<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyNamespace">
    <Style TargetType="{x:Type local:ContentPanel}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ContentPanel}">
                    <Grid Background="Transparent">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="18"/>
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <Border Grid.Row="0" Background="#FF6C79A2"
CornerRadius="4 4 0 0" Padding="5 3 5 3">
                            <TextBlock VerticalAlignment="Center" Foreground="White" 
Text="{Binding Path=Title, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type local:ContentPanel}}}"/>
                        </Border>
                        <ContentPresenter Grid.Row="1"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

3. Finally edit the class so that it inherits from the UserControl class and add a initialize method that will be called by the constructor to load the XAML from the resource dictionary:

    public class ContentPanel: UserControl
    {
        public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register("Title", typeof(string), typeof(ContentPanel),
new UIPropertyMetadata(""));
        public ContentPanel()
        {
            Initialize();
        }
        private void Initialize()
        {
            ResourceDictionary resources = new ResourceDictionary();
            resources.Source = new Uri("/MyAssemblyName;component/ContentPanel.xaml", 
UriKind.RelativeOrAbsolute);
            this.Resources = resources;
        }
        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }
    }


The Uri format might seem odd, but just edit my example to define the names of your dll and xaml file.

Don't forget to vote on Microsoft Connect to get Microsoft to fix the XAML parser!

Written by Tom

February 24, 2010 at 00:56

Posted in .NET, WPF

Tagged with , , ,

Supporting WPF Binging Without the WindowsBase Library

leave a comment »

WPF Bindings provide a powerful way to link your data with the user interface. But what can you do to keep your data classes independent from the WPF framework?

There are a couple of ways to support WPF binding. For none-UI classes the best option is to implement the INotifyPropertyChanged and INotifyCollectionChanged interfaces. Implementing them explicitly keeps the interface of your data classes clean and all the WPF functionality available only for those classes that support it.

private event PropertyChangedEventHandler PropertyChanged;


protected void OnPropertyChanged(string name)
{
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(name));
}
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
{
    add { PropertyChanged += value; }
    remove { PropertyChanged -= value; }
}

Unfortunately in .NET 3.5 both the interfaces are a part of the WindowsBase WPF library, so it is not possible to support bindings without referencing to it. This also means all the assemblies that need to take advantage of your data classes need to reference the library.

It made me very happy to read in Jamie Rodriguez’s blog that in .NET 4.0 the notify interfaces have been type forwarded to System.dll! I could also confirm this using Visual Studio 2010 Beta 2. Hurray!

Ps. According to the Data Binding Performance article on MSDN, the notify interfaces provide a slightly better performance compared to using XXXChanged events.

Written by Tom

January 15, 2010 at 18:25

Posted in .NET, WPF

Tagged with , , ,

Faster XML Serialization

leave a comment »

A lot of run-time compilation is involved when the XmlSerializer is used. For better performance it is recommended to run sgen.exe to generate a serialization assembly to speed up the XML serialization. In a way, the idea behind SGen is the same as for NGen.

There is a Generate Serialization Assembly drop-down in the project settings in Visual Studio, but this covers only available Web service proxies. To have Visual Studio run SGen automatically for other types, you need to manually add the following lines to your project file:

<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"  Outputs="$(OutputPath)$(_SGenDllName)">         
    <SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)"  References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)">
        <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
    </SGen>
</Target>

Written by Tom

January 4, 2010 at 17:13

Posted in .NET, XML

Tagged with , ,

Excel 2003 Add-in development Tricks and Tips

leave a comment »

When developing an Excel add-in, much time is spend on figuring out how to programmatically implement things possible by hand or in a VBA macro. Here are some tips and tricks to help out masterin Excel using C#!

Value Validation

When reading the value of a cell (specially numeric values), you should always start by validating it.  The reason is simple, if a cell contains an error caused by an invalid formula or reference (e.g. #N/A, #REF ,#NAME, #DIV/0, #NULL, #VALUE and #NUM), the cell value will return a error code (e.g. -2146826273) instead of a value you might be expecting (0 or null).

You can find all the common Excel formula functions in Application.WorksheetFunctions. The following example uses the IsError function for converting a error value to null.

Range cell = range.Cells[row, col] as Range;

if (!Application.WorksheetFunction.IsError(cell))

{
    value = cell.Value2;
}
else
{
    value = null;
}

For more information on handling cells with errors, visit the VSTO & .NET & Excel blog

Controlling the User Interface

When processing cells you might in some situations need to prevent the user from editing the workbook and seeing the cells being updated. For this I usually used the following functions:

public void BeginUpdate()
{
    Application.ScreenUpdating = false;
    Application.Interactive = false;
}
public void EndUpdate()
{
    Application.ScreenUpdating = true;
    Application.Interactive = true;
}

Make sure you call the EndUpdate in a finally block, or you risk having the user lose all his work if an unhanled exception occurs!

Better Performance By Caching

Looping repeatedly through collections provided by the Excel API can be very very slow, thanks to the COM interface.

If you have a lot of named ranged in your workbook, caching the Names collection might speed up your application 10x or more.

private Dictionary<string, Range> _NamedRanges;
public Dictionary<string, Range> NamedRanges
{
    get
    {
        if (_NamedRanges == null)
            LoadNamedRanges();
        return _NamedRanges;
    }
}
private void LoadNamedRanges()
{
    _NamedRanges = new Dictionary<string, Range>();
    foreach (Name name in Application.ActiveWorkbook.Names)
    {
        try
        {
            _NamedRanges.Add(name.Name, name.RefersToRange);
        }
        catch (Exception)
        {
            // Ignored
        }
    }
}
public void Refresh()
{
    if(_NamedRanges != null)
        _NamedRanges.Clear();
    _NamedRanges = null;
}

Note that reading the ReferesToRange value of some internal Excel ranges might cause an exception to be thrown.

Storing Data

Many applications support the concept of custom (file) properties. These provide a easy way to store custom application data (key-value-pairs)  into a data file.

Like all the Office applications, also Excel supports custom properties enabling you to store data into the workbook. One thing to bare in mind though is that every property can only hold up to 255 characters.

By implementing the following easy steps, you can store basically any kind of object data into the workbook (I will maybe post some code later):

  1. Tag your class(es) using the standard XML attributes and use the XmlSerializer to serialize the objects to a string
  2. Just to be on the sure side, encode the string using Base64 (this also hides the data from the user)
  3. Split the data to chunks of 255 characters and store them into custom properties. Name each property with a running number to help you re-assemble the data string.

To read back the custom properties to objects, all you need is to run the steps in a reverse order.

Event Handling

The COM interface causes many problems when it comes to managing Excel events. One reason to this is must be the automatic GAC and that event handlers are hard to marshal, this results in the managed side being out-of-sync with the unmanaged Excel API. The symptoms of these problems are random exceptions and loss of event handlers (e.g. the event handler of a menu is usually lost after the first click).

In my experience the only way to be safe is not to play around with the Excel events. Also make sure you place all your menu handling code in the main add-in class!

Written by Tom

December 30, 2009 at 02:28

Posted in .NET, Office

Tagged with , ,

Windows 7 Activation: Error 0xC004F074

with 3 comments

Windows 7 activation failure

Installing Windows 7 was over in a few minutes, but I had some problems with the activation. After some googling I found the answer in one of the comments to a post in Mikael Sands blog.

If you get an error 0xC004F074 when trying to activate a enterprise edition Windows 7, check that your date and time settings are correct! For some reason my date setting was wrong and correcting it enabled Windows 7 to communicate with the KMS.

Written by Tom

December 15, 2009 at 18:45

Posted in Uncategorized, Windows

Tagged with

Follow

Get every new post delivered to your Inbox.