# Sunday, October 07, 2007

If you've read Raymond Chen's blog long enough, then you know trying to change system stuff directly in Windows registry is discouraged, if not frowned upon.  So when I kept hacking away at the registry trying to get some Windows Firewall exceptions for XP and Vista created, I decided to take a step back and see what Windows's API's are out there to do this.

Doing some Google searches doesn't reveal much (which is why I decided to blog this), except these two hidden gems Syslog daemon for Windows Eventlog, and Adding a port to the XP Firewall.  Both of these gave me pointers in the right direction to create this gem:

  1 private static void ExceptionToFirewall(bool add, string imageFileName, string name)
  2 {
  3 	Type netFwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr");
  4 	INetFwMgr mgr = (INetFwMgr)Activator.CreateInstance(netFwMgrType);
  5 
  6 	INetFwProfile curProfile = mgr.LocalPolicy.CurrentProfile;
  7 	if (add)
  8 	{
  9 		Type NetFwAuthorizedApplicationType = Type.GetTypeFromProgID("HNetCfg.FwAuthorizedApplication", false);
 10 		INetFwAuthorizedApplication app = (INetFwAuthorizedApplication)Activator.CreateInstance(NetFwAuthorizedApplicationType);
 11 
 12 		app.Name = name;
 13 		app.ProcessImageFileName = imageFileName;
 14 		app.Enabled = true;
 15 		app.RemoteAddresses = "*";
 16 		app.Scope = NET_FW_SCOPE_.NET_FW_SCOPE_ALL;
 17 
 18 		curProfile.AuthorizedApplications.Add(app);
 19 	}
 20 	else
 21 	{
 22 		curProfile.AuthorizedApplications.Remove(imageFileName);
 23 	}
 24 }
 

To use this, you'll need to add a reference to COM component HNetCfg.FwMgr (Guid "{304CE942-6E39-40D8-943A-B913C40C9CD4}", file path C:\windows\system32\hnetcfg.dll).

One note, don't use the IpVersion property of INetFwAuthorizedApplication, under Windows Vista it throws a NotImplimentedException.

kick it on DotNetKicks.com 

del.icio.us Tags: , ,

C# | Firewall | Windows
Sunday, October 07, 2007 6:50:55 PM (Alaskan Daylight Time, UTC-08:00)
# Thursday, September 13, 2007

Usually I post solutions I've discovered or created to problems I've encountered.  Now, I've run into a problem with the XmlSerializer and I need your help solving it.  Scroll to the bottom for an update.

The Problem

I have a class called Foobar.  Foobar inherits from List<string>, and contains one member Title.  When I use the XmlSerializer to serialize and deserialize Foobar, all the items in the List are make it through safely, but the member Title does not.

The Code

using System; using System.Collections.Generic; using System.IO; using System.Xml.Serialization; internal class Program { private static void Main() { Foobar f = new Foobar(); f.Add("1"); f.Add("2"); f.Title = "Title"; MemoryStream mem = new MemoryStream(); XmlSerializer xs = new XmlSerializer(typeof(Foobar)); xs.Serialize(mem, f); mem.Seek(0, 0); mem.Seek(0, 0); Foobar deser = (Foobar)xs.Deserialize(mem); Console.WriteLine(deser); } } [Serializable] public class Foobar : List<string> { public string Title; }

The Solution

One way I came up with to solve this problem is make Foobar not inherit from List<string>, and make a member called Items that is a List<string>, but that's kind of hokey.  I've searched Google and can't find a solution.  So I'm appealing to my dear readers for a better solution.

Update

Looks like I was being way to specific in my Google search, searching on "XmlSerializer List" gives us this http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=566175&SiteID=1 as the first item.  In the post,

Elena Kharitidi says "XmlSerializer does not serialize any members if a collection. Only collection items get serialized. This is by design, basically a decision was made to handle collections as arrays not as classes with multiple properties, so collections should look like arrays on the wire, therefore they do not have any members other then collection items, and can be “flattened” by adding the [XmlElement] to the member of the ICollection type."

Long and short, I need to use the hokey solution I came up with (or something like it), or write my own serializer.

Thursday, September 13, 2007 7:22:29 AM (Alaskan Daylight Time, UTC-08:00)
# Sunday, August 26, 2007

I downloaded the very excellent Resource Refactoring Tool (http://www.codeplex.com/ResourceRefactoring) the other day.  It works great in code files, but I found that it didn't work at all for ASPX/HTML pages.  Seeing this as a challenge, I decided to hack something up in VBA to automatically extract the selected text, create a resx name for the text, add it to the resource file, and insert the ASP.NET literal control.

How to use it

This is split up into two different macro modules, one named Utilities, and the other named what ever you want.  Then add them to your Visual Studio tool bar so you have something convenient you can click on (Right click the tool bar, click Customize, click Commands, then Macros under categories, find what you named the macro and then drag it up to your tool bar.  You can either drag it to an existing tool strip, or create your own.  Finally right click on the item while still in customize mode and add an image).

 

Caller:

Imports System Imports EnvDTE Imports EnvDTE80 Imports System.Diagnostics Public Module MoreMacros Public Sub AspTextLiteral() Dim resx as ProjectItem = DTE.ActiveWindow.Object.GetItem("solution\project\folder\ResourceFile.resx") Utilities.AspTextLiteral(resx) End Sub Public Sub InQuoteLiteral() DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate() Dim resx as ProjectItem = DTE.ActiveWindow.Object.GetItem("solution\project\folder\ResourceFile.resx") Utilities.InQuoteLiteral(resx) End Sub End Module

Utilities:

Imports System Imports EnvDTE Imports EnvDTE80 Imports System.Diagnostics Imports System.Xml Public Module Utilities Public Sub AspTextLiteral(ByRef resourceFile As ProjectItem) Const literalFormat = "<asp:Literal runat=""server"" Text=""<%$ Resources:{0},{1}%>"" />" Const inQuotesFormat = "<%$ Resources:{0},{1}%>" LiteralReplacer(resourceFile, literalFormat, 4) End Sub Public Sub InQuoteLiteral(ByRef resourceFile As ProjectItem) Const inQuotesFormat = "<%$ Resources:{0},{1}%>" LiteralReplacer(resourceFile, inQuotesFormat, 3) End Sub Private Sub LiteralReplacer(ByRef resourceFile As ProjectItem, ByVal template As String, ByVal delete As Int16) Dim ts As TextSelection = DTE.ActiveDocument.Selection Dim name As String = StripNonAllowedChars(ts.Text).Trim.ToLower Dim value As String = ts.Text Dim path As String = resourceFile.Properties.Item("LocalPath").Value Dim resName As String = System.IO.Path.GetFileNameWithoutExtension(resourceFile.Name) name = AddResourceEntry(path, name, value) ts.Text = String.Format(template, resName, name) DTE.ActiveDocument.Selection.Delete(delete) End Sub 'Returns the value of the name used Public Function AddResourceEntry(ByRef resourceFilePath As String, ByVal name As String, ByVal value As String) As String Dim doc As XmlDocument = New XmlDocument doc.Load(resourceFilePath) 'See if it exists first Dim root As XmlElement = doc.DocumentElement Dim e As XmlElement = root.SelectSingleNode(String.Format("data[@name=""{0}""]", name)) If e Is Nothing Then name = CreateUniqueName(root, name) Dim elem As XmlElement = CreateResourceFileElement(doc, name, value) root.AppendChild(elem) Else If e.SelectSingleNode("value").InnerText.ToLower = value.ToLower Then Return name Else name = CreateUniqueName(root, name) Dim elem As XmlElement = CreateResourceFileElement(doc, name, value) root.AppendChild(elem) End If End If doc.Save(resourceFilePath) Return name End Function Private Function CreateUniqueName(ByRef root As XmlElement, ByVal name As String) As String If IsNumeric(name.Substring(0, 1)) Then name = "n" & name End If 'Name doesn't exist, use it If Not CheckNameExists(root, name) Then Return name End If Dim result As String 'Build a unique name For I As Int16 = 1 To 100 result = name & I If Not CheckNameExists(root, result) Then Return result End If Next Return name & Guid.NewGuid.ToString End Function Private Function CheckNameExists(ByRef root As XmlElement, ByVal name As String) As Boolean Dim e As XmlElement = root.SelectSingleNode(String.Format("data[@name=""{0}""]", name)) Return Not (e Is Nothing) End Function Private Function CreateResourceFileElement(ByRef doc As XmlDocument, ByVal name As String, ByVal value As String) As XmlElement Dim result As XmlElement = doc.CreateElement("data") SetAttribute(result, "name", name) SetAttribute(result, "xml:space", "preserve") Dim valueElem As XmlElement = doc.CreateElement("value") valueElem.InnerText = value result.AppendChild(valueElem) Return result End Function Private Function SetAttribute(ByRef element As XmlElement, ByVal attr As String, ByVal value As String) As XmlElement If element.Attributes.GetNamedItem(attr) Is Nothing Then Dim attrib As XmlAttribute = element.OwnerDocument.CreateAttribute(attr) attrib.Value = value element.Attributes.Append(attrib) Else element.Attributes.Item(attr).Value = value End If Return element End Function Private Function StripNonAllowedChars(ByVal text As String) As String Const non_allowed = """';:,<.>/?\|`~!@#$%^&*()-=+[{]} " For I As Integer = 0 To non_allowed.Length - 1 text = text.Replace(non_allowed(I).ToString, "") Next Return text End Function End Module

 

del.icio.us Tags: , , ,
Sunday, August 26, 2007 8:56:04 PM (Alaskan Daylight Time, UTC-08:00)