Code Repo    |     RSS
MD's Technical Sharing



Thursday, October 30, 2008

Make a .NET application run at startup

Only applicable to .Net desktop application. For .NET compact framework application, use SHCreateShortcut and creates a shortcut in \Windows\Startup folder.


'name of application to be set in registry key
Private Const appname As String = "MyAppName"

'check whether or not the application is set to run at startup via registry key
'return TRUE if ok, FALSE if error
Public Function IsRunAtStartup() As Boolean
Try
Dim key As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", False)
Dim keyValue As Object = key.GetValue(appname)
Return keyValue IsNot Nothing
Catch ex As Exception
writeLog("Error @IsRunAtStartup: " + ex.Message)
Return False
End Try
End Function

'set whether or not the application is set to run at startup via registry key
'return TRUE if ok, FALSE if error
Public Function SetRunAtStarup(ByVal runStartup As Boolean) As Boolean
Try
Dim key As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True)
If runStartup Then
key.SetValue(appname, Application.ExecutablePath.ToString)
Else
key.DeleteValue(appname)
End If
Return True
Catch ex As Exception
writeLog("Error @SetRunAtStarup: " + ex.Message)
Return False
End Try
End Function

Read More »

Sunday, October 26, 2008

Toggle Button in .NET

Ever wondered how to create a button which toggles it's state in C# windows Forms? It used to exist in VB6 / Office development as a ToggleButton, but cannot easily be found in C#

It turns out you need to use the System.Windows.Forms.Checkbox control but set its Appearance property to 'Button'. Usually you would just set this in the IDE but alternatively heres the code ...


CheckBox checkBox1 = new System.Windows.Forms.CheckBox();
checkBox1
.Appearance = System.Windows.Forms.Appearance.Button;

Read More »

Wednesday, October 22, 2008

Late-binding in .NET

Early-binding:

Variable types are defined at compile time (e.g. string, integers):

String st = "hello world";
Boolean ok = st.Contains("hello");


The compiler and linker will help verify that the argument types used to call a function matches the function's signature.

Late-binding:

At compile time, variable are declared as generic type (Object in .NET or Variant in VB6). The actual type will only be defined later at run-time, just before the object is used.

The developer needs to specify the function signatures and to ensure that the correct types are used.

In C/C++, late binding (a.k.a. run-time dynamic linking) often takes the form of LoadLibrary / GetProcAddress / FreeLibrary. The MSDN Library provides a good example of late binding in C/C++. Early biding is known as load-time dynamic linking in C++.

In VB6 and VB.NET, late-binding is possible with Option Strict turn off:

Option Strict Off
Dim st as Object = "hello world"
Dim ok as Object = st.Contains("hello")


'st' will be resolved to String type and 'ok' to Boolean at run-time.

Option Strict is by default off for all new VB.NET project created in VS2005. To change the default to On, go to the Visual Studio's Tools | Options menu, click the Projects \ VB Defaults folder and set Option Strict to On.

However, in C#, late-binding needs to be performed via Reflection:

Object obj = new object();
obj = "Hello world";
Type objType = obj.GetType();
Object objRet = objType.InvokeMember("IndexOf", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, obj, new object[] { "world" });


Reference:
  1. What is late binding?, http://blogs.msdn.com/davidklinems/archive/2006/11/27/what-is-late-binding.aspx
  2. Late Binding with Reflection, http://www.c-sharpcorner.com/UploadFile/samhaidar/LateBindingWithReflection09122005053810AM/LateBindingWithReflection.aspx?ArticleID=921b6d13-f609-4520-8a7d-8e70ce13b53b
Read More »

Saturday, October 18, 2008

Sharing resource files between different VS projects

A .NET resource file created by VS contains:

1. Resources.resx: XML declaration of all resources

2. Resources.Designer.vb: autogenerated by VS custom tool (VbMyResourcesResXFileCodeGenerator) during the build process. This file facilitates the accessing of resources from .NET code (e.g. My.Resources namespace in VB and [ProjectName].Resources in C#). Everytime the resources file changes, VS will run the tool to re-generate the resources designer file. The re-generation process can also be done manually by right clicking the .resx file and choose Run Custom Tool.

3. In the property of the .resx file, CustomTool is set to VbMyResourcesResXFileCodeGenerator and CustomToolNamespace is My.Resources (for VB). Build action for .resx file should be Embedded Resources

To share resources file between 2 projects:

1. In the first project, proceed to create the resource file as per normal

2. In the 2nd project, create the resource file as per normal. After that, remove the .resx file and .designer.vb from the project (you may need to enable View->Show All Files in order to see these files under Project). Proceed to add the .resx file and .designer.vb file from the first project into the current project as link

3. For these 2 added files, make sure the Build Action, Custom Tool and Custom Tool Namespace has been set accordingly.

Note: If resources are shared between desktop and device projects, there are chances that the code generated by the custom tool for the desktop project will overwrite that of the device, causing incompatibilities and build errors. As a work around, if such errors occur, before building, right click the resources file and choose Run custom tool.
Read More »

Thursday, October 16, 2008

TrustFailure exception during HTTPWebRequest via HTTPS connection

If an HTTPWebRequest is made via a secure connection (HTTPS) and the certificate is not trusted, a WebException with Exception.Status = TrustFailure will be thrown. To bypass this, we need to explicitly declare a custom certificate policy in a separate class:


Imports System.Net
Imports System.Security.Cryptography.X509Certificates

Public Class TrustAllCertificatePolicy
Implements System.Net.ICertificatePolicy

'default empty constructor
Public Sub New()
End Sub

Public Function CheckValidationResult(ByVal sp As ServicePoint, ByVal cert As X509Certificate, ByVal req As WebRequest, ByVal problem As Integer) As Boolean Implements ICertificatePolicy.CheckValidationResult
'return true to accept all certificates. Otherwise examine 'cert' and return either TRUE or FALSE according to its properties
Return True
End Function

End Class


Before the call to HTTPWebRequest, explicitly state the custom policy:

System.Net.ServicePointManager.CertificatePolicy = New TrustAllCertificatePolicy()


Reference: http://www.pcreview.co.uk/forums/thread-1226590.php

Read More »

Monday, October 13, 2008

Kill a process given its executable name.

BOOL KillProcessByName(const TCHAR* p_strEXE)
{
printf("Attempting to terminate ");
OutputDebugString(p_strEXE);
printf("\n");

HANDLE hSnapShot
= NULL;
PROCESSENTRY32 pEntry
= {0};

// Get the snapshot of the system
hSnapShot
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (hSnapShot != INVALID_HANDLE_VALUE)
{
pEntry
.dwSize = sizeof(pEntry);

//Get first process
if (Process32First(hSnapShot, &pEntry))
{
TCHAR strTempExe
[MAX_PATH];
_tcscpy(strTempExe, pEntry.szExeFile);

printf("Found: ");
OutputDebugString(strTempExe);
printf("\n");

//found process on the first attempt, kill it
if (_tcscmp(strTempExe, p_strEXE) == 0) goto KillProcess;

//Iterate through all other processes
while (Process32Next(hSnapShot, &pEntry))
{
_tcscpy(strTempExe, pEntry.szExeFile);

printf("Found: ");
OutputDebugString(pEntry.szExeFile);
printf("\n");

//we have found our process;
if (_tcscmp(strTempExe, p_strEXE) == 0) goto KillProcess;
}
}
else
{
printf("Process32First FAILED. Error %d\n", GetLastError());
}
}
else
{
printf("Process32First FAILED. Error %d\n", GetLastError());
}

//if we are here it means process cannot be found;
goto ProcessNotFound;

KillProcess:

CloseHandle(hSnapShot);

//kill it
HANDLE hProcess
= OpenProcess(PROCESS_ALL_ACCESS, FALSE, pEntry.th32ProcessID);
if (hProcess)
{
if (::TerminateProcess(hProcess, 0))
{
printf("Process terminated.\n");
return TRUE;
}
else
{
printf("TerminateProcess FAILED. Error %d\n", GetLastError());
return FALSE;
}
}
else
{
printf("OpenProcess FAILED. Error %d\n", GetLastError());
return FALSE;
}

ProcessNotFound:
CloseHandle(hSnapShot);

printf("Specified process not found.\n");
return FALSE;
}

Read More »

Wednesday, October 8, 2008

Serializing/De-serializing an ArrayList

Declarations:


'Type of each element in the ArrayList
Public Structure ArrayListEntry

End Structure

'ArrayList containing elements of above type
Public myArrayList As New ArrayList


Declare a custom serializer:


Dim customSerializer As New XmlSerializer(GetType(Object()), New System.Type() {GetType(ArrayListEntry)})


Methods to serialize data into XML:


A custom serializer must be used.


Public Sub saveSerializedData(ByVal datafile As String, ByVal ConfigObj As Object, ByVal serializer as XmlSerializer) As Boolean
Dim writer As New StreamWriter(datafile)
serializer.Serialize(writer, ConfigObj)
writer.Close()
End Sub


To use the method:


saveSerializedData("out.xml", myArrayList.ToArray, customSerializer)


Method to de-serialize data back to Object:


Public Function readSerializedData(ByVal datafile As String, ByRef ConfigType As Type) As Object
Dim retConf As Object = Nothing
Dim serializer As XmlSerializer = New XmlSerializer(ConfigType)
Dim fs As New FileStream(datafile, FileMode.Open)
retConf = serializer.Deserialize(fs)
fs.Close()
Return retConf
End Function


To use the method:


myArrayList.AddRange(CType(readSerializedData("out.xml", myArrayList.GetType, isok, customSerializer), Collections.ICollection))

Read More »