Author Archives: Rudolf - Page 6

VS 2013 Express tips

Just thought to share a tip or two about making the user experience better. The following applies to the desktop version but should also work (with some minor adjustment) to the other editions as well.

Change the all UPPERCASE main menus

In the registry, find the key HKEY_CURRENT_USER\Software\Microsoft\WDExpress\12.0\General. Add a (32-bit) DWORD value named SuppressUppercaseConversion and give it a value of 1. Next time you open the IDE the menu’s will be normal Title case again. It also applies to VS2012 editions as well (just change the version number to 11.0). For web express just change the ‘WDExpress’ part.

Update: If you are using the Web express edition the registry path for the change upper case menus are: HKEY_CURRENT_USER\Software\Microsoft\VWDExpress\12.0\General

Adding more themes

By default there are only 3 themes (for the express versions). To add some more options go to http://alinconstantin.blogspot.com/2012/09/using-color-themes-with-visual-studio.html?_sm_au_=isV7sFqHt8JbtbNM

Adding my Source backup tool

My source backup tool id aware of the desktop express version and can automatically add itself as one of the custom tools of the IDE. See SourceBackup.

If I come across more tips I’ll add them here as well.

 

Command line and strings

I’ve blogged about this some time ago under another topic (Creating-daily-log-files) but I find myself regularly searching for it again when I have to create a new batch file for something plus have to output some uniquely named log file.

Situation:

You have some script/batch file that does some stuff/maintenance/imports whatever. It runs from some kind of scheduler unattended so you need to have it generate a log file in case there were errors/issues. Creating an output log file is fairly easy but having it create a new name each day/time is a bit more tricky.

Possible solution:

This script assumes a date time format of yyyy/mm/dd

SET UNIQUESTR=%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%
MyTool.exe > MyTool%UNIQUESTR%.log

This will create a log file with a date and time stamp each time it is run (assuming you don’t run it twice in the same second)

Have fun kids!

Update: a nice site with some helpful info -> http://www.dostips.com/DosCommandIndex.php

QuickMon 2.13

Just a quick heads-up for any QuickMon users. A new version was added recently with a couple of small but nice improvements.

Some of the changes:

  • UI client now automatically refresh the config of ‘Detail’ windows (if the particular Collector’s config was edited)
  • The WMI collector was basically rewritten to improve it and add a little WMI query builder interface. This help people that are not experts using WMI syntax or know all the classes/properties that are available.

 

List all servers where I have an RDP session on (even ones where I’m disconnected)

This is something more than just one administrator has had trouble with. How do you find out what servers/machines you have worked on at some point and happened to simply use the ‘disconnect’ feature because you still had windows open? So far I have not found a simple way to do this – however I have created a script that helps with this. Unfortunately it still requires you to specify a list (input text file) of possible servers than needs to be checked. I would have liked if it was possible to have it automatically discover all machines with RDP sessions that use my logon…

The solution I created is simply a powershell script that takes an input text file with the list of machines you want to test connections with. This list would probably contain the usual machines you connect to. The other bit of the ‘solution’ is calling the ‘qwinsta’ utility that queries a specified machine and returns some details about RDP connections active on that machine. The script must then parse the output to figure out if your username is one of them…

param (
    $myAccount #(Read-Host -Prompt "Enter a user name")
    ,$serverListFile #(Read-Host -Prompt "File with list of servers")
)
if ($myAccount -eq $null){
    $myAccount = $env:username
}
if ($serverListFile -eq $null){
    $scriptpath = $MyInvocation.MyCommand.Path
    $dir = Split-Path $scriptpath
    $serverListFile = $dir + "\myservers.txt"
}

$showDebugInfo = $false
$reader = [System.IO.File]::OpenText($serverListFile)
"Listing RDP sessions for " + $myAccount
try {
    for(;;) {
        $server = $reader.ReadLine()
        if ($server -eq $null) { break }
        # process the line
        if(!(Test-Connection -Cn $server -BufferSize 16 -Count 1 -ea 0 -quiet))
        {
            " Error accessing " + $server
        }
        else
        {
            try
            {
                if ($showDebugInfo){
                    "Checking " + $server + "..."
                }
                $qwinstaResults = (qwinsta /server:$server | foreach { (($_.trim() -replace “\s+”,”,”))} | ConvertFrom-Csv)
                ForEach ($queryResult in $qwinstaResults)
                {
                    if ($queryResult -CMatch $myAccount)
                    {
                        "Logged on to " + $server
                    }
                }
            }
            catch
            {
                " Error processing " + $server
            }
        }
    }
}
finally {
    $reader.Close()
}
"Done"

Then using this script is as easy as calling it from (say) a batch file like this:

powershell.exe .\MyRDPConnections.ps1 myusername myservers.txt

Not perfect but at least it helps.

Event Scavenger 5

Seems like life is just getting more hectic these days. I’ve been running version 5 of my Event gathering tool for a while after I ‘upgraded’ the product last year already but never had the time to actually create any way to package it so others can also use it.

Part of the problem was that I decided to use a new Installer technology (thanks to the brilliant minds at MindLessoft formerly known as Microsoft…) – Wix. Unfortunately Wix is not exactly a walk in the park thing to learn and with limited time it was very hard to create anything that is kinda useful.

Anyway, to make a short story long… I decided to just go ahead and publish the latest version with whatever installers I managed to create up to now (and hope for the best).

So, there is a new ‘stable’ release of Event Scavenger on the CodePlex site. Good luck and may the force be with you…

Windows Forms vs WPF

The following short piece is about my opinion of comparing old fashioned Windows Forms development to using WPF (Windows Presentation Foundation).

After some real experimenting, researching, googling, scratching, digging, hair pulling (what is left of it), swearing, yelling, kicking around getting a very simple WPF application to work I can seriously say that WPF is a load of … brown stuff. I’m not denying that it could be used to create really beautiful and powerful applications given enough time, patience (and hair) but, the effort to do this is making me question whether this is worth while. It has a few benefits over WinForms but they are offset by some really annoying and lacking features, not to mention that it also have all the same disadvantages that WinForm applications have (compare to stuff like Web/mobile applications). Essentially, anything you can do with WPF can also be done with WinForms with less time and effort.

Let me give a few examples.

Basic layout and design of a form

I’m sure once you are completely fluent with WPF and all the possible permutations of properties, behavior, styles etc. that you can also do basic layouts of an application very quickly. For me, knowing exactly what I wanted and even what I’m looking for, it took more that two days to create a basic interface (which I could have done in 5 minutes in WinForms). Yes, part of the problem was I’m not fluent in all that is WPF but thanks to Google I could find solution quickly every time. Despite this I had to retest every possible basic behavior of all controls – even simple things like clicking on a blank space inside a control to ensure all ‘basic’ functionality as a plain user would expect (people that have been using Windows app for years), are still the same. One of the most important fundamental concepts of UI design is to have consistency – like behavior of controls. Something like keyboard navigation was seriously not part of the WPF designers ideas.

The ListView control.

This control has been changed in several ways which could both be seen and good and bad. In WinForms this is/was one of my favorites. The way you design, code and use columns are very different from WinForm ListViews. It does give you more powerful ‘formatting’ options but this make it incredibly complex as well. Doing basic stuff like right aligning a column is not straight forward anymore. Yes, it can be done but this requires doing ‘non-standard’ things like ‘Styles’, custom code and so on. Then behavior like selecting items in the ListView has changed and even something like ‘unselecting’ all items by clicking on a blank space inside the control now requires you to write ‘extra’ code just to accomplish it. Essentially this is not the same ListView control that we were used to in WinForms but a new control that superficially looks like it.

There is however one aspect/feature of this control that I really like. The way you can bind columns to properties of an object – which by the way is the only way to use it! In general I do NOT use databinding features because it removes your ability to do really powerful things with the control and more importantly databinding controls never really work well with huge sets of data. For that reason I always populated my controls myself so I have ‘real’ control over them. That does come at the cost of having to manually always sync the displayed values on a control with the underlying data.

Summary

There might be people out there that prefer WPF over an ‘old’ technology like WinForms and possible they can create even better applications if they put their mind to it but I’m still in the WinForms camp. Then you have to keep in mind that WPF just like WinForms as a development technology is in danger of being abandoned thanks to the whole HTML5 and JavaScript mobile revolution.  WPF might become just another one of those potential (good) technologies that Microsoft killed before it had time to evolved into something really good. That is a shame.

Update:

I also discovered that WPF does not even support some VERY basic dialog boxes like browsing for a folder. I mean, FFS Microsoft, what were the developers of WPF smoking when they created this abortion of a tool/technology??

Also, they changed the very standard way of returning results from dialog/messages boxes to use a nullable boolean in stead of a usable structure. WTF??

Adding performance counters to your application (C#)

Nothing about this is exactly new or ground breaking but few developers (enterprise) these days add proper monitoring abilities to their apps. We (now that I mostly do administration and management of other peoples apps) that has to support these things don’t come equipped with x-ray eyes or ESP pills so knowing how the the internals of ‘your’ works is an issue…

Classically developers tend to use stuff like log file, event log and so on to ‘see’ what is going on inside their apps. However, these things also pick up a lot of noise so they usually get turn off for production use but that still leaves us with the requirements that we want to know ‘what your app is doing all the time’ – when we want to track it. Ok, to make a long story shorter, there is such a thing like performance counters that can help us to know if your app is performing or not. What they are and what they can do for you you can go read up on MSDN, Google etc.

Now, it appears most developers are scared of these things – or just too lazy to implement them. I’ve created a little helper class that makes it at least a little easier to implement – without all the worries about what happens if things blow up etc. It is written is such a way that if itself ‘breaks’ it should not break the rest of the app (don’t contribute to a bigger problem).

Setting it all up.

Creating a ‘Category’ is the first step in setting up a performance counter. Once it is created you don’t have to recreate it again (unless you go and delete it which would be rather stupid). The following routine do just that.

PerformanceCounterCategory InitializeCategory(string category, CounterCreationData[] creationData, string instance = "")
        {
            PerformanceCounterCategory pcc = null;
            if (!PerformanceCounterCategory.Exists(category))
            {
                if (instance.Length > 0)
                    pcc = PerformanceCounterCategory.Create(category, category, PerformanceCounterCategoryType.MultiInstance, new CounterCreationDataCollection(creationData));
                else
                    pcc = PerformanceCounterCategory.Create(category, category, PerformanceCounterCategoryType.SingleInstance, new CounterCreationDataCollection(creationData));
            }
            else
                pcc = new PerformanceCounterCategory(category);
            return pcc;
        }

All this does is create the category for you if it doesn’t exist yet or else just returns the existing one. All you specify is the name and the definitions of the counters you want to use. Optionally you can specify an ‘instance name’ which is handy if you have multiple instances of the same set of ‘things’ you want to ‘monitor’. The default is a single instance (e.g. like a global instance). Keep in mind that a single category can only have counters of one of two types – either single instance or multi-instance counters. This cannot be changed unless the whole category is deleted and recreated again.

The next step is to create run-time ‘instances’ of the counters.

PerformanceCounter InitializePerfCounter(string categoryName, string counterName, string instanceName = "")
        {
            PerformanceCounter counter = null;
            try
            {
                if (instanceName.Length > 0)
                {
                    if (IsCategoryMultiInstance(categoryName))
                        counter = new PerformanceCounter(categoryName, counterName, instanceName, false);
                    else
                        RaiseWarningMessage(string.Format("Performance category '{0}' is not set up for multiple instances! ({1})", categoryName, counterName));
                }
                else
                {
                    if (!IsCategoryMultiInstance(categoryName))
                        counter = new PerformanceCounter(categoryName, counterName, false);
                    else
                        RaiseWarningMessage(string.Format("Performance category '{0}' is not set up for single instance use! ({1})", categoryName, counterName));
                }
                if (counter != null)
                {
                    counter.BeginInit();
                    counter.RawValue = 0;
                    counter.EndInit();
                }
            }
            catch (Exception ex)
            {
                RaiseErrorMessage(string.Format("Error initializing performance counter '{0}'!\r\n{1}", counterName, ex.ToString()));
            }
            return counter;
        }

There are a couple of sub-routines not listed yet. Please just ignore for now – they will be included in the attached sample code.

Next step is just how to use them – setting the values. I tend to only use two types of counters – a ‘rate of’ and absolute values. The ‘rate of’ type of counters are typically used to track the number of events or sum of something per second while absolute values track the actual value of something as it is ‘now’ at that moment of tracking – e.g. CPU % usage.

void SetCounterValue(PerformanceCounter counter, long value)
        {
            try
            {
                if (counter == null)
                {
                    RaiseWarningMessage("Performance counter not set up or installed!");
                }
                else
                {
                    counter.RawValue = value;
                }
            }
            catch (Exception ex)
            {
                RaiseErrorMessage(string.Format("Increment performance counter error! : {0}\r\n{1}", counter.CounterName, ex.ToString()));
            }
        }
void IncrementCounter(PerformanceCounter counter)
        {
            IncrementCounterBy(counter, 1);
        }
void IncrementCounterBy(PerformanceCounter counter, long incBy)
        {
            try
            {
                if (counter == null)
                {
                    RaiseWarningMessage("Performance counter not set up or installed!");
                }
                else
                {
                    counter.IncrementBy(incBy);
                }
            }
            catch (Exception ex)
            {
                RaiseErrorMessage(string.Format("Increment performance counter error! : {0}\r\n{1}", counter.CounterName, ex.ToString()));
            }
        }

Events
In order to provide all this functionality without ‘breaking’ anything else I make use of ‘events’ e.g. RaiseWarningMessage and RaiseErrorMessage. The calling class/code don’t have to make use of the events but of course that would make troubleshooting a bit harder if needed. The code for this is fairly simple:

        public event MessageRaisedDelegate ErrorRaised;
        internal void RaiseErrorMessage(string message)
        {
            if (ErrorRaised != null)
            {
                ErrorRaised(message);
            }
        }
        public event MessageRaisedDelegate WarningRaised;
        internal void RaiseWarningMessage(string message)
        {
            if (WarningRaised != null)
            {
                WarningRaised(message);
            }
        }

Implementation
It is possible to use the utility class ‘as is’ but I would recommend doing the following to provide ‘cleaner’ code. Inheriting from the class ‘PerfCounterUtilBase’ (not shown in above code) and implementing all the specific performance counter functionality ‘you’ need is a better way to so it. The following is just example code to initialize the performance counter category and counters you want to use:

void InitializePerformanceCounters()
        {
            string lastErr = "Create performance counter category error!: {0}";
            try
            {
                CounterCreationData[] creationData = new CounterCreationData[]
                    {
                        new CounterCreationData("Clicks/Sec", "Clicks per second", PerformanceCounterType.RateOfCountsPerSecond32),
                        new CounterCreationData("Total X value/Sec", "Sum of X values per second", PerformanceCounterType.RateOfCountsPerSecond32),
                        new CounterCreationData("Total Y value/Sec", "Sum of Y values per second", PerformanceCounterType.RateOfCountsPerSecond32),
                        new CounterCreationData("Last X value", "Last X value", PerformanceCounterType.NumberOfItems32),
                        new CounterCreationData("Last Y value", "Last Y value", PerformanceCounterType.NumberOfItems32)
                    };
                InitializeCategory(Category, creationData, Instance);

                lastErr = "Initialize performance counter(s) error!: {0}";
                clicksPerSecond = InitializePerfCounter(Category, "Clicks/Sec", Instance);
                xValuePerSecond = InitializePerfCounter(Category, "Total X value/Sec", Instance);
                yValuePerSecond = InitializePerfCounter(Category, "Total Y value/Sec", Instance);
                lastXValue = InitializePerfCounter(Category, "Last X value", Instance);
                lastYValue = InitializePerfCounter(Category, "Last Y value", Instance);
            }
            catch (Exception ex)
            {
                RaiseErrorMessage(string.Format(lastErr, ex.Message));
            }
        }

Then you can simply have specific methods like these to use in your own code:

public void IncClicks()
        {
            IncrementCounter(clicksPerSecond);
        }
        public void IncXValues(long value)
        {
            IncrementCounterBy(xValuePerSecond, value);
        }
...

In ‘your’ code you simply do this then:

pcu = new PerfCounterExampleImplemetation();
pcu.ErrorRaised += new MessageRaisedDelegate(pcu_ErrorRaised);
pcu.WarningRaised += new MessageRaisedDelegate(pcu_WarningRaised);
pcu.Category = txtCategory.Text;
pcu.Instance = txtInstance.Text;
pcu.InitializePerformanceCounters();
...
void pcu_ErrorRaised(string message)
        {
            MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

void SomeMethod()
        {
            long val = GetSomeValue();

            if (pcu != null)
            {
                pcu.IncClicks();
                pcu.IncXValues(val);
                ...
            }
        }

Now go have fun…

Example code: ShowPerfCounterUtils

QuickMon 2.8

I recently got a few suggestions about additional functionality that could be useful in my QuickMon tool – extending Collector service window options and supporting TLS in the SMTP notifier. Both of these modifications have been implemented with some modifications or further enhancements.

Also recently I added a new collector to call SOAP Web services which allows you poll/test web service responses and report success/failure based on specified criteria.

In the mean while I’m looking to add some performance counter functionality into the base component of QuickMon so it would be possible to monitor it (monitor the monitor kind of idea…). The intention is that then you can see that QuickMon is actually performing work and you get some idea of how busy it is.

Then, since version 2.7 I have a new icon/logo for the product – two lighting bolts that are shaped to look like a ‘Q’ (sort of). It looks better than the previous dark colored arrow logo.

QMon3

The UI tool statuses icons have also been updated to use the logo plus the previous colored orbs/balls.

Go grab it here.

Monitor a Web Service

Ever wanted a way to monitor whether your web service is actually working or cannot monitor a resource directly and need to put a web service in between to access it? Well, I’ve added a SOAP Web service collector to QuickMon so it can monitor/alert  on issues/problems related to Web services.

See the documentation about this collector here.

A summary of the documetation:

This collector allows you to poll/query SOAP web services and interpret the results. It supports several simple ‘macros’ to make it easier to test returned values or even DataSets or Arrays.

List AD users in a group using powershell

This is not a rocket science thing since there are apparently multiple ways to do this but I had a specific requirement to quickly get a list of users for a group but only list specific properties which include the “Title” property that is not available using the AccountManagement namespace.

So without mush further ado… here is a simple script that works for me.

# Read the input parameters $GroupName
param([string] $GroupName = $(throw write-host "Please specify the group name." -Foregroundcolor Red))

$Recurse = $true

$OutputFile = "GroupUsers.csv"
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$group=[System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($ct, $GroupName)
$members = $group.GetMembers($Recurse)

$columnNames = "Name,Title,Description"
$columnNames | Out-File -FilePath $OutputFile -Encoding 'UTF8'
foreach($user in $members){
    $DE = $user.GetUnderlyingObject()
    $output = $user.name + "," + $DE.title + "," + $user.description

    Write-Host $output
    $output | Out-File -FilePath $OutputFile -Encoding 'UTF8' -append
    $output = ""
}

In order to get to the ‘Title’ property I use the ‘GetUnderlyingObject’ method to get the DirectoryEntry object which do have the ‘Title’ property. This way it makes it possible to access any/all the ‘forgotten’ properties which they never implemented in the new namespace.
Additionally it also save the output to a CSV file.