Category Archives: .NET

Determining .NET Framework version from the native C++ code.

.NET Framework version 4.5 and higher can be determined with the following C++ code:

#include <windows.h>

bool IsDotNet45Installed()
{
    DWORD value{};
    DWORD dataSize = sizeof(value);
        
    const LONG retCode = ::RegGetValue(
        HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\",
        L"Release",
        RRF_RT_REG_DWORD,
        nullptr,
        &value,
        &dataSize
    );

    if (retCode != ERROR_SUCCESS)
    {
        return false;
    }

    return value >= 378389;
}
(more…)

Generating .NET wrappers for COM during build in MS Visual Studio

If in some Visual Studio solution a .NET project references a C++ project that implements a COM server then the following command can be used in Post-Build Event of the C++ project to generate .NET wrapper for COM:

"$(TargetFrameworkSDKToolsDirectory)tlbimp.exe" "$(TargetPath)" /verbose /strictref /asmversion=$(Version) /out:"$(TargetDir)$(TargetName)Lib.dll"

In VS2015 by default this command will generate .NET 4.0 assembly. To generate .NET 2.0 assembly, the following command can be used:

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\TlbImp.exe" "$(TargetPath)" /verbose /strictref /asmversion=$(Version) /out:"$(TargetDir)$(TargetName)Lib.dll"

I am not sure that changing TargetFrameworkVersion attribute in PropertyGroup Label=”Globals” element of the project file can help here, so it is not clear how to get rid of absolute path.

Also it is impossible to add a reference to a TLB or EXE file to .NET assembly, so using TLB generated by MIDL directly is not an option (MIDL->Output page of C++ project using $(OutDir)$(TargetName).tlb as Type Library name).

How to run WIX bootstrapper application UI with elevated privileges?

WIX bootstrapper application (BA) can easily determine if it runs as admin with the following code:

using System;
using System.Diagnostics;
using System.Security.Principal;

static bool IsAdmin()
{
    WindowsIdentity id = WindowsIdentity.GetCurrent();
    WindowsPrincipal principal = new WindowsPrincipal(id);
    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

and if it does not, run a new instance as admin and exit:

static void RunAsAdmin()
{
    ProcessStartInfo proc = new ProcessStartInfo
    {
        UseShellExecute = true,
        WorkingDirectory = Environment.CurrentDirectory,
        FileName = Process.GetCurrentProcess().MainModule.FileName,
        Verb = "runas"
    };

    Process.Start(proc);
}

(more…)

Implementation of WPF’s ICollectionView interface

The existing ICollectionView implementations in WPF, for example ListCollectionView, work very good in trivial cases, they even can sort and filter the items from the underlying collection, but they have some significant disadvantage: they do not keep the correct sort order of an item and they do not filter the item out if its property is changed until ICollectionView.Refresh() method is called explicitly.

To overcome this inconvenience I developed my own implementation of ICollectionView interface that listens to all its items property change events via WeakEventManager and fires corresponding collection change events to re-soft or re-filter the item if needed. It was not a very simple task for me, and I even debugged WPF source code a bit and realized that it works a bit strange, for example, ItemsControl cannot work with my ICollectionView implementation directly, instead it creates some CollectionViewProxy that wraps it and uses some proxy enumerator to access an item by index:

(more…)

Debugging .NET Framework with Visual Studio 2013

Visual Studio 2013 allows easily to debug .NET 4.5.1 Framework source code. If you use a previous version of .NET (4.5 or earlier) change the target .NET version of the your projects to 4.5.1 or higher. If you have some C++ CLI projects modify TargetFrameworkVersion attribute manually in all *.vcxproj files:

<PropertyGroup Label="Globals">
  ...
  <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
  ...
</PropertyGroup>

then go to Tools->Options->Debugging->General and check/uncheck the following options:

Debugging .NET Framework with Visual Studio 2013

(more…)

My experience with WPF

When I worked on some navigation system I developed so called “Control Panel” with various custom WPF controls:

(more…)

HwndHost is not clipped inside ScrollViewer

I created a simple white control with a black border derived from HwndHost (named LightGrid) and added it to ScrollViewer along with some other controls (replaced with “…”) as shown below:

<ScrollViewer HorizontalScrollBarVisibility="Disabled">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            ...
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            ...
        </Grid.RowDefinitions>
        ...
        <Border Grid.Row="6" Grid.ColumnSpan="2" Visibility="Visible" Height="200">
            <nc:LightGrid />
        </Border>
    </Grid>
</ScrollViewer>

It looks correctly in the lower scroll position, and it even can scroll inside ScrollViewer (it moves when I move the scroll bar), but when scrolled, it is not clipped so it obscures other controls:

(more…)

Using a WPF control in a MFC application

I’ve been working on some MFC application and to apply my WPF knowledge I added a WPF control written in C# to my MFC CView with the following code:

int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;

    try
    {
        gcroot<hwndsource ^> hwnd_source = gcnew HwndSource(0, WS_VISIBLE | WS_CHILD, 0, 0, 0, "HwndSource", IntPtr(m_hWnd));

        MyWpfControl ^ control = gcnew MyWpfControl();

        hwnd_source->RootVisual = control;
    }
    catch (Exception ^ ex)
    {
        String ^ msg = ex->Message;
    }

    return 0;
}

All that I needed to do is to follow the steps described in this post: How do I host WPF content in MFC Applications, fix VS2012 bug described here, and got rid of std::mutex and std::lock_guard replacing them with the following classes using typedefs:

(more…)

WPF TreeView does not support Data Virtualization

WPF implements UI Virtualization via VirtualizingStackPanel and it works great, but situation with Data Virtualization is a bit more complex.

After doing some experimentation I realized that VirtualizingStackPanel when used with WPF TreeView does not allow the data to be virtualized because it iterates through all the collection of data items from inside its MeasureOverride function. However, it access only visible data items when used with DataGrid or ListView, so it allows to use some paging or caching techniques in this case. See the following articles for more information:

If you interested on what I tried to do with TreeView, please read below.

(more…)

How to implement WCF service in PHP

Today I implemented my first PHP Web Service and successfully used it by C# client or, more precisely, I created WCF service contract in C# and implemented it in PHP.  A new option “singlewsdl” in WCF 4.5  helped me a lot. Using this option I generated the service description as a single WSDL-file without additional XSD-files containing the data contracts of the service. Then I uploaded this WSDL-file on my Web Server and written PHP code for all the methods of the service.

(more…)