Clear stale ESX iSCSI targets

During our beta testing of our new VMWare environment, we created various volumes and then deleted them. After removing them from the Equallogic SAN, we found ESX server was still trying to login to those targets. After some research, I stumbled across the following files containing the stale entries:

[root@vmware root]# cd /var/lib/iscsi
[root@vmware iscsi]# ls -la
total 16
drwx——    2 root     root         4096 Dec 17 12:11 .
drwxr-xr-x   11 root     root         4096 Oct 23 09:17 ..
-rw——-    1 root     root          830 Dec 17 11:22 vmkbindings
-rw——-    1 root     root          474 Dec 17 12:16 vmkdiscovery
[root@vmware iscsi]#

Put the host into maintenance mode, then edit both the /var/lib/iscsi/vmkbindings and /var/lib/iscsi/vmkdiscovery files to remove the stale entries. Reboot the host and exit maintenance mode. Lastly, rescan the HBA:

esxcfg-swiscsi -s

Repeat for all hosts that are attempting to use the stale entries.

Windows 2003 SP2 Network Issues

Included with SP2 is the Scalable Networking Pack which was a redeisgn of some major networking components to offload some of the processing to onboard components of certain network cards. Unfortunately, this seems to still be in its infancy and we started noticing very strange problems right away. A colleauge found this post on the MS Exchange team’s blog which ultimately led us to the answer: http://msexchangeteam.com/archive/2007/07/18/446400.aspx.

The symptoms we noted on our side were specifically that OS X users behind certain NAT firewalls would timeout when trying to retrieve pages from our web servers. After weeks of troublehsooting, we finally narrowed it down to a problem where pages less than 1440 bytes worked fine, but larger pages simply timed out. We also noticed that some of our technicians had problems connecting via RDP to various servers. The initial connection would drop, but sub-sequent connections worked find. Most of our Dell systems have onboard Broadcom NIC’s. Supposedly, this new Networking Pack which is enabled by default works only with the latest drivers. However, we found that even using the latest drivers provided directly from Broadcom, we were still having problems.

Luckily, the fix does not require a reboot and is easily implemented. Simply disabling the tcp chimney offload solved all of our issues:

netsh int ip set chimney disabled

You can view the state of each of the connections to the server and their offload state by running the netstat -t command.

Emulating keyboard events in .NET

Every now and then, you may need to emulate pressing keys on a keyboard to accomplish things through code. I found I needed to utilize this method for an Outlook programming project. After a little searching, I was able to emulate a user pressing the “ALT” button twice. You can use the keybd_event function (http://msdn2.microsoft.com/en-us/library/ms646304.aspx) to emulate keyboard events:

Imports System.Runtime.InteropServices

‘List of virtual key codes: http://msdn2.microsoft.com/en-us/library/ms645540.aspx
Const VK_SHIFT = &H10
Const VK_NUMLOCK = &H90
Const VK_ESC = &H1B
Const VK_MENU = &H12 ‘This is the ALT key
Const KEYEVENTF_KEYUP As Integer = &H2

<DllImport(“user32”)> _
Public Sub keybd_event(ByVal vk As Byte, ByVal sc As Byte, ByVal Flags As Integer, ByVal dwExtraInfo As Integer)
End Sub

Public Sub PressAltKeyTwice()
‘Simulate Key Press
keybd_event(VK_MENU, vbNull, 0, 0)
‘Simulate Key Release
keybd_event(VK_MENU, vbNull, KEYEVENTF_KEYUP, 0)

Application.DoEvents() ‘This was needed in my code to register the first keypress. If I did not have this, the system acted as though I press it only once.

‘Simulate Key Press
keybd_event(VK_MENU, vbNull, 0, 0)
‘Simulate Key Release
keybd_event(VK_MENU, vbNull, KEYEVENTF_KEYUP, 0)

Application.DoEvents()

End Sub

Enabling two-way communication between javascript and parent WebBroswer class

When I began looking for a way to do this, I thought it was going to be very difficult. What I wanted, was a javascipt method inside a WebBrowser object hosted in a Custom Task Pane, to call a method in the parent object’s class that would then call a method in the web page view of a folder, which would then execute client-side javascript inside that HTML document object. Fortunately, this is a very easy task by utilizing two methods: window.external and HTMLDoc.parentWindow.execScript.

Getting a client-side javascript method to invoke a method inside the parent class is as simple as using:

– In the HTML code:

<a href=”http://blogs.orcsweb.com/ControlPanel/Blogs/posteditor.aspx?SelectedNavItem=NewPost#” onclick=”javascript:window.external.MyMethod(var1, var2);”>Invoke MyMethod</a>

– In parent object’s class

Public Sub MyMethod(ByVal var1 As String, ByVal var2 As String)
MsgBox(“Var1: ” & var1 & “, Var2: ” & var2)
End Sub

In Outlook, if the current folder is set to use a web view instead of the standard folder list, the Application.ActiveExplorer.HTMLDocument reference will contain a valid mshtml.HTMLDocument object (it will throw an exception otherwise). Executing client-side javascript (or vbscript in my case) is as easy as calling the parentWindow.execScript method:

Dim oHTMLDoc As mshtml.HTMLDocument

oHTMLDoc = Application.ActiveExplorer.HTMLDocument

oHTMLDoc.parentWindow.execScript(“ClientSideMethod(‘” & Var1 & “‘,'” & var2 & “‘)”)

The point of doing this is that the web page view of the folder contains an Outlook View Control object, and using the above methods, we are able to set the “Restriction” property of the object from a web page hosted inside a custom task pane.

Resource Protocol in .NET

I never liked deploying an application that had numerous dependencies as there just seemed to be more room for error. When I discovered the resource protocol (res://), it seemed like a great way to embed HTML files I needed to distribute with my Outlook add-in. The nice part is that there is a single file deployed to the user’s system and you avoid any issues of users accidentally removing dependency files or similar headaches. I originally thought it would be as easy as adding my HTML file as a resource in my Visual Studio project, but come to find out that would create a managed resource (resx:// protocol). Unfortunately, the resx protocol has two glaring limitations:

From MSDN (https://msdn2.microsoft.com/en-us/library/bb189724.aspx):

The resx:// protocol is designed to load resources from .resx files that are embedded into managed assemblies, with the following limitations:

  • The resx:// protocol is used to load resources from a managed assembly, which must be strong-name signed and located in either %windir%\ehome or the global assembly cache (GAC).
  • In the syntax resx://myassembly/myresourcefile/myresourceidentifier, the myassembly parameter does not have a file extension, so you cannot have a managed DLL and EXE with the same name and be able to load resources from both of them.

So I set out on a quest to figure out how to embed a HTML file into my DLL and access it using the resource protocol. It actually isn’t that difficult, but the documentation is scarce. Thanks to Wouter van Vugt’s post (http://tinyurl.com/34pezy), I was able to stumble my way through it. Here are the steps:

1. Edit your project file (.vbproj or .csproj) and add the following:
<PropertyGroup>
<Win32Resource>NameOfResourceFile.res</Win32Resource>
</PropertyGroup>

2. Create a resource script file named NameOfResourceFile.rc and add it to your project. It should look something like this:
/* standard resource # for HTML */
#define HTML 23

/* include all resources from external files */
RES_REF     HTML     “NameOfHTMLFile.html”

/* end */

3. Add the HTML file named NameOfHTMLFile.html to your project.

4. Add the following to the prebuild commandline (Project Properties > Compile > Build Events):
“C:|Program Files|Microsoft Visual Studio 8|SDK|v2.0|Bin|rc” /r “$(ProjectDir)NameOfResourceFile.rc”

5. Compile you project.

6. Test it. Put this in a browser to load the file: res://NameOfDLL.dll/RES_REF

You can also embed graphics into the resource dll and reference them in the embedded HTML file. Note that you need to specify the resource type in the URL if it is not a HTML resource (the default). For example, if you embed a bitmap, you would reference it like so: res://NameOfDLL.dll/2/NameOfBitmapFile.bmp. You can find a list of common resource types here: http://msdn2.microsoft.com/en-us/library/aa365064.aspx. Images don’t have an associated resource type, so you would use res://NameOfDLL.dll/GIF/NameOfGIFImage.gif to access the image. Also, you can’t use the resource protocol to access .xsl or .xml files.

Remote Debugging in VS 2005

What do you do when you cannot reproduce an issue that is occuring in production in your development environment? Enter the nightmare that is Remote Debugging. For the better part of a day, I have been trying to remotely debug my Exchange transport agent on a production system. Unfortunately, I cannot reproduce the error in our development environment and I cannot install VS 2005 on the Exchange server, so I am forced to pull apart the DLL in production to see exactly what is going on. Well, to my surprise, Microsoft apparently wanted to make this as difficult as possible to accomplish. After scouring the Internet, I seem to have found a solution. Some notes that may save you some time:

  • To enable Remote Debugging, you need to run the MSVCMON.EXE file for your platform located under Program Files\Microsoft Visual Studio 8\Common 7\IDE\Remote Debugger (if you are on an x64 machine, the x86 version will be under Program Files (x86) and the x64 version under Program Files).
  • Be sure that the version of MSVCMON.EXE matches the version of VS 2005 on the debugging system.
  • The system running VS 2005 will need to know the path to the symbols file on the remote system. It is best to copy the symbols file to the same location as your DLL and set the path under Tools > Options > Debugging (tick Show all settings) > Symbols. Click the folder icon and enter the UNC path to the appropriate location. It is also best to browse to that folder via My Computer to ensure the debugging system can connect to the UNC share properly.
  • If your system running VS 2005 is behind a NAT firewall, forget about using Remote Debugging. All the testing I have performed and all the information I have found simply says this will not work. Furthermore, you will run into all kinds of problems if there is a firewall between the systems. It is best to use a system on the same subnet as the remote system.
  • Debugging managed code will not work using the “Remote (Native only with no authentication)” transport or “No Authentication” mode (as indicated by the “native only”) meaning you will have to enable authentication (use “Default” transport). Note that you can view the output of debug messages using the No Authenticate mode, but you will not be able to step through code or set breakpoints.
  • If the systems are not in the same domain or in domains that do not have trusts configured in both directions, you will need to create local users on each system so neither box can be a domain controller. The local users will need to have the same username and password.

Outlook 2007 Form Regions

New to Microsoft Outlook 2007 is Form Regions. These nice little pieces of code attach as “sub-forms” to existing forms in Outlook 2007. You can have them display adjoining to the standard Outlook form, as a separate tab, or replace the Outlook form entirely. Technet has a few great samples to play with:

Walkthrough: Creating an Outlook Form Region
http://msdn2.microsoft.com/en-us/library/aa942741(VS.80).aspx

Building an Outlook 2007 Form Region with a Managed Add-In
http://msdn2.microsoft.com/en-us/library/bb226713.aspx

Outlook 2007 Sample Add-ins: Rules Add-in, Travel Agency Add-in, and Prepare for Meeting Add-in
http://msdn2.microsoft.com/en-us/library/bb226710.aspx

You really have free reign with what you can do here … except that form regions do not currently support managed controls, meaning you’ll need to stick with ActiveX controls for now … though any ActiveX control will work. Here’s a screenshot from an “alpha” version of our ticketing system that uses form regions:

Screen1

The nice thing with forms regions is that they can attach to a standard Outlook form or to a customized form and they finally look and feel like part of Outlook. No more Office 97 style controls. The controls can access user defined fields or, like in our case, we populate them with data from SQL.

Create a Mail-Enabled Public Folder in Exchange 2007

Microsoft is threatening to deprecate Public Folders, though they claim they will maintain support through 2016. The alternative, Windows Sharepoint Services, isn’t a good fit for all circumstances … specifically when you would like to use a Public Folder as a mailing list. Use the commands below to create a new Mail-Enabled Public Folder:

Create public folder:
– New-PublicFolder “Folder Name”
– Enable-MailPublicFolder “\Folder Name”
– Set-MailPublicFolder -Identity “\Folder Name” -EmailAddressPolicyEnabled 0
– Set-MailPublicFolder -Identity “\Folder Name” -PrimarySMTPAddress “foldername@aliasdomain.com

MS Exchange 2007 Transport Agents

I haven’t blogged in a while because I have been buried in work writing a new ticketing system based on Exchange 2007 and Outlook 2007. Most of what we’re doing is fairly unexplored (or at least undocumented) territory. For those who have used Event Sinks in previous versions of Exchange, you maybe be happy (or disappointed depending upon your point of view) to find out that Microsoft is deprecating Event Sinks and replacing them with Transport Agents. In my numerous hours scouring the Internet looking for information on how these are implemented, I found just two worthwhile resources:

Transport Agent Tutorial
http://msexchangeteam.com/archive/2006/12/04/431755.aspx

Transport Agent Sample
http://msdn2.microsoft.com/en-us/library/aa579185.aspx

The first is a blog post from a member of the MS Exchange team, on the other is a sample listed in Technet. Furthermore, nearly all code you’ll find regarding Transport Agents in written in C#. While I have nothing against C# and actually come from a Java background, more of our team is familiar with VB.NET and I feel it’s more human readable. According to Microsoft and the Exchange team, “Agents have full access to all messages they process.” You’ll quickly find out that this isn’t the case. Rather, I should say they don’t “easily” have full access rights to all the messages they process. In fact, strangely most of the properties of the message are read-only which posed some particular issues for our development. Luckily, we found a few workarounds that suited our needs for our environment.

You have two basic types of Transport Agents: Smtp Receive agents and Routing agents. A custom Smtp Receive agent will fire on incoming messages to the Smtp server while they would not fire on outgoing messages on our test environment (a single Exchange 2007 Server running in Hub Transport mode). A custom Routing Agent will fire after a Smtp Receive agent and on outgoing messages. Though I haven’t proven this theory, I would also assume that a Smtp Receive agent would fire on messages transmitted to an Edge Transport Exchange 2007 server. You can find a list of available events your agent can call here: http://technet.microsoft.com/en-us/library/e7389d63-3172-40d5-bf53-0d7cd7e78340.aspx. You’ll also notice from this page that Microsoft provides numerous built-in agents to handle various tasks.

One of the first snags I had in trying to get the sample agent from Technet running, was the Namespace. VB.NET does not behave in the same manner as C# when it comes to namespaces. In order to use the install command specified in the Technet article, I had to clear the root namespace:

Screen1

Another big snag we ran into was changing the MessageClass to the our custom form. Thankfully, Yuri from Microsoft was able to provide a workaround: http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=1381211&SiteID=17. I highly recommend using this forum as not only the MVP’s but many of the MS product teams patrol with tons of helpful information.

SQL Update failure with hidden GridView column

As I’m still fairly new to ASP.NET, I came across what seemed to be a rather simple task that didn’t seem possible. I wanted to use a GridView control to display information from an SQL query and allow the user to edit the values in the GridView control. My update SQL statement included a WHERE clause referencing the primary key, an identity field. While it was not necessary to display the value to the user, it is necessary to reference the value in order to update the underlying data. I added the column to my GridView and marked it as hidden. To my surprise, any changes to the data in Edit mode were not saved. I checked and re-checked my update query and everything looked right. I set the column back to visible and voilà, the edit worked properly. After scouring google for a solution and wading through numerous posts that suggested using CSS to hide the data, I finally came across this little blurb in the ASP.NET GridView documentation on the MSDN site:

If the Visible property of a column field is set to false, the column is not displayed in the GridView control and the data for the column does not make a round trip to the client. If you want the data for a column that is not visible to make a round trip, add the field name to the DataKeyNames property.

http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx

I checked the properties of GridView and surely, no fields were listed in the DataKeyNames property. I added my primary key and removed the column entirely from the GridView. The data was then updated successfully.