Sunday, June 6, 2010

How to make your Windows form appear “Always on Top”

Most of us would have seen and used the Task Manager which is an integral part of Windows. One key behavior exhibited by the task manager is that if its “Always on top” option is turned on, the window will remain open even if focus is moved to another window. So suppose you have notepad and task manager open and the Always on top option is turned on. Now, even if you have set the focus inside notepad and are able to type in notepad, the foreground form will still appear to be Task manager. It makes sense to have this option in applications like Task manager. For example, suppose you want to see the spikes in memory usage or network bandwidth in real time as you use a particular application. It will be easy to have the application open and use it while Task manager is on top so that the changes are visible in real time. In general, this behavior would seem appropriate for many applications that provide system level information in real time.

Having said that, usage of this option can also make sense for user applications, especially for applications which provide some features that work across multiple other applications. For example, I was recently developing an application that provides a history feature in the Windows clipboard (by default Windows clipboard allows a single item to be maintained on the clipboard so this tool was designed to have multiple items on the clipboard and allow pasting of any item from within those) and works across all Windows applications. I felt it would be great to have the Always on top kind of functionality in the form for this application since it would let users always see what is there in the clipboard currently thereby letting him choose the right text/image to paste. As it turns out, enabling this behavior for your applications is really easy if you are using .Net. All you need to do is set the property named TopMost to True for the form that you want to always appear on top. Something like,

mainForm.TopMost = true;




.Net and hence, Windows will handle the rest of the stuff for you; you don’t need to do anything else. Isn’t that really easy? I guess that’s the power that frameworks make available to developers and help in improving their productivity.

Problem with SSL in SQL Reporting Services

When you do a fresh install of the SQL Server, you get an option to install and configure or only install Reporting Services along with the Database engine. If you choose the install and configure option, the Report Server and Report Manager websites will be created and configured for you by the wizard itself (along with a bunch of other stuff like the databases used by Reporting Services). However, it seems the wizard configures the websites to use SSL and when you try to browse the websites using the default URLs – http://localhost/reports and http://localhost/reportserver, you get this error:

The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel

Digging deeper, if we look at the RSReportServer.config file which we can find in <installation directory>:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportServer (this is the location for SQL 2008 R2, for SQL 2008 the folder name should be MSRS10.MSSQLSERVER) , we can find the configuration setting which causes this. Within the <configuration> node, there should be an element as below,

<Add Key="SecureConnectionLevel" Value="2"/>





The value of the SecureConnectionLevel setting can vary from 0-3, with a higher value indicating a greater level of security. In order to avoid using SSL, we need to change the value to 0. After changing this value and saving the config file, if we try hitting the Report manager or Report server site, it should start working. One surprising thing that I found was that there was no way (at least I couldn’t find one) to change this setting from the Reporting Services Configuration Manager. Even though we can add/remove the certificates which will be used by SSL, even if we delete all certificates from the configuration manager, it still doesn’t stop using SSL. But hopefully this post will help you to change it from the config file and get rid of the error.

Tuesday, April 13, 2010

Powerful Disk management features in Windows 7

As you all might have read or heard, Visual Studio’s latest version has been shipped – VS 2010. So I decided to get rid of Visual Studio 2008 from my machine and install the latest (and greatest) version. Unfortunately, I didn’t have enough space in my hard disc for installing it – there was 6 GB free space only in my OS drive (C drive) and Visual Studio 2010 Ultimate needs 6GB of space for itself. However, I had lots of free space in the other drives so I was wondering if somehow I could magically extend the OS drive by borrowing space from the other drives. Enter Windows 7 disk management.

To start using the built in disk management utility in Windows 7, just type “disk management” in the start box and click on the “Create and format hard disk partitions” link which should appear almost instantaneously. The start menu should look something like below.

image

The disk management UI is fairly intuitive and shows information about the drives on your hard disc in a tabular as well as graphical format. This is what it showed for my machine.

image

As we can see, there are 3 drives as well as a system partition of 300MB. This snapshot shows information after I extended the drive:). The C: drive was only 40 GB earlier. So let me mention the steps that I followed to extend C: from 40GB to 60GB by taking 20GB from D: drive.

  1. Backup data from D: - I copied the data to E: since I had a lot of free space in that drive
  2. Delete the D: - We need to do this to make the space available for use in another drive. To delete the drive, right click on it in the graph and select “Delete Volume”
  3. Extend C: – To do this, right click on the C drive in the graph and select “Extend Volume”. A wizard will open up asking for the amount of space you want to add to the existing space in the drive. Enter an appropriate amount of space and complete the wizard to extend the volume
  4. Recreate D: – Right click in the unallocated space between C: and E: and select the option to create a new Simple volume. Use all the space available when prompted to enter the space to be used for the drive and complete the wizard.

NOTE: In case the UI shows “At risk” for any of the drives, it will not allow the volume extension. In this case, click on Action –> Rescan disks from the menu to refresh the drive information. This should hopefully resolve the “At risk” errors, unless there is something seriously wrong with your disc :)

I really loved the disk management utility shipped with Windows and hopefully, this post will help highlight how easy yet powerful this utility really is. Hope this also helps you in resolving similar space crunch issues.

Monday, February 22, 2010

Displaying context menu for system tray icon in C#

In the last post, I talked about creating a system tray icon for applications. Often, there is also a need to show menus when the user clicks this icon. Let’s see how we can accomplish this.

To enable menus on the system tray icon, we need to use the ContextMenuStrip control. Drop this control from the toolbox onto the form design surface. The control will be displayed in the bottom half, below the actual form. We need to do 3 things now to make the menu work:

  • Link the menu to the icon – The ContextMenuStrip only represents a menu of options. To make it work, we need to link it to another control, in our case, it is the NotifyIcon control. Select the NotifyIcon control, go to its Properties and set the ContextMenuStrip property to point to the menu control.
  • Add the menu options – Select the menu control and go to its properties. For the Items property, click on the Ellipsis to open the Items Collection Editor. Here, we can add the menu items we want to appear in the context menu
  • Add event handlers for menu options – Finally, we need to specify what should happen when the menu items are clicked. For this, we need to attach event handlers. Attaching event handlers is pretty straightforward. In the code behind, use the normal <controlName>.<eventName> += <eventHandler> syntax to specify the event handler. For example, for a control named menuExit, we can attach menuExit_Click as a Click event handler using the following line:

menuExit.Click += new EventHandler(menuExit_Click);

You can add as many menu options as you want. In fact, it is quite common to have applications like download accelerators and anti virus software to run in the background with an icon in the system tray that has huge (often multi level) menus. But now, creating such menus is no longer limited to large product companies. You also know the trick for making menus like these :-)

Monday, February 15, 2010

Difference in Repeat behavior between Windows Media Player and Winamp

Most of you would have used at the Windows media player (WMP) or Winamp or both as your music player of choice. Both of them provide 2 options to control the sequence in which songs are played. These are Shuffle and Repeat. The definition of Shuffle is the same in both the players and basically means that instead of the songs being played sequentially, they will be chosen randomly from the playlist. However, there is a subtle difference in the definition of Repeat. Let me try to highlight this difference in this post.

There are 4 combinations possible between Shuffle and Repeat. The table below highlights the behavior of each player for the various combinations.

Shuffle/Repeat combination

Windows Media Player

Winamp

Shuffle – OFF
Repeat – OFF
Plays songs in sequence. Cycles to the beginning of the list once the last song is played Plays songs in sequence. Stops playing songs once the last song is played
Shuffle – OFF
Repeat – ON
Plays songs in sequence. Cycles to the beginning of the list once the last song is played Plays songs in sequence. Cycles to the beginning of the list once the last song is played
Shuffle – ON
Repeat – OFF
Plays songs randomly. Cycles to the beginning of the list once the last song is played Plays songs randomly and stops when each song in the playlist has been played once
Shuffle – ON
Repeat – ON
Plays songs randomly. Songs can be repeated even when all the songs in the playlist have not yet been played at least once Plays songs randomly. Songs can be repeated even when all the songs in the playlist have not yet been played at least once

 

As is evident from the above table, the difference in the behaviors of both the players comes when Repeat is OFF. This is because of 2 reasons:

  • Repeat in Winamp means turning repeat of song and playlist on/off
  • Repeat in WMP only means turning repeat of songs on or off. Repeat of playlist is not under the control of the user. Once the playlist is complete, WMP will automatically cycle back to the beginning of the list.

Given this understanding of Repeat, when using Shuffle in WMP, based on the playlist type, we should set the Repeat as on/off as follows:

  • Playlist with few songs : We might want to set Repeat OFF so that all the songs in the playlist have an equal chance of being played. No song will be repeated till ALL songs have been played once
  • Playlist with large number of songs : We might want to set Repeat ON otherwise we might have to wait a long time before a song we hear once gets played again

Hope this post helps in clarifying the difference in behavior of both these popular players and aids you in choosing the right setting when listening to your favorite songs.

Thursday, February 4, 2010

Creating a system tray application in C#

Many a times, we want to create applications that sit in the system tray (the area where the clock, volume control etc are displayed) instead of/in addition to the taskbar. Or, when the user minimizes the application window, we would want it to work in the background and display an icon for it in the system tray. Doing this is very easy and can be accomplished by the following steps:

  1. Hiding the form
  2. Turn OFF the taskbar display
  3. Setting properties for display in system tray
  • Hiding the form – This is pretty straightforward and needs just 2 lines of C# code
   1: this.WindowState = FormWindowState.Minimized;


   2: this.Hide();






where “this” refers to the form being hidden




  • Set taskbar display to be OFF – This needs setting just a single property which can be set either at design time or at run time, as follows





   1: this.ShowInTaskbar = false;




again, “this” refers to the form being hidden




  • Setting properties for display in system tray – To display the application icon in the system tray, we need to drop the NotifyIcon control from the toolbox onto the form. The control will be displayed under the actual form on the design surface. After dropping the control, we can set the following properties for it:



    • Text – This is the text that will be displayed when you hover the mouse over the system tray icon


    • Icon – An "ico” icon file which will be used as the icon in the system tray


    • BalloonTipText – The text which will be displayed when you enable the balloon tip


    • BalloonTipTitle – The title of the balloon tip when it is enabled




So there you have it, 3 simple steps to enable system tray display for your application.

Sunday, November 8, 2009

SQL Server 2008 Compression Features

SQL Server 2005 introduced the concept of variable length fields to enable space conservation by using only the storage needed for the value even if the declared storage is more than that. SQL Server 2008 takes storage space saving not only a step further, but a giant leap ahead. This is especially important since databases in today’s times are reaching sizes of Tera bytes and beyond. I will be covering some high level concepts behind the compression features introduced in SQL 2008. For more detailed reading, you can follow the links provided at the bottom of the post.

Essentially, SQL 2008 provides 2 ways to compress the data:

  • Backup Compression
  • Data Compression
    • Row Compression
    • Page Compression

Backup compression enables shrinking the size of the backup files when they are written to the file system. Since almost all important databases have a backup strategy in place, this is a feature that should be applicable in a wide range of scenarios. It can be enabled either on an individual basis using an option in the Backup command or using the system SP sp_configure. Restoring would be the same regardless of whether the backup is compressed or not except the fact that older versions of SQL Server would not be able to read the compressed backups.

Data compression is a slightly more complex topic as compared to Backup compression. Let me first explain the 2 compression techniques in Data compression.

  • Row compression uses variable length storage technique for all data types, including fixed data types. For the application, it would still seem that the fixed types are implemented as such but under the hood, SQL Server stores them using variable storage. Row compression doesn’t impose a very big overhead on the system and should generally be enabled on all tables and indexes
  • Page compression is a slightly more complicated beast. First and foremost, when you enable Page compression, Row compression is enabled automatically. Additionally, Page compression uses something called Column prefix and Page dictionary to provide a greater degree of compression.
    • In Column prefix, SQL Server stores the common values at the beginning of values in a column in the CI(Compression Information) section and the actual cells will have pointers to the CI block
    • For Page dictionary, a 'dictionary' of repeating column values on the given page is created in the CI structure, and again, pointers to the value in the dictionary are left in the original column value location

Page compression involves additional overhead in case of querying as well as inserts and updates. So it must be enabled selectively. Generally, it should be enabled only for tables and indexes with very few updates and/or high number of scans.

SQL Server also provides some DMVs and system SPs to help developers/administrators to get a better understanding of the impact and possible gains from enabling compression. Some of these are:

  • sp_estimate_data_compression_savings - Allows you to estimate the savings you will be able to perceive for a given table/index
  • sys.dm_db_persisted_sku_features - To determine whether a database is using compression
  • data_compression_desc column in the catalog view sys.partitions - To determine what is compressed, and how (row or page)
  • sys.dm_db_index_operational_stats - To determine the number of Scans (S) and Updates (U) on a table

Some additional points about SQL Compression:

  • The data compression feature is available in the Enterprise and Developer editions of SQL Server 2008 only
  • It is recommended to compress one table, index, or partition at a time in most cases because compression requires additional temporary structures to be created which impose space and processing overheads
  • It is also recommended to compress smaller objects before larger ones so that the space freed up by the smaller ones can be utilised as temporary storage when compressing the larger objects.
  • After data compression has completed, the space saved is released to the respective data file(s). However, the space is not released to the file system, because the file size doesn’t reduce automatically as part of data compression. There are ways to release the space to the file system, including using DBCC SHRINKDATABASE and DBCC SHRINKFILE

As mentioned earlier, I tried to cover most of the high level concepts that one would need to understand for using compression. There are some excellent articles on MSDN that cover various implementation details and performance benchmarks regarding compression. I am providing a couple of links below, which you can use for reference.

Data Compression: Strategy, Capacity Planning and Best Practices

Katmai (Sql 2008) - Data Compression (including Backup Compression)