NullifyNetwork

The blog and home page of Simon Soanes
Skip to content
[ Log On ]

Archive - Historical Articles

You are viewing records from 08/16/2007 18:54:39 to 07/27/2008 22:56:42. I'll be adding support for selecting a date range in future.

http://fantasticcontraption.com/ is quite possibly the best free web game I've encountered.

In it you get to solve complex (or seemingly simple looking) physics puzzles to move one item to another with only bars that you join together and motors (wheels in the game) that turn uncontrollably.  It is then your job to make sense of these and make them do what you command!  A very simple premise that rapidly gets out of control.

(Chris gets the blame for suggesting it to me and making it consume a huge amount of my free time today...)

Permalink 

My site and a bunch of hosted sites were down over the weekend due to an explosion at the datacentre where the servers are located in Houston.  This is now fixed.

No e-mail was lost as the server in New York was still up, but it's still mighty annoying.

Permalink 

I just encountered a small tool Microsoft released in 2005 called Log Parser 2.2.  This is a tool that allows you to take literally any data format anywhere and turn it into anything, very handy - particularly when processing IIS logfiles.

The site that used to exist for it has vanished, but there's still a few good resources out there related to it:-

Alexis Eller's talk on using log parser (I couldn't find a blog for her unfortunately)

Professor Windows - May 2005 article which has a lot of good examples.

Update - I am trying to build a replacement for tools like Webalizer which aren't maintained anymore (or are insanely complex to install and configure and maintain strange files as 'summaries').  I am currently using the following command to create and maintain a multiple GB database containing an indexed set of logfiles and getting back graphs of the data instantly for display in Open Flash Chart.

The command I'm using is:

"C:\Program Files\Log Parser 2.2\logparser" "select 1, * into WebLog 
from <MyIISSiteNumber>" -i:IISW3C -o:SQL -server:(local) -database:NullifyDBLog 
-driver:"SQL Server" -createTable:ON 
-transactionRowCount 100 -iCheckpoint:CheckpointFile.lpc

Which is working really well, it took about 30 minutes to process 4 or 5 years of logs and now updates the database near instantly!

Watch out for the fact that LogParser isn't too bright when making tables, to do this with my log format you need to create extra indexes, I opted for indexing obvious things like date, time, the uri, the referrer, the bytes transferred and the user agent.

Permalink 

Just so I don't forget, Visio UML generation is no longer available in Visual Studio 2008 out of the box; to add it back in just run the following reg file (adapted for your file paths obviously):

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Editors\{742C6336-9457-4885-8778-CBEC892F8EA2}]
"DisplayName"="#14"
"Package"="{FED78099-10D1-4A78-B037-ABCFA1A107B3}"
"ExcludeDefTextEditor"=dword:00000001
@="Visio Editor"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Editors\{742C6336-9457-4885-8778-CBEC892F8EA2}\Extensions]
"vsd"=dword:00000032

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\OutputWindow\{BC5C26E6-DF2B-46C9-B74E-0E057228055D}]
@="#2"
"Package"="{FED78099-10D1-4A78-B037-ABCFA1A107B3}"
"InitiallyInvisible"=dword:00000001
"Name"="Visio UML"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Packages\{FED78099-10D1-4A78-B037-ABCFA1A107B3}]
"InprocServer32"="C:\\PROGRA~1\\MICROS~1\\Office12\\UMLVS.DLL"
@="VisioUml Package"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Packages\{FED78099-10D1-4A78-B037-ABCFA1A107B3}\SatelliteDll]
"Path"="C:\\Program Files\\Microsoft Office\\Office12\\"
"DllName"="UMLVSUI.Dll"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Menus]
"{FED78099-10D1-4A78-B037-ABCFA1A107B3}"=", 1000, 1"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Projects\{D1DCDB85-C5E8-11D2-BFCA-00C04F990235}\AddItemTemplates\TemplateDirs\{FED78099-10D1-4A78-B037-ABCFA1A107B3}\/1031]
@="#213"
"TemplatesDir"="C:\\Program Files\\Microsoft Office\\Office12\\1031\\Vsdir\\"
"Package"="{FED78099-10D1-4A78-B037-ABCFA1A107B3}"
"SortPriority"=dword:00000032

(Taken from http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2488400&SiteID=1 )

Permalink 

I was trying to get speech recognition to work as easily as text-to-speech synthesis and noticed that there's a gotcha in that you can't use it from an MTA STA thread, so you need to invoke it on another thread.  Calling BeginInvoke on an anonymous delegate instance of voidDelegate sorts this pretty easily and is a nice and brief method of avoiding the problem.

Here's the necessary code to make a blank form with two text boxes (called TextBox1 and TextBox2) do speech recognition continually.  To use this code you need a reference to System.Speech.DLL and a using clause pointing to System.Speech.Recognition.

Note that hypothesized text is also displayed, so you can see the speech recognition engine 'thinking' which is handy as it lets you tell if you need to do more training with the engine.

private void Form1_Load(object sender, EventArgs e)

{

       InitSpeechRecognition();

}

 

SpeechRecognitionEngine _recognitionEngine;

 

public void InitSpeechRecognition()

{

       voidDelegate d = new voidDelegate(initSpeechRecognition);

       d.BeginInvoke(null, null);

}

 

private delegate void voidDelegate();

 

private void initSpeechRecognition()

{

       _recognitionEngine = new System.Speech.Recognition.SpeechRecognitionEngine();

       _recognitionEngine.SetInputToDefaultAudioDevice();

       DictationGrammar d = new DictationGrammar();

       d.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(d_SpeechRecognized);

       _recognitionEngine.UnloadAllGrammars();

       _recognitionEngine.SpeechHypothesized += new EventHandler<SpeechHypothesizedEventArgs>(r_SpeechHypothesized);

       _recognitionEngine.RecognizeCompleted += new EventHandler<RecognizeCompletedEventArgs>(r_RecognizeCompleted);

       _recognitionEngine.LoadGrammar(d);

       _recognitionEngine.RecognizeAsync();

}

 

void r_RecognizeCompleted(object sender, RecognizeCompletedEventArgs e)

{

       BeginRecognition();

}

 

delegate void SpeechHypothesizedPassThroughDelegate(object sender, SpeechHypothesizedEventArgs e);

 

void r_SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)

{

       if (this.InvokeRequired)

       {

              this.Invoke(new SpeechHypothesizedPassThroughDelegate(r_SpeechHypothesized), sender, e);

       }

       else

       {

              textBox2.Text = e.Result.Text;

       }

}

 

delegate void SpeechPassThroughDelegate(object sender, SpeechRecognizedEventArgs e);

 

void d_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)

{

       if (this.InvokeRequired)

       {

              this.Invoke(new SpeechPassThroughDelegate(d_SpeechRecognized), sender, e);

       }

       else

       {

              //display the recognised text, or process it here

              textBox1.Text += e.Result.Text + " ";

       }

}

 

private void BeginRecognition()

{

       new voidDelegate(delegate()

       {

              _recognitionEngine.RecognizeAsync();

       }).BeginInvoke(null, null);

}

 

private void StopRecognition()

{

       new voidDelegate(delegate()

       {

              _recognitionEngine.RecognizeAsyncStop();

       }).BeginInvoke(null, null);

}

Permalink 

There's an example over on divelements blog about how to host the winforms designer, as there seems to be a lack of documentation anywhere... Permalink 

I wanted to run a bunch of methods simultaneously on as many threads as possible to get the job done, but still wait at the end.  I know MS have something coming to solve this, but wanted a lightweight solution, so here it is:

public class Parallel
{
       public static T[] ExecuteWaitAll<T>(Func<T>[] functions)
       {
              List<T> resultSet = new List<T>();
              int i = 0;
              object lockObject = new object();
              foreach (Func<T> function in functions)
              {
                     lock (lockObject)
                     {
                           i++;
                           function.BeginInvoke(delegate(IAsyncResult result)
                           {
                                  lock (lockObject)
                                  {
                                         resultSet.Add(function.EndInvoke(result));
                                         i--;
                                  }
                           }, null);
                     }
              }
 
              while (i > 0)
              {
                     Thread.Sleep(1);
              }
              return resultSet.ToArray();
       }
}

To use this, you simply call it with a list of delegates you want to execute, and define the return type:

public void ExecuteWait()
{
       List<Func<int>> list = new List<Func<int>>();
       for (int i=0; i<100; i++)
       {
              list.Add(new Func<int>(delegate()
                     {
                           Thread.Sleep(1000);
                           return 1;
                     }));
       }
      
       int[] quantity = Parallel.ExecuteWaitAll<int>(list.ToArray());
       int count = 0;
       foreach (int result in quantity)
       {
              count += result;
       }
}

The result is now valid for 100 executions but took a lot less time than 100 seconds to calculate.  You could of course just be running four things at the same time, all different using this.

Permalink 

This is really simple but annoyed me for a few minutes until I got .NET Reflector up, so hopefully this will help someone else.

The render method on ASP.NET WebControl based server controls seems to be adding a span tag around the HTML output for some reason, to fix this simply override the Render method:

protected override void Render(HtmlTextWriter writer)
{
    RenderContents(writer);
}

Permalink 

Well Microsoft have just released Windows Server 2008 and Visa service pack 1 to manufacturing.  Still waiting for SQL Server 2008, but the stack is almost complete :)

Excellent features I'm looking forward to are:

  • IIS 7 on a server OS!
  • IPv6 file and print sharing (and oh my goodness is file and print sharing faster)
  • IPv6 over VPN!!
  • RDP over IPv6! (Can you tell I'm an IPv6 fan)
  • Application level terminal services (like Citrix has)
  • Fail back router support!  If you bring one down and then back up, it doesn't keep using the failover!
  • IPv6 enabled by default and not uninstallable (disabling will have to do for people who don't want to use it which should result in a lot more IPv6 compatible servers).
  • Read only domain controllers - good for if the domain controller is sighted somewhere insecure.
  • ADAM is now a first class citizen if you need an LDAP server but not active directory.  Active directory is also no longer completely intrinsyc to the server once promoted too!

The only unfortunate thing I can see is the removal of the basic firewall and OSPF from routing and remote access, but the basic firewall has been replaced by windows firewall - I just hope you can still define rules for the other hosts in the network.

Permalink  3 Comments 

There's an article on MSDN about how to host the Windows Workflow Foundation design surface (which is a redistributable).

The example code is really complete and worth a look at, it's almost an out-of-the-box copy of just the workflow designer from Visual Studio.

If your end user requires more flexibility than most you can offer them drag-and-drop customisation of particular processes in your system (like creating a new customer could be made to go off and send details to a webservice without you, the developer; needing to get involved).

Permalink 

Just a single snippet of code to work from, I included explanations in the comments. This is really a very easy to use feature in C# 3. Unfortunately you can’t create extension properties yet, but that will likely be coming soon.

namespace ExtensionMethods
{
       //Note that this class is static, it must be to contain extension methods and
       //it also can't reside inside another class.
       public static class ExampleExtensionMethod
       { 
              //This is the extension method
              public static bool HasLetterAInIt(this string s)
              {
                     //Just return if it contains the capital letter A as this is just an
                     //example
                     return s.Contains("A");
              }
       }
      
       class Program
       {
              static void Main(string[] args)
              {
                     //This will print false
                     Console.WriteLine("TEST".HasLetterAInIt().ToString());
                     //whilst this will print true
                     Console.WriteLine("AAHH!!".HasLetterAInIt().ToString());
              }
       }
}

Permalink 

Create a .NET 3.5 Console, Windows Forms or WPF project, add an SQL Compact Edition local database, I left the default name of Database1.sdf for the example. Just right click and open it from solution explorer and add some tables. I added two tables:  Person and Pet, with a relationship between the two (right click the child table, choose properties to get the add relationship option).

Next you want to add a command to visual studios tools menu, using Tools, External Tools… This command will allow you to generate a Linq To SQL DBML file which describes the contents of the database. Once we have that Linq is perfectly compatible with SQL Compact Edition – but the Visual Studio design tools aren’t so we need to do this manually.
Title:  Make &Linq classes for Database
Command:  C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SqlMetal.exe
Arguments: $(ItemPath) /dbml:$(ItemFileName).dbml
Initial Directory: $(ItemDir)
Now this tool will let you generate your DBML, select your Database1.sdf file then choose Tools, “Make Linq classes for Database”. It should pop up and seemingly do something in a command prompt.
Now right click your project, choose Add existing item and then change the filetype to either Data Files or All files. You should see there’s a new file called Database1.dbml – select this file and add it to your solution.
Bingo! It is now available to be edited in Linq – you can double click this dbml file and you’ll get the designer up – it should show your classes (NOTE: At this point I should add that relationships weren’t automatically generated for compact edition).
Now it’s time to use Linq to actually connect and query/save some data. This is where Linq takes a lot of the hassle out of building software that talks to databases, it simply works.
static void Main(string[] args)
{
       //Connect to the database itself.
       using (Database1 db = new Database1("Database1.sdf"))
       {
              //This is easy because we used SqlMetal to generate
              //the dbml targetting an SQL Compact edition database.
              //Normally you'd have to specify a full connection string.
 
              //obviously remove these two lines if you don't want to start with an empty database each time.
              db.Person.DeleteAllOnSubmit(db.Person);
              db.SubmitChanges();
 
              //Create a couple of Person entities
              Person simon = new Person();
              simon.Name = "Simon";
              simon.EMail = "me@myhost";
 
              //and a cat for me
              Pet cat = new Pet();
              cat.Name = "Fluffy";
              simon.Pets.Add(cat);
 
              db.Person.InsertOnSubmit(simon);
 
              Person fred = new Person();
              fred.Name = "Fred";
              fred.EMail = "them@myhost";
              db.Person.InsertOnSubmit(fred);
 
              //now actually add them to the database
              db.SubmitChanges();
 
              //Select the names of some people                                   
              var names = from Person p in db.Person
                                  select p.Name;
 
              //Print those names
              foreach (string name in names)
              {
                     Console.WriteLine(name);
              }
 
              //but you can also get back the entities instead of just names
              //this is handy if you require more than just one item for a particular person
              var people = from Person p in db.Person
                                   select p;
 
              foreach (Person person in people)
              {
                     Console.WriteLine(String.Format("{0} has an e-mail adddress of {1}", person.Name, person.EMail));
              }
 
              //but what if you want multiple items not all in one person?
              //well you can use anonymous classes
              var peopleAndPets = from Person p in db.Person
                                                orderby p.Pets.Count descending
                                                select new { p.Name, p.Pets.Count };
 
              //this is where the var keyword becomes essential. peopleAndPets
              //is not of a type that can be described before compilation.
              foreach (var quantity in peopleAndPets)
              {
                     Console.WriteLine(String.Format("{0} has {1} pets", quantity.Name, quantity.Count.ToString()));
              }
       }
 
       Console.WriteLine("The example is over!");
       Console.ReadKey();
}
Permalink  1 Comments 

This is really easy and quick, but something that is handy. Getting speech synthesis to work under .NET 3.0 is really a breeze.

First, add a reference to System.Speech – this contains the managed speech API, it allows you to do recognition and synthesis extremely easily.
Next, add the following to an empty console application/button click event:
using (System.Speech.Synthesis.SpeechSynthesizer synth = new System.Speech.Synthesis.SpeechSynthesizer())
{
     synth.SelectVoiceByHints(System.Speech.Synthesis.VoiceGender.Female, System.Speech.Synthesis.VoiceAge.Teen, 0);
     synth.Speak("Hello world!");
}
And you’re done! That should have taken less than a minute if your references dialog didn’t take ages to load.
If you have Microsoft Anna (you have Windows Vista, Autoroute or Streets and Trips installed) then this will use that preferentially (that’s the SelectVoiceByHints line), otherwise it may use Microsoft Sam which sounds pretty bad but works well.
Permalink  3 Comments 

If you’re getting the Windows Forms designer instead of the Compact Framework 3.5 designer then you likely have a problem in your registry.  When you try to compile the build succeeds, but then you get the following warning:

C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets : warning : An internal error occurred in PlatformVerificationTask. System.Exception: Could not locate an IAsmmetaBindingService for platform PocketPC.  Check your registry settings for the platform.

C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets : warning :    at Microsoft.CompactFramework.Build.AsmmetaContext..ctor(String ndpversion, String platformFamily, String platformID, ICollection references)

C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets : warning :    at Microsoft.CompactFramework.Build.Tasks.PlatformVerificationTask.Execute()

This also manifests itself in the GetDeviceFrameworkPath entry not accepted by the schema in the “C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets” file.

Well, there’s an easy enough solution to these problems, the AsmmetaBinder entries are missing from the registry in each of the sub-types under:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETCompactFramework\v3.5.0.0

So here’s the entries you need to copy into notepad, save as fix.reg or similar and then double click:-

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETCompactFramework\v3.5.0.0\PocketPC\AsmmetaBinder]
"TypeName"="Microsoft.CompactFramework.Build.PocketPC.BindingService, Microsoft.CompactFramework.Build.Tasks, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, Custom=null"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETCompactFramework\v3.5.0.0\PocketPC\AsmmetaBinder\4118C335-430C-497f-BE48-11C3316B135E]
"TypeName"="Microsoft.CompactFramework.Build.WM50PocketPC.BindingService, Microsoft.CompactFramework.Build.Tasks, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, Custom=null"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETCompactFramework\v3.5.0.0\Smartphone\AsmmetaBinder]
"TypeName"="Microsoft.CompactFramework.Build.SmartPhone.BindingService, Microsoft.CompactFramework.Build.Tasks, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, Custom=null"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETCompactFramework\v3.5.0.0\Smartphone\AsmmetaBinder\BD0CC567-F6FD-4ca3-99D2-063EFDFC0A39]
"TypeName"="Microsoft.CompactFramework.Build.WM50SmartPhone.BindingService, Microsoft.CompactFramework.Build.Tasks, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, Custom=null"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETCompactFramework\v3.5.0.0\WindowsCE\AsmmetaBinder]
"TypeName"="Microsoft.CompactFramework.Build.WindowsCE.BindingService, Microsoft.CompactFramework.Build.Tasks, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, Custom=null"

This one has been annoying me for a while now, as I do a bit of compact framework development.  I simply compared two exactly similar XP machines entire compact framework installs – files, registry settings, etc till I found the differences between a working and non-working system.

Permalink 

There's a limit on the data sent and recieved in WCF, resulting in errors like this when the webservice sends back larger messages:

"The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element."

The fix for this is to create a new binding with much larger limits:

System.ServiceModel.BasicHttpBinding binding = new System.ServiceModel.BasicHttpBinding();
binding.MaxBufferSize = 1024 * 1024 * 2; //bit bigger than default
binding.MaxReceivedMessageSize = 1024 * 1024 * 2;
binding.ReaderQuotas.MaxStringContentLength = 1024 * 1024 * 2;
ServiceReference1.MyServicesSoapClient client = new ServiceReference1.MyServicesSoapClient(binding, new System.ServiceModel.EndpointAddress("http://myservice/service.asmx"));

Permalink 

Just a reminder to myself, to let a user run an application pool without granting silly rights, you just need to run:

aspnet_regiis -ga <machine>\<user>

Which grants rights to the metabase and the temporary files folder.

Permalink 

I just noticed that Visual Studio 2008 is now out to MSDN subscribers!

Unsurprisingly MSDN is struggling to work :)

Permalink 

Well the subject says it all - I am indeed still around.

Trying to develop Windows Presentation Foundation applications with VS2K5 is more an exercise in suffering than getting any work done, even with Expression Blend to help.

Since it is coming out this month I should have plenty more to post at some point soon :)

 

Permalink 

Just a quick note so I can look it up easier later :)  - Simply call EnableGlass(); in the Form load event and it'll change the form to support glass.

You also need to implement support for changing the colour scheme of Vista and it needs to invalidate the form after running EnableGlass - a call to this.Invalidate();

private void EnableGlass()

{

       if (Environment.OSVersion.Version.Major >= 6) //check for vista

       {

              DwmEnableComposition(true);

              DWM_BLURBEHIND d = new DWM_BLURBEHIND();

              d.dwFlags = DWM_BLURBEHIND.DWM_BB_BLURREGION | DWM_BLURBEHIND.DWM_BB_ENABLE;

              d.fEnable = true;

              d.hRegionBlur = IntPtr.Zero;

              DwmEnableBlurBehindWindow(this.Handle, d);

              Paint += new PaintEventHandler(Glass_Paint);

       }

}

 

[StructLayout(LayoutKind.Sequential)]

public class DWM_BLURBEHIND

{

       public uint dwFlags;

       [MarshalAs(UnmanagedType.Bool)]

       public bool fEnable;

       public IntPtr hRegionBlur;

       [MarshalAs(UnmanagedType.Bool)]

       public bool fTransitionOnMaximized;

 

       public const uint DWM_BB_ENABLE = 0x00000001;

       public const uint DWM_BB_BLURREGION = 0x00000002;

       public const uint DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004;

}

 

[DllImport("dwmapi.dll", PreserveSig = false)]

public static extern void DwmEnableComposition(bool bEnable);

 

[DllImport("dwmapi.dll", PreserveSig = false)]

public static extern bool DwmIsCompositionEnabled();

 

[DllImport("dwmapi.dll", PreserveSig = false)]

public static extern void DwmEnableBlurBehindWindow(IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);

 

private void Glass_Paint(object sender, PaintEventArgs e)

{

       if (Environment.OSVersion.Version.Major >= 6)

       {

              if (DwmIsCompositionEnabled())  //check Aero is enabled

              {

                     e.Graphics.FillRectangle(Brushes.Black, this.ClientRectangle);

              }

       }

}

Permalink 

MSDN subscriber downloads now works in Opera, I just happened to use the wrong browser to go there and it worked great.  They even suggested manually installing the file transfer manager if not running IE.

I'm impressed, congratulations to whoever at Microsoft instigated making it cross browser (or at least, not moan and stop you outright).

Permalink