Windows Vista and 7 provide a rather robust firewall API that can be used to add exceptions to the firewall. The code below will add an exception to the windows firewall for the specified application, provided that the code is run with administrator privileges. Add a reference to %systemroot%\system32\FirewallAPI.dll to your application.
Imports NetFwTypeLib
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' Create the Application we want to add to the exception list
Dim appType As Type = Type.GetTypeFromProgID("HnetCfg.FwAuthorizedApplication")
Dim app As INetFwAuthorizedApplication
app = DirectCast(Activator.CreateInstance(appType), INetFwAuthorizedApplication)
' Set the application properties
app.Name = "Negative0's Sandbox"
app.ProcessImageFileName = "C:\Users\Negative0\vbsandbox2.exe"
app.Enabled = True
' Get the firewall manager, so we can get the list of authorized apps
Dim fwMgrType As Type = Type.GetTypeFromProgID("HnetCfg.FwMgr")
Dim fwMgr As INetFwMgr
fwMgr = DirectCast(Activator.CreateInstance(fwMgrType), INetFwMgr)
' Get the list of authorized applications from the Firewall Manager, so we can add our app to that list
Dim apps As INetFwAuthorizedApplications
apps = fwMgr.LocalPolicy.CurrentProfile.AuthorizedApplications
apps.Add(app)
Occasionally I need to write an app that reads pixels from the screen. When searching small chunks of the screen, the windows GetPixel API works fine, but if I need to search the whole screen, that gets too slow. One way that I have found that is about twice as fast as GetPixel is copying the screen to a bitmap and using the Bitmap's GetPixel method. Below is an extension method that works with the Screen class to find pixels.
Module ScreenExtensions
<Extension()> _
Public Function FindPixelsByColor(ByVal CurrentScreen As Screen, ByVal SearchColor As Color) As List(Of Point)
Dim ScreenBitmap As Bitmap = Nothing
Dim ScreenCopier As Graphics = Nothing
If CurrentScreen Is Nothing Then Throw New ArgumentException("The screen object is nothing.")
If SearchColor = Color.Empty Then Throw New ArgumentException("The search color is empty.")
Try
' Initialize our output of points.
Dim OutputPoints As New List(Of Point)
' Create the bitmap object that will be used to store the image of the screen.
ScreenBitmap = New Bitmap(CurrentScreen.WorkingArea.Width, CurrentScreen.WorkingArea.Height, _
Imaging.PixelFormat.Format32bppArgb)
' Create the graphics object that will be used to copy the screen
ScreenCopier = Graphics.FromImage(ScreenBitmap)
' Copy from the screen to the bitmap, so we can search for the pixels we are looking for
ScreenCopier.CopyFromScreen(New Point(0, 0), New Point(0, 0), _
New Size(CurrentScreen.WorkingArea.Width, CurrentScreen.WorkingArea.Height))
Dim ScreenColor As Color
' Loop through all of the pixels in the bitmap
For x As Integer = 0 To CurrentScreen.WorkingArea.Width - 1
For y As Integer = 0 To CurrentScreen.WorkingArea.Height - 1
' Get the color at the current pixel from the screenshot.
ScreenColor = ScreenBitmap.GetPixel(x, y)
' Compare the color from the screenshot with the desired color. We need to level off the alpha
' for this compare to work properly. All colors from the screenshot have an alpha of 255.
If ScreenColor = Color.FromArgb(255, SearchColor) Then
' If we have a match, then add the current x,y to our output.
OutputPoints.Add(New Point(x, y))
End If
Next
Next
Return OutputPoints
Catch ex As Exception
Throw New Exception("Unable to perform pixel search.", ex)
Finally
If ScreenBitmap IsNot Nothing Then ScreenBitmap.Dispose()
If ScreenCopier IsNot Nothing Then ScreenCopier.Dispose()
End Try
End Function
End Module
Taking a screenshot from a .Net app is very easy. The function to use is the CopyFromScreen function from the Graphics class.
Dim b As Bitmap
'Hide the form, so it doesn't show in the screenshot
Me.Hide()
b = New Bitmap(My.Computer.Screen.WorkingArea.Width, _
My.Computer.Screen.WorkingArea.Height, _
Imaging.PixelFormat.Format32bppArgb)
Dim g As Graphics = Graphics.FromImage(b)
g.CopyFromScreen(New Point(0, 0), New Point(0, 0), _
New Size(My.Computer.Screen.WorkingArea.Width, _
My.Computer.Screen.WorkingArea.Height))
'Show the form again
Me.Show()
'Save the file
Dim ofd As New SaveFileDialog ()
ofd.Filter = "(*.bmp)|*.bmp"
If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
b.Save(ofd.FileName)
End If
I was helping someone with an issue restoring vb6 windows from a .Net application over on VBForums. The issue ended up being that the MainWindowHandle of the process was returning the window handle for the ThunderRT6Main window. The ThunderRT6Main is a hidden window that all VB6 apps have that is used for message processing. When we called ShowWindow against this window handle, nothing would happen. To get around this, I ended up calling the GetWindow API with a GW_HWNDPREV to get the window handle of the form window and then called ShowWindow on that.
Private SW_SHOWNORMAL As Integer = &H1
<Runtime.InteropServices.DllImport("user32", EntryPoint:="ShowWindow")> _
Private Shared Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As Integer) As Integer
End Function
Declare Auto Function GetWindow Lib "user32.dll" ( _
ByVal hWnd As IntPtr, ByVal uCmd As UInt32) As IntPtr
Const GW_HWNDPREV As Integer = 3
Dim proc As New Process
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' Start the process
With proc
.StartInfo.FileName = "c:\temp\project1.exe"
.Start()
End With
' Wait for it to finish loading and put the window handle into the form caption
proc.WaitForInputIdle(10000)
Me.Text = proc.MainWindowHandle.ToString("x8")
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
' Call GetWindow with GW_HWNDPREV to get the form from the ThunderRT6Main window
Dim vb6Window As IntPtr = GetWindow(proc.MainWindowHandle, GW_HWNDPREV)
' Call ShowWindow on the window we got back from the last call, which should be the ThunderRT6FormDC window
ShowWindow(vb6Window, SW_SHOWNORMAL)
Whenever I need to write a keyboard listener, I always have to go back and search through old code to get the exact syntax. I then end up copying and pasting a whole bunch of code. I decided it was time to create a DLL that will handle all of this work for me. I also decided that I will post the DLL up here for anyone to use as they see fit.
The DLL is copyrighted, however, it is free for distribution with personal or commercial applications.
The setup package, which includes a help file, a sample app, and the DLL, can be downloaded from the downloads page, or from the link below.
The sample app shows off the basic functionality of listening for one particular key, a set number of keys, or all key presses on a system. Below is a screenshot of the sample application. This dll works system wide, not just within the application that is using it.
Creating a plugin architecture in a C# application is a fairly easy task. The video below will walk you through the process of setting up the plugin architecture and it will implement a simple plugin.
The source for the project can be downloaded Here.
The video below gives an overview of creating a ComboBox that does conditional formatting. The code uses regular expressions to determine if an item in a combobox should have special formatting. The code is nowhere near production ready, but it should give you an idea of how to do formatting of items in a combobox drop down list. See the full post if you want to copy the code.
I found a nice little post from Heather Solomon on allowing SharePoint to have multiple levels of sub navigation. It works really well, but the navigation editor in MOSS does not let you nest sub-menus by default. I wrote a quick little C# app that allowed me to add navigation as needed. Here is the meat of the code.
SPNavigationNode oNewNode = new SPNavigationNode("My New Tab3","");
oWeb.Navigation.TopNavigationBar.AddAsLast(oNewNode);
oNewNode.Properties.Add("NodeType","Heading");
oNewNode.Update();
SPNavigationNode oChild1 = new SPNavigationNode("C1","/");
oNewNode.Children.AddAsFirst(oChild1);
oChild1.Properties.Add("NodeType","Heading");
oChild1.Update();
SPNavigationNode oChild2 = new SPNavigationNode("C2","/");
oChild1.Children.AddAsFirst(oChild2);
Note: I have only tested this on MOSS 2007 and it did some weird things to my tab highlighting that I haven't figured out yet.