Wednesday, February 25, 2009
How to programaticaly detect .NET framework installed
Reading the registry:
C++ example:
http://astebner.sts.winisp.net/Tools/detectFX.cpp.txt
C# example:
http://www.codeproject.com/KB/dotnet/frameworkversiondetection.aspx
Browsing the file system folder %systemroot%\Microsoft.NET\Framework:
http://msdn.microsoft.com/en-us/kb/kb00318785.aspx
Tuesday, February 24, 2009
Browsing trough files programaticaly
To browse trough the filesystem .net provides in System.IO namespace two very useful functions: Directory.GetFiles and Directory.GetDirectories. What those functions do is quite obvious. Simple example below.
Public Function SearchForFile(ByVal targetDirectory As String, ByVal fileToFind As String, ByVal recursive As Boolean) As String Dim fileName As String = String.Empty 'ProcessFolder(targetDirectory) If fileToFind IsNot Nothing Then Dim fileEntries As String() = Directory.GetFiles(targetDirectory) ' Process the list of files found in the directory. For Each fileName In fileEntries If fileName.ToLower.Contains(fileToFind) Then Return fileName End If Next fileName If recursive Then Dim subdirectoryEntries As String() = Directory.GetDirectories(targetDirectory) ' Recurse into subdirectories of this directory. Dim subdirectory As String For Each subdirectory In subdirectoryEntries SearchForFile(subdirectory, fileToFind, recursive) Next subdirectory End If End If Return fileName End Function
Friday, February 20, 2009
How to set backgroud color of MDI
Since the property is not available at design time, all you need is a simple loop through controls (probably in load event) to set the background color of mdi window.
foreach (Control ctrl in Controls) { if (!(ctrl is MdiClient)) continue; string colorName = ConfigurationManager.AppSettings["Dialog.BackColor"]; if (colorName == null) continue; Color color = Color.FromName(colorName); //checks if color is transparent, mdiclient.backcolor doesn't support transparent colors if (color.A != 0) ctrl.BackColor = Color.FromName(colorName); }
Monday, February 16, 2009
How to make an simple SMTP client
Imports System Imports System.Net Imports System.Net.Mail Imports System.Net.Mime Imports System.Threading Imports System.ComponentModel Module SimpleAsynchronousExample Dim mailSent As Boolean = False Private Sub SendCompletedCallback(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs) 'Get the unique identifier for this asynchronous operation. Dim token As String = CType(e.UserState, String) If (e.Cancelled) Then Console.WriteLine("[{0}] Send canceled.", token) If (e.Error IsNot Nothing) Then Console.WriteLine("[{0}] {1}", token, e.Error.ToString()) Else Console.WriteLine("Message sent.") End If mailSent = True End If End Sub Sub Main(ByVal args As String()) 'Command line argument must the the SMTP host. Dim client As SmtpClient = New SmtpClient("hostname") '' Specify the e-mail sender. '' Create a mailing address that includes a UTF8 character '' in the display name. Dim from As MailAddress = New MailAddress("someone@test.com", "Some" + " One", System.Text.Encoding.UTF8) ' Set destinations for the e-mail message. Dim toAddress As MailAddress = New MailAddress("someone@test.com") '' Specify the message content. Dim message As MailMessage = New MailMessage(from, toAddress) message.Body = "This is a test e-mail message sent by an application. " ''Include some non-ASCII characters in body and subject. message.Body += Environment.NewLine + "This is a mail" message.BodyEncoding = System.Text.Encoding.UTF8 message.Subject = "test message 1" + "test message" message.SubjectEncoding = System.Text.Encoding.UTF8 ' Set the method that is called back when the send operation ends. AddHandler client.SendCompleted, AddressOf SendCompletedCallback ' The userState can be any object that allows your callback ' method to identify this send operation. 'For this example, the userToken is a string constant. Dim userState As String = "test message1" client.SendAsync(message, "this is me") Console.WriteLine("Sending message... press c to cancel mail. Press any other key to exit.") Dim answer As String = Console.ReadLine() '' If the user canceled the send, and mail hasn't been sent yet, '' then cancel the pending operation. If (answer.StartsWith("c") AndAlso mailSent <> False) Then client.SendAsyncCancel() End If ''Clean up. message.Dispose() Console.WriteLine("Goodbye.") End Sub End ModuleIn order for example to work hostname of a SMTP server must be entered. Also make sure to have relay rules set. If you want no rule to apply set:
Friday, February 13, 2009
Pagging as concept part2
SELECT *
FROM (SELECT ROWNUM row_num, column1, column2
FROM (SELECT column1, column2
FROM table
)
WHERE ROWNUM <= :page_num * :rec_count)
WHERE row_num > (:page_num - 1) * :rec_count
Rec_count tells us how many records we want on a page, an page_num is the number of page we want.
I like this version more that maybe more used version:
SELECT *
FROM (SELECT ROWNUM, table_name.*
FROM (SELECT *
FROM table) table_name
WHERE ROWNUM <= 200)
WHERE ROWNUM <= 101
Whole point of doing sub select is to limit the number of results with inner select and then extract the rows required with outer select.
Simple implementation of SQL for paging modification would look something like:
Public Function GetSQL(ByVal sqlin As String, ByVal sort As String, ByVal table As String, ByVal page As Integer, ByVal rec_count As Integer) As String
Dim sql2 As String = " SELECT * FROM (SELECT ROWNUM as ROW_NUM, " & table & ".* FROM "
sql2 = sql2 & " ( " & sqlin & " " & sort & " ) " & table
sql2 = sql2 & " WHERE ROWNUM <= " & page & " * " & rec_count & ") WHERE ROW_NUM > (" & page & " - 1) *" & rec_count
Return sql2
End Function
Monday, February 9, 2009
Paging as a concept
Paging is yet another mysterious word used in by software developers. In principle it means that instead of downloading all the data returned by a query at once from database, we download subset (page)(first 100 rows) and when user browse through records, we fetch another page, and continue to do so until we have downloaded all the data. When applying this concept we presume that user will narrow its search when he cannot find what he was looking for in first n pages. If done correctly paging can have a significant impact on application performance.
Here is how we do it on all the databases that support rownum:
SELECT * FROM
( SELECT rownum as row_num,
column1,
column2,
column3,
FROM
datatable
)
WHERE ROWNUM <= 201 and ROW_NUM >= 300
Downside of paging is that it does not guaranty the coherence of data. If data in database is modified during the paging, duplicates or missing data my appear.
Thursday, February 5, 2009
Wednesday, February 4, 2009
How to easily produce CSV files
If dataset (datatable) is the source then:
Public Shared Sub ProduceCSV(ByVal dt As DataTable, ByVal file As System.IO.StreamWriter, ByVal WriteHeader As Boolean)
Dim i As Int32
Dim j As Int32
Dim myCIintl As System.Globalization.CultureInfo
myCIintl = System.Globalization.CultureInfo.CurrentCulture
If (WriteHeader) Then
Dim arr(dt.Columns.Count - 1) As String
For i = 0 To dt.Columns.Count - 1
arr(i) = dt.Columns(i).ColumnName
arr(i) = GetWriteableValue(arr(i))
Next
file.WriteLine(String.Join(myCIintl.TextInfo.ListSeparator, arr))
End If
For j = 0 To dt.Rows.Count - 1
Dim dataArr(dt.Columns.Count - 1) As String
For i = 0 To dt.Columns.Count - 1
Dim o As Object = dt.Rows(j)(i)
dataArr(i) = GetWriteableValue(o)
Next
file.WriteLine(String.Join(myCIintl.TextInfo.ListSeparator, dataArr))
Next
End Sub
Making csv files from reader:
Public Shared Sub ProduceCSV(ByVal reader As DbDataReader, ByVal file As System.IO.StreamWriter, ByVal WriteHeader As Boolean)
Dim i As Int32
Dim myCIintl As System.Globalization.CultureInfo
While reader.Read
myCIintl = System.Globalization.CultureInfo.CurrentCulture
If (WriteHeader) Then
Dim arr(reader.FieldCount) As String
For i = 0 To reader.FieldCount - 1
arr(i) = reader.GetName(i)
arr(i) = GetWriteableValue(arr(i))
Next
file.WriteLine(String.Join(myCIintl.TextInfo.ListSeparator, arr))
WriteHeader = False ''header zapisemo samo enkrat
End If
Dim dataArr(reader.FieldCount - 1) As String
For i = 0 To reader.FieldCount - 1
Dim val As String
'If reader.GetName(i).ToLower.Contains("stid") Then
' val = String.Format("""STID:{0}""", reader.Item(i))
'Else
val = GetWriteableValue(reader.Item(i))
'End If
dataArr(i) = val
Next
file.WriteLine(String.Join(myCIintl.TextInfo.ListSeparator, dataArr))
End While
End Sub
Since csv in my case contain millions of records I use reader as a source to limit memory usage and boost performance.
How to make binding to objects (classes) work
Public Class ListOfUnits
Private _ID As Integer
Public Property ID() As Integer
Get
Return _ID
End Get
Set(ByVal value As Integer)
_ID = value
End Set
End Property
Private _UNIT As String
Public Property UNIT() As String
Get
Return _UNIT
End Get
Set(ByVal value As String)
_UNIT= value
End Set
End Property
end class
then make another class, that inherits from bindinglist(of T), where T is your class name
Public Class SortableListOfUnits
Inherits BindingList(Of ListOfUnits)
Private mIsSorted As Boolean
Private m_SortDirection As ListSortDirection
Private m_SortProperty As PropertyDescriptor
Protected Overrides ReadOnly Property SortPropertyCore() As System.ComponentModel.PropertyDescriptor
Get
Return m_SortProperty
End Get
End Property
Protected Overrides ReadOnly Property SortDirectionCore() As System.ComponentModel.ListSortDirection
Get
Return m_SortDirection
End Get
End Property
Protected Overrides ReadOnly Property SupportsSortingCore() As Boolean
Get
Return True
End Get
End Property
Protected Overrides Sub ApplySortCore(ByVal prop As System.ComponentModel.PropertyDescriptor, ByVal direction As System.ComponentModel.ListSortDirection)
Dim items As System.Collections.Generic.List(Of ListOfUnits) = DirectCast(Me.Items, List(Of ListOfUnits))
If Not IsNothing(items) Then
m_SortDirection = direction
m_SortProperty = prop
items.Sort(New PropertyComparer(Of ListOfUnits)(prop.Name, direction))
mIsSorted = True
Else
mIsSorted = False
End If
Me.OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1))
End Sub
Protected Overrides ReadOnly Property IsSortedCore() As Boolean
Get
Return mIsSorted
End Get
End Property
Protected Overrides Sub RemoveSortCore()
mIsSorted = False
End Sub
End Class
3) all you need now is a property comparer or in simple words a class that will implement a IComparer(Of T) interface if you want to make your own comparing logic. I have found a excelent implementation of icomparer online, that is generic, since i do not want to write comparer logic for every class.
Imports System.Reflection
Public Class PropertyComparer(Of T)
Implements IComparer(Of T)
Private FPropertyName As String = ""
Private FDirection As SortDirection
Public Sub New(ByVal propertyName As String)
FPropertyName = propertyName
FDirection = SortDirection.Ascending
End Sub
Public Sub New(ByVal propertyName As String, ByVal Direction As SortDirection)
FPropertyName = propertyName
FDirection = Direction
End Sub
' Try to sort based on type using CompareTo method
' Multiple by FDirection to alternate sort direction
Public Function Compare(ByVal x As T, ByVal y As T) _
As Integer Implements System.Collections.Generic. _
IComparer(Of T).Compare
Dim propertyX As PropertyInfo = x.GetType().GetProperty(FPropertyName)
Dim propertyY As PropertyInfo = y.GetType().GetProperty(FPropertyName)
Dim px As Object = propertyX.GetValue(x, Nothing)
Dim py As Object = propertyY.GetValue(y, Nothing)
If (TypeOf px Is Integer) Then
Return Compare(Of Integer)(CType(px, Integer), CType(py, Integer)) * FDirection
End If
If (TypeOf px Is Decimal) Then
Return Compare(Of Decimal)(CType(px, Decimal), CType(py, Decimal)) * FDirection
End If
If (TypeOf px Is DateTime) Then
Return Compare(Of DateTime)(CType(px, DateTime), CType(py, DateTime)) * FDirection
End If
If (TypeOf px Is Double) Then
Return Compare(Of Double)(CType(px, Double), CType(py, Double)) * FDirection
End If
If (TypeOf px Is String) Then
Return Compare(Of String)(CType(px, String), CType(py, String)) * FDirection
End If
If (TypeOf px Is Decimal) Then
Return Compare(Of Decimal)(CType(px, Decimal), CType(py, Decimal)) * FDirection
End If
Dim methodX As MethodInfo = propertyX.GetType().GetMethod("CompareTo")
If (methodX Is Nothing = False) Then
Return CType(methodX.Invoke(px, New Object() {py}), _
Integer) * FDirection
Else
Return 0
End If
End Function
Private Function Compare(Of K As IComparable)(ByVal x As K, _
ByVal y As K) As Integer
Return x.CompareTo(y)
End Function
Public Enum SortDirection
Descending = -1
Ascending = 1
End Enum
End Class