This is a dumping ground of software development topics that I've run across and found interesting (mainly .NET development). Many topics are covered more thoroughly in other places, and much of the information is gleaned from other places, and I'll try to credit those sources when possible.

Friday, December 02, 2016

C# .NET: 
How many bytes per kilobyte (KB)? How many bytes per megabyte (MB)? How many bytes per terabyte (TB)? etc. I've used constants like these many times.

public static ulong BytesPerKilobyte = (ulong)Math.Pow(2.0, 10.0);  // 1,024
public static ulong BytesPerMegabyte = (ulong)Math.Pow(2.0, 20.0);  // 1,048,576
public static ulong BytesPerGigabyte = (ulong)Math.Pow(2.0, 30.0);  // 1,073,741,824
public static ulong BytesPerTerabyte = (ulong)Math.Pow(2.0, 40.0);  // 1,099,511,627,776

Friday, March 18, 2011

SQL: Sorting NULL Values

I was ordering a result set by a field that is nullable, but wanted any rows whose value for this field was null to be at the end of the set, not the beginning. Probably should have figured this out on my own, but you know how quick Mr. Google can provide the answer. This site had me up and running in a matter of seconds:

ORDER BY
   CASE
      WHEN Region IS NULL THEN 1
      ELSE 0
   END,
   Region

SQL Server: Restore cannot process database because it is in use by this session.

I tried to restore a SQL Server 2005 database, but kept getting the following error:

Restore cannot process database 'WTF' because it is in use by this session. It is recommended that the master database be used when performing this operation.

I opened Activity Monitor and killed a couple processes hanging on the database, but got the same error. When I opened the Activity Monitor again, one process had come back. I closed SSMS trying to get rid of this process, to no avail. I googled a bit and found various people going round and round about it, then found this simple solution from The DW Experience.

The problem was that my SQL login had its "Default database" set to the database I was attempting to restore, which keeps opening a session. By changing the default database to something else, I could finally restore the database. Then I promptly set the default database back, because that's the way I like it. Since I'll probably run into this problem again, I figured I should write it up here.

SQL: Many-to-Many Database Design

Here is a useful article on handling many-to-many relationships in your database design. I especially liked the advice on creating additional indexes on the table, which I promptly put to use on the 10 link tables I am currently working with:

http://www.singingeels.com/Articles/Understanding_SQL_Many_to_Many_Relationships.aspx

Wednesday, July 07, 2010

ICO File Creation

Here's a handy site for creating an ICO file:FavIcon from Pics

Thursday, January 14, 2010

C# .NET: Updating a DataGridView Cell's BackColor

Wow, this was harder than it should have been, maybe. As usual, I just didn't feel like digging into the dirty details, so maybe it makes plenty of sense. Anyway, I had a DataGridCheckBoxColumn that when checked, I wanted to "disable" some other cells (check indicates the user is an administrator and other settings do not apply). To disable, I set the ReadOnly property for each cell and the Style.BackColor to gray. However, the BackColor change just wasn't happening, and then it was happening, but not until the check cell lost focus, and so on. Finally, the oh-so-important EndEdit call did the trick.


/// <summary>
/// Event handler for when cell content is clicked. Specifically, we are checking if the Administrator
/// checkbox state is changed and refreshing the grid so the un-necessary cells are disabled and
/// grayed-out (via the subsequent CellFormatting event).
/// </summary>
private void OnCellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (theGrid.Columns[e.ColumnIndex] != ColumnAdminCheckBox)
return;

theGrid.EndEdit(); // VERY important call or the repaint doesn't happen until the cell loses focus.
theGrid.Refresh();
}

/// <summary>
/// Event handler for when cell content is formatted. Specifically, we are checking the state of the
/// Administrator checkbox and setting the ReadOnly and BackColor of the cells that do not apply when
/// user is an administrator.
/// </summary>
void OnCellFormatting(object sender, System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
{
// Only update certain columns
DataGridViewColumn column = theGrid.Columns[e.ColumnIndex];
if (column != ColumnA && column != ColumnB &&
column != ColumnC)
return;

object obj = theGrid[theGrid.Columns.IndexOf(ColumnAdminCheckBox), e.RowIndex].Value;
if (obj == null || obj.GetType() != typeof(bool))
return;

bool admin = (bool)obj;

theGrid[e.ColumnIndex, e.RowIndex].ReadOnly = admin;
e.CellStyle.BackColor = (admin ? theGrid.BackgroundColor : Color.White);
}

Thursday, October 22, 2009

Disabling ASP.NET Session

Interesting tidbit from this MSDN page.

"You should be aware that even when not in use, sessions carry some overhead for an application. You can squeeze a little bit more performance out of your pages if you turn off sessions on pages that do not use it. Also, setting session state to read-only can also optimize pages that read but do not write data to sessions. Configure sessions in this fashion by adding an attribute to the @Page directive in one of these two ways:"

<%@ Page EnableSessionState="false" %>
<%@ Page EnableSessionState="readonly" %>

Wednesday, August 05, 2009

SQL Server - Scripting table data

Scripting data is handy for lookup tables and I found just what I needed in this stored procedure and discussion. I copied the enhanced procedure below, just in case the link ever dies.


CREATE PROCEDURE dbo.spScriptInsertStatements (
@TableName varchar(100),
@WhereClause varchar(1000) = NULL,
@OrderBy varchar(1000) = NULL
)
AS

DECLARE @sql nvarchar(MAX)
DECLARE @sqlColumns varchar(MAX)
DECLARE @sqlColumnValues varchar(MAX)
DECLARE @hasIdentity bit
DECLARE @tbl TABLE (
SortOrder int IDENTITY(1, 1) NOT NULL,
SQLText varchar(MAX) NULL
)

SET @hasIdentity = 0

SELECT @sqlColumns = COALESCE(@SqlColumns + ', ','') + COLUMN_NAME,
@hasIdentity = CASE @hasIdentity
WHEN 0 THEN COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity')
ELSE 1 END
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
AND (@OrderBy IS NULL OR COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 0)

SELECT @SqlColumnValues = COALESCE(@SqlColumnValues + '+ '', '' + ','') + CASE
WHEN DATA_TYPE IN ('varchar','nvarchar', 'char', 'nchar', 'datetime' )
THEN 'COALESCE(QuoteName(' + Column_Name + ', ''''''''), ''NULL'')'
ELSE 'COALESCE(CAST(' + Column_Name + ' AS varchar(MAX)), ''NULL'')' END
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
AND (@OrderBy IS NULL OR COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 0)

SELECT @sql = 'SELECT ''INSERT INTO ' + @TableName + ' (' + @SqlColumns + ') ' +
'VALUES ('' + ' + @SqlColumnValues +' + '')'' AS SQLText FROM ' + @TableName +
COALESCE(' WHERE ' + @WhereClause, '') + COALESCE(' ORDER BY ' + @OrderBy, '')

-- If table contains an Identity column and sorting was not specified
IF @hasIdentity = 1 AND @OrderBy IS NULL
BEGIN
INSERT INTO @tbl (SQLText) VALUES ('SET IDENTITY_INSERT ' + @TableName + ' ON ')
INSERT INTO @tbl (SQLText) VALUES ('GO ')
END

INSERT INTO @tbl (SQLText)
EXEC sp_executesql N'EXEC sp_executesql @statement = @sql', N'@sql nvarchar(MAX)', @sql

-- If table contains an Identity column and sorting was not specified
IF @hasIdentity = 1 AND @OrderBy IS NULL
BEGIN
INSERT INTO @tbl (SQLText) VALUES ('GO ')
INSERT INTO @tbl (SQLText) VALUES ('SET IDENTITY_INSERT ' + @TableName + ' OFF ')
INSERT INTO @tbl (SQLText) VALUES ('GO ')
END

SELECT SQLText FROM @tbl ORDER BY SortOrder

-- Unit Test
--
-- EXEC spScriptInsertStatements @TableName = 'glsBatchType'
-- EXEC spScriptInsertStatements @TableName = 'glsBatchType', @WhereClause = 'glsTypeSeq < 3'
-- EXEC spScriptInsertStatements @TableName = 'glsBatchType', @OrderBy = 'glsTypeCode DESC'
--
GO

ASP.NET Panel with empty GroupingText

Using the GroupingText property of an asp:Panel will cause a pretty box to surround a group of controls, but sometimes I want to have that box without the text. I set GroupingText=" " hoping it would be interpreted as no text, but instead you can see the space in the box, which is annoying. Checking out the client side HTML (and MSDN documentation), I found the panel is represented as FIELDSET and LEGEND elements. By replacing the asp:Panel elements with fieldset, and not specifying a legend, I get the caption-free box I want. Note that you may have to put your fieldset in a div to get the style you want, like width. Simple example below:

<asp:Panel runat="server" GroupingText="Group of controls" Width="300px">
A panel using GroupingText="Group of controls"
</asp:Panel>
<br />

<asp:Panel runat="server" GroupingText=" " Width="300px">
A panel using GroupingText=" " (see gap in box above?)
</asp:Panel>
<br />

<div style="width: 300px;">
<fieldset runat="server">
A fieldset to get a solid box with no text.
</fieldset>
</div>

Wednesday, February 13, 2008

C# .NET: Ignoring Alt-F4 key combination

Alt-F4 is a shortcut that closes a window. For some reason you may not be fond of this behavior. After doing some digging around, I finally found a good method of ignoring this request - overriding the ProcessDialogKey method. You can go do more research if you'd like, but the basic code is as follows:

protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == (Keys.Alt | Keys.F4))
return true;
else
return base.ProcessDialogKey(keyData);
}

Friday, February 08, 2008

Getting a Batch File's Command Line

I can't remember where I got this batch script, but it's handy for getting the complete command used to call the batch file. For instance, the text written to the file may be something like this: "C:\cmdlinetest.bat" -install -param2 some other stuff...
-------------------------------------------------------------------------

REM Set variable 'line' to first token in the command line.
set line=%0

REM Loop through the next token, concatenating value, then shifting the
REM command line to process the next token. Stop when token is empty.
:loop
set line=%line% %1
if "%1" == "" goto :done
shift
goto loop

REM Done finding command line arguments, echo to file.
:done
echo %line% > C:\cmdline.txt

Thursday, May 03, 2007

OuterXml for Java

Java can be extremely frustrating, particularily because there always seems to be many many different ways to do a simple task. For example, I needed to get a fragment from an XML document which seems easy enough. .NET has the XmlNode class which has a property OuterXml. Done. However, no such simple equivalent exists for Java, at least in my limited experience. I don't claim to be an XML expert, so I'm not about to write a diatribe. After a couple of hours, I found this guy's blog, which I used as a basis for the method below. You can figure out how to get a org.w3c.dom.Node object, that's another painful tale...


public static String getOuterXml(Node node)
throws TransformerConfigurationException, TransformerException
{
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty("omit-xml-declaration", "yes");

StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(node), new StreamResult(writer));
return writer.toString();
}

Thursday, April 05, 2007

Windows Firewall for FTP

This is silly, but it hung me up for more than a few minutes. I was trying to FTP from a laptop to my desktop PC (running Microsoft's IIS FTP server). The client would claim it was connected, then after a few seconds, report "Connection closed by remote host." So I'm guessing it's a firewall problem, and I'm right (for a change), but it was still not easy to find. So below are the screen shots of the magical checkbox I needed to check.

Thursday, February 01, 2007

Random Password Generator

I needed to create a random password. First I found this short method, which didn't work. Then I found this guy agreed with me. His code works, but not so hot in my test program. The parameterless Random constructor uses a time-based seed value (per millisecond?) so there are duplicates. The code I ended up with reuses a single Random member.

Then there's the holy grail, which was too much for the requirements I was working with, eight alphanumeric digits only. Simplicity is divine.


private Random m_random = new Random();

public string CreateRandomPassword(int length)
{
char[] chars = new char[length];

int index = 0;
while (index < length)
{
char c = (char)m_random.Next(48, 122);
if (Char.IsLetterOrDigit(c))
{
chars[index] = c;
index++;
}
}

return new string(chars);
}

Thursday, December 14, 2006

C# vs. Java

Here is an interesting comparison of C# and Java. I like the way the sections are organized by:
- Same functionality.
- Similar functionality.
- Same concept, but totally different implementation.
- Unique C# functionality
- Unique Java functionality

http://www.25hoursaday.com/CsharpVsJava.html

Wednesday, November 29, 2006

Installing IIS after Visual Studio

This is pretty lame, but it's bit me twice causing a few wasted hours. If you install IIS after Visual Studio, some ASP.NET settings aren't applied properly. After messing with permissions and other settings to no avail, I did a Repair of the .NET Framework installation and I was in business. The Microsoft article below doesn't mention the Repair, but says to use the aspnet_regiis utility. Maybe I'll try that next time...

http://support.microsoft.com/default.aspx?scid=kb;en-us;306005

Ping memory leak?

The details give me a headache, but there appears to be a leak in the 2.0 Ping class, particularily when sending asynchronously.

http://blog.downtownsoftwarehouse.com/2006/11/14/using-the-ping-class-in-net-20-without-memory-leaks/

A longer diatribe that reaches the same conclusion:
http://www.julmar.com/blog/mark/PermaLink,guid,fc83197b-ce2d-47ab-b70a-db352085b370.aspx

And just in case the links above die, here's the gist of it:
"...you must explicitly call IDisposable.Dispose(), or you’ll end up with the inherited Dispose() method which doesn’t do anything useful at all in this case. You can do this by casting the Ping object to IDisposable."


private void Refresh(Object sender, EventArgs args)
{
Ping ping = null;
try
{
ping = new Ping();
ping.PingCompleted += PingComplete;
ping.SendAsync(defaultHost, null);
}
catch
{
((IDisposable)ping).Dispose();
}
}

private void PingComplete(Object sender, PingCompletedEventArgs args)
{
((IDisposable)sender).Dispose();
}

Friday, October 20, 2006

What the...

Your mother might not find it interesting, but if you're reading this, then I bet you'll find http://thedailywtf.com quite enjoyable. It's good to hear of situations worse than your own. And if yours is worse, then submit it and we can all laugh with you.

C# .NET Click vs. DoubleClick

This is kind of silly, but slightly interesting nonetheless. I needed to create a backdoor into a WinForm app, so I chose a lucky Label to be the gatekeeper. Ten clicks on the Label control and then enter the secret password to get in. Sounds simple enough, but adding a handler for the Label's Click event didn't quite work. I'm a notorious fast clicker, and it turns out many of my clicks were actually interpretted as double clicks. So if I clicked slowly ten times, it would work. That's the long story, the short story is, I used the MouseDown event instead.

Friday, October 06, 2006

P/Invoke site

Platform invoke (a.k.a. P/Invoke or pinvoke) is the means of calling unmanaged code (typically in a DLL) from a .NET assembly. This allows you to leverage existing modules with new development. It's also useful for accessing the Win32 API when .NET doesn't quite provide the functionality you need (an all-too-common occurrence). A great site to help decipher the DllImport signature for Win32 function is http://www.pinvoke.net. It's a Wiki too, so you can add your experience to the site as you wish.

Followers