Programming in C#, Java, and god knows what not

Gone

On 23rd August, 2008 Lutz Roeder gave .NET Reflector development to Red Gate Software. At that time Red Gate agreed to provide free community version and everything seemed same. There was paid version available with Visual Studio integration but for occasional need you could always count on free one. This is bound to change with 1st March. Red Gate Software decided to require $35 for what was once known as freeware.

I remember .NET Reflector as a great tool for debugging assemblies that you have no source for. It helped me more than once to navigate my way around some obscure bug that would trigger in other people’s library. I will not even mention how much I learned by viewing other people’s code. :)

I will not go into blaming anyone for killing free version of this tool. Lutz was quite in his rights to give it to Red Gate and I assume that Red Gate is allowed to ask money for it. I also think that most of attacks on Red Gate’s forum are unfounded and uncalled for. Reality sucks, learn to live with it. I am just sad that this beautiful tool will leave my toolbox for now.

Will I buy a licence? Maybe some time, but not right now.

[2012-11-07: Licence for .NET Reflector is $95 these days but there is freeware alternative from JetBrains: dotPeek]

Legacy

When I did redesign of site into blog format some things got lost. I was quite surprised that those files, not linked from my site, were still getting bunch of hits, especially legacy VB 6.0 code. It seems that there are still some people using it.

By popular demand, here is all that code in single archive. Do note that even most youngest code is from 2004 with most of code being even older. I bring you also original descriptions, nothing is modified in any way.

Download is here.

VB.NET 2.0

  • DnDTabControl How to reorder TabPages inside TabControl.
  • Highlander Detecting already running program and letting first instance know that.

VB.NET 1.1 DLLs

  • Medo This DLL is compiled version of classes given on these pages and some classes without source code. There is Profile class that lets you save Form position, ListView Columns witdh and more. OleDb class lets you to easily perform one line queries. There are few more CRC algorithms including CRC8. There is also many more classes that can prove to be useful. There are not too many samples now but more of them will come.

VB.NET 1.1 Classes

  • BigOFD OpenFileDialog class implemented in .NET has small problem. Buffer size is too small to handle more than few hundred files or even less. This replacement was designed to give you direct access to Windows API and to allow custom buffer sizes. It is mostly compatible with .NET OpenFileDialog so no porting problems should occur.
  • Bitwise This class gives you ability to perform unsigned Shift left, Shift right, Rotate left and Rotate right bitwise operations over Integer and Short (aka Int16 and Int32) data types. This is very usefull in some algorithms that must be implemented in unsigned logic that is currently unupported by Visual Basic.
  • COM This class can be used to perform read and write operations on serial communication ports (COM). It has basic example until I gather some time to make better one.
  • CRC-16 This class gives you ability to check data integrity with CRC16 algorithm.
  • CRC-32 This class gives you ability to check data integrity with CRC32 algorithm.
  • RC4 This class enables you to crypt your data using fast RC4 algorithm.
  • Registry VB.NET includes its own vision of registry access. This vision makes everything possible but its drawback is in number of code lines for most simple things. By using this class you can write/read REG_DWORD and REG_SZ data types in one line.
  • TagItem First ListBox control use in .NET was very confusing for me. Like, I am sure many of you, I used ItemData to fill in ID of somekind. But there is no ItemData in Kansas anymore so “Dorothy” had to find another solution. It took some time to see that new “Items.Add” formula takes Object as argument. From there, everything was downhill. By using Text and ID as an argument, this class can be successfully used to retrieve same information later. One Object argument is added for “just in case” situations.

VB.NET 1.1 Macros

  • VB6ver Enables you to use VB6 style versioning in .NET enviroment.

Java

  • DateTime 1.10 When I started to learn Java, its date management model drove me crazy. It was too much complicated for simple calculations. Here is class that enables date/time management in simple .NET alike class.
  • Road to Java This script is diary of differences I notice while learning Java. It is not complete nor it will ever be but I will work on it.

VB 6.0 Classes

  • APIFile This class was developed to open files via API which has advantage of being able to trim them by using Length property.
  • CRC32 This class gives you ability to check data integrity with standard CRC32 algorithm.
  • SHA-1 This class enables you to encrypt your passwords with SHA-1 hash (one-way) algorithm.
  • Window You can enumerate open windows by using this class.
  • XY This class enables you to draw in X-Y coordinate system. Usefull for drawing mathematical functions graphs.

VB 6.0 Controls

  • CmnDlg Complete substitude for CommonDialog control. No .ocx needed.
  • Contain This control can be used as container for other controls.
  • Progress Complete substitude for ProgressBar control. No .ocx needed.
  • TextComplete This control gives you AutoComplete ability.
  • TrayIcon This control gives you option to show icons in Tray notification area.

VB 6.0 Modules

  • Browse This module enables you to show Browse dialog.
  • CRC16 This module gives you ability to check data integrity with standard CRC16 algorithm.
  • CRC32 This module gives you ability to check data integrity with standard CRC32 algorithm.
  • Date This module enables you to find out when is Easter.
  • HrBox This module enables you to show Croatian MsgBox and InputBox.
  • RC4 This module enables you to crypt your data using fast RC4 algorithm.
  • Registry This module enables you to access Windows registy.
  • SHA-1 This module enables you to encrypt your passwords with SHA-1 hash (one-way) algorithm.
  • Shuffle This module contains functions for shuffling elements of zero-based arrays (for playlists, cards, etc.).
  • ShutDown This module enables you to shut down your computer or put it in sleep mode from your program.
  • Swap This module enables you to Swap variables in single instruction.

Mono, Ubuntu and Clipboard

Reading clipboard in .NET is fairly straightforward.

   var text = Clipboard.GetText();

Once you stumble into Mono under Linux, things tend to change. Clipboard works only inside your application, rest of system works on different plane altogether. In order to get text from system clipboard we need to have following code:

    Gtk.Clipboard clippy = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
    var text = clippy.WaitForText();

And here comes the problem. These functions need reference to both gdk-sharp and gtk-sharp. Unfortunately this also means that you cannot run it without MONO runtime. You can forget running application under Microsoft’s .NET Framework. Even if we don’t use those functions our applications will fail upon startup since it cannot resolve all references.

I solved this issue by having separate .dll for clipboard operations on Linux but I haven’t created any reference to it. In order to determine clipboard content I use reflection to load it (only if we are on Mono):

private string GetClipboardText() {
    if (IsRunningOnMono) {				
        var fullExePath = new FileInfo(Assembly.GetExecutingAssembly().Location);
        var gtkAss = Assembly.LoadFile(Path.Combine(fullExePath.DirectoryName, "GtkClipboard.dll"));
        var assMethod = gtkAss.GetTypes()[0].GetMethod("GetGtkText");
        txtClipboard.Text = assMethod.Invoke(null, new object[] { }) as string;
    } else {
       txtClipboard.Text = Clipboard.GetText();
    }
}

private static bool IsRunningOnMono {
    get {
        return (Type.GetType("Mono.Runtime") != null);
    }
}

And what should we put in our .dll? It ends up that it is quite simple code:

public static class Clipboard {
    public static String GetGtkText() {
        Gtk.Clipboard clipboard = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
        if (clipboard != null) {
            return clipboard.WaitForText();
        } else {
            return "";
        }
    }
}

P.S. You will notice here that reflection code loads first class that comes in array. Since I only have one class in that whole .dll this is not an issue. If you add more classes to that assembly take care that you select correct one.

Showing Form in Mono

When I develop application that should be usable on Linux I usually program it in C# with Visual Studio. From time to time I test it with Mono Migration Analyzer. End result is usually runnable under Linux after some further debugging. This time I had to create application that would be used primarily under Linux so I took different approach - MonoDevelop.

Most difficult thing to get used to after transfer from Visual Studio world is lack of Windows Forms designer; everything needs to be done by hand. Doing that I stumbled upon strange behavior. Take this simple code:

private void SomeButton_Click(object Sender, EventArgs e) {
    using (var frm = new SomeForm()) {
        frm.ShowDialog(this);
    }
}
...
internal class SomeForm : Form {
}

This code is dead simple - there is no chance of error. However this code also doesn’t work properly under Mono 2.6 (I haven’t checked other versions). Form will be shown first time button is clicked but not second time. What puzzled me the most is fact that I knew that that ShowDialog should work - other .NET application that I used under Linux worked perfectly.

First rule of bug-triage is to trim code as much as possible to determine which line is problematic one - there was nothing to trim here and I still had a bug. As it turned out, this bug shows it’s ugly head only if you don’t have any controls on Form. As soon as first control is added everything works as expected. I haven’t seen this behavior in my other applications since I never had an empty form to show.

It just shows that testing smallest possible working code is not always an answer.

White-on-White Spinner

Illustration

As far as Android goes, I like it’s light theme much better that black one. It is matter of preference really since both are equally functional.

First time I used Spinner control I noticed interesting result - I got white text on white background. While other controls used theme that was defined application wide Spinner forced white background on it’s drop-down. Black theme defines white text on black background, Spinner forces white background - white text on white background is their bastard offspring.

Solving this took a little bit of time and single line. It was easiest to change background color for drop-down just after it is inflated:

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {				
    if (convertView == null) {			
        View view = _inflater.inflate(android.R.layout.simple_list_item_single_choice, parent, false);
        view.setBackgroundColor(Color.BLACK);
        ((TextView)view).setSingleLine();
        ((TextView)view).setEllipsize(TruncateAt.END);
        convertView = view;
    }
    return super.getDropDownView(position, convertView, parent);
}

P.S. It might be as well that I broke something to get Spinner behave this weirdly - I haven’t investigated much further after I got the result.

ConnectionString Loses Password Field

Illustration

One application used ConnectionString that read “Server=.\SQLEXPRESS; Database=MyDatabase; MultipleActiveResultSets=true; User ID=MyUser; Password=MyPassword; Connect Timeout=10;”. Yes, I know all dangers of transporting user id and password in this manner, but trust me, there was no other choice for this particular scenario. It worked for quite some time and I was satisfied with it.

As upgrade went, I needed one additional connection. I saw no problem with it, I did it plenty of times:

public SqlConnection Clone(SqlConnection original) {
    var clone = new SqlConnection()
    clone.ConnectionString = original.ConnectionString
    return clone;
}

However, in this particular scenario, all I got was “Login failed for user…” message. After some checking, I noticed one peculiar thing. My connection string, as far as SqlClient was concerned, was “Server=.\SQLEXPRESS; Database=MyDatabase; MultipleActiveResultSets=true; User ID=MyUser; Connect Timeout=10;”. My Password field was completely missing!

ConnectionString gets cleaning treatment and password just gets omitted. Solution comes in form of one additional parameter. If we add “Persist Security Info=true;” to out ConnectionString SqlConnection will give us enough rope to hang ourself and Password field will be preserved.

Visual Studio 2010 SP1 Beta

Illustration

Visual Studio 2010 has SP1 lurking around. It just arrived in form of beta accessible only to MSDN subscribers but I am sure that general public will get it at Thursday.

Total download size is 593 MB in single ISO. Exact content of package was not published (as time of writing this post) so I risked my main development machine and I installed this service pack beta based on faith alone. Installation took around an hour with need for single restart and with annoying flashing of taskbar button every few minutes (probably as each independent package was queuing-up).

I must confess that I see no big difference. Everything is where it should be. There might be some new templates and there is probably a lot of bug-fixing around. However, everything appears to be stable and this is best thing I can say about any beta.

As expected, it also contains new offline Help Viewer. Cries for normal offline viewer started with Visual Studio 2010 beta and only grew stronger with final release. This service pack finally brought something that works as good as offline viewer in times of Visual Studio 6.

I am eagerly waiting to see which features I missed and what exactly is in this service pack. In meantime I hope that my machine will not crash… :)

[2010-12-08: Official announcement is available now.]

Fixed Width Columns in ListView

I like .NET’s ListView control and I often end up using it in places where even ListBox would suffice. ListView with single column in Details view is exactly look that I usually shoot for.

Of course, width of column needs to be adjusted in order to maximize usable space. This is easily done by simply resizing column to fit width of ListView but with some space reserved for vertical scrollbar. Here is code for e.g. Form_Load:

listView_columnTest.Width = listView.ClientRectangle.Width - SystemInformation.VerticalScrollBarWidth;

And, if there weren’t any users, that would be enough. Problem is that any user can change with of column and thus disturb our delicate balance :). Solution is in handling ListView.ColumnWidthChanging event. Somebody would expect that setting e.Cancel to true would be enough but this is actually not a case. Full solution requires two lines:

private void lsvFilters_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e) {
    e.NewWidth = ((ListView)sender).Columns[e.ColumnIndex].Width;
    e.Cancel = true;
}

Benchmarking SQL

When I work on improving database performance, I follow three simple steps: measure, measure and measure. Basic tool for that is simple timer. In SQL Server syntax that would read something like this:

CHECKPOINT; DBCC DROPCLEANBUFFERS;
DECLARE @StartTime DATETIME = GETDATE();

SELECT SomeField1, SomeField2 FROM SomeTable WHERE (SomeFieldN='Something');

SELECT [Duration] =  DATEDIFF(ms, @StartTime, GETDATE());

Although code is pretty much straightforward, first line requires some explanation.

SQL Server is pretty smart tool with lot of caching going around and testing on cached data is not something that gives consistent results. CHECKPOINT statement ensures that all dirty pages are written to disk and DBCC DROPCLEANBUFFERS ensures that cache is cleaned. Those two statements together basically force database to be in worst-case-scenario for performance but in best state for testing.

Of course, not all decisions can be made by this simplest of all tests. However, it will serve as pretty good rule of a thumb.

Should I REORGANIZE or REBUILD?

As I work on adding new stuff to existing database there is good chance that indexes will get fragmented. On quite a few occasions I got them in 90% fragmentation range. And that affects performance.

SQL Server 2008 has two main ways to fight fragmentation. One is REORGANIZE command (e.g. “ALTER INDEX ALL ON MyTable REORGANIZE”). This will do simple shuffling of existing data. No new allocations will be done. Unfortunately this also means that, especially in case of multiple files, some things will stay unoptimized.

For worst-case-scenarios there is REBUILD (e.g. ALTER INDEX ALL ON MyTable REBUILD). This command creates new index instead of current one. This will probably cause some new allocations and thus it will take a little longer, but final result will be impeccable.

Microsoft has really nice page that explains both how to check fragmentation and what can be done to solve it. Rule of thumb there is that you should REBUILD once fragmentation is over 30% and REORGANIZE when fragmentation is lower. I view this as quite good rule if you have SQL Server Enterprise. However, if Enterprise is not your edition of choice, things change a little.

Since I mostly work with SQL Server Express, only question that I ask my self is whether database can be offline. Below Enterprise edition, REBUILD operation CAN NOT be done while other operations are pending. If database has to be accessible, only option is REORGANIZE.

I do not mind that much since REORGANIZE is usually sufficient. And, if changes are large enough that they would cause real fragmentation mess, they are also big enough to allow for offline REBUILD.

I find that Microsoft has right to limit some functionality (in this case online rebuilds) to certain editions of their software. However, I do hate when they don’t find it necessary to document this “small” difference. On other had, if Microsoft did all documenting, I would have nothing to write about.

P.S. This represents my view as a programmer, database administrator might not approve this. :)