<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>tech.einaregilsson.com</title>
	<atom:link href="http://tech.einaregilsson.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://tech.einaregilsson.com</link>
	<description>A site for my programming pet projects</description>
	<lastBuildDate>Tue, 23 Feb 2010 08:19:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Module initializers in C#</title>
		<link>http://tech.einaregilsson.com/2009/12/16/module-initializers-in-csharp/</link>
		<comments>http://tech.einaregilsson.com/2009/12/16/module-initializers-in-csharp/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 15:34:01 +0000</pubDate>
		<dc:creator>einar</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[utilities]]></category>

		<guid isPermaLink="false">http://tech.einaregilsson.com/?p=352</guid>
		<description><![CDATA[One feature of the CLR that is not available in C# or VB.NET are module initializers (or module constructors). A module initializer is simply a global function which is named .cctor and marked with the attributes SpecialName and RTSpecialName. It is run when a module (each .NET assembly is comprised of one or more modules, [...]]]></description>
			<content:encoded><![CDATA[<p>One feature of the CLR that is not available in C# or VB.NET are module initializers (or module constructors). A module initializer is simply a global function which is named .cctor and marked with the attributes SpecialName and RTSpecialName. It is run when a module <small>(each .NET assembly is comprised of one or more modules, typically just one)</small> is loaded for the first time, and is guaranteed to run before any other code in the module runs, before any type initializers, static constructors or any other initialization code. I wanted to use this feature for a project I was doing but was unable to use it directly in C# so I created my own solution. <span id="more-352"></span></p>
<p>Now, why did I need this? Well, I was loading my other assemblies from an unusual place and I wanted to subscribe to the AppDomain.AssemblyResolve event before any types in my assembly were initialized. This feature is clearly not something you&#8217;re going to need every day, (actually I can&#8217;t think of a single other use case where I&#8217;d need it) but if you do, here&#8217;s how I solved it.</p>
<p>I used the excellent <a href="http://www.mono-project.com/Cecil">Mono.Cecil</a> library to create a small program that injects a module initializer into an existing assembly. Cecil is a fantastic library that makes it incredibly easy to manipulate assemblies and can do pretty much anything that you could possibly want to do with IL code. Using it I wrote a small program that simply takes in an assembly filename and the name of a parameterless static void method that exists in the assembly, and injects a module initializer that does nothing but call that method. The original code I wrote, the interesting part without all the error checking and stuff, is shown below:</p>
<pre class="brush: csharp;">
string assemblyName = &quot;Test.dll&quot;;
string typeName = &quot;Foo.Bar.ModuleInit&quot;;
string methodName = &quot;Run&quot;;

AssemblyDefinition assembly = AssemblyFactory.GetAssembly (assemblyName);
TypeReference voidRef = assembly.MainModule.Import(typeof(void));
var attributes = MethodAttributes.Static
                | MethodAttributes.SpecialName
                | MethodAttributes.RTSpecialName;
var cctor = new MethodDefinition( &quot;.cctor&quot;, attributes, voidRef);

TypeDefinition type = assembly.MainModule.Types[typeName];
MethodReference methodRef = type.Methods.GetMethod(methodName,new Type[]{});
cctor.Body.CilWorker.Append(cctor.Body.CilWorker.Create(OpCodes.Call, methodRef));
cctor.Body.CilWorker.Append(cctor.Body.CilWorker.Create(OpCodes.Ret));
assembly.MainModule.Inject(cctor, assembly.MainModule.Types[&quot;&lt;Module&gt;&quot;]);
AssemblyFactory.SaveAssembly(assembly, assemblyName);
</pre>
<p>I then added all the neccessary error handling, unit testing etc. and the resulting program can be <a href="/download/InjectModuleInitializer.exe">downloaded here</a>. The program is just a single executable since I merged Mono.Cecil into it using the excellent <a title="Merges multiple assemblies into one" href="http://research.microsoft.com/en-us/people/mbarnett/ILMerge.aspx">ILMerge</a> tool. You can run it from the command line and give it the filename of your assembly and optionally specify the method to call. If no method is explicitly specified then the program looks for a type named ModuleInitializer (may be in any namespace) and looks for a method named Run in that type and calls that method in the module initializer.</p>
<p>Run without specifying the method, looks for ModuleInitializer::Run in any namespace.</p>
<p style="font-family:monospace; font-weight:bold; font-size:13px; background-color:black;color:white;padding:5px;"> InjectModuleInitializer.exe Test.dll</p>
<p>Run and specify the method as Foo.Bar.SomeClass::SomeMethod</p>
<p style="font-family:monospace; font-weight:bold; font-size:13px; background-color:black;color:white;padding:5px;"> InjectModuleInitializer.exe /m:Foo.Bar.SomeClass::SomeMethod Test.dll</p>
<p>Realistically though, if you want to do this you probably want to do it right after building your assembly.  That&#8217;s why the assembly also includes an MSBuild task, so that it can be used directly in a .csproj file. The best target to use for this is the AfterBuild target. To use this task in your project you need to edit your .csproj file and add two things:</p>
<ol>
<li>At the top, inside the &lt;Project&gt; element include the following:
<pre class="brush: xml;">
&lt;UsingTask TaskName=&quot;InjectModuleInitializer&quot;
           AssemblyFile=&quot;c:\some\folder\InjectModuleInitializer.exe&quot; /&gt;
</pre>
<p>If the InjectModuleInitializer.exe assembly is registered in the global assembly cache you could also write that as</p>
<pre class="brush: xml;">
&lt;UsingTask TaskName=&quot;InjectModuleInitializer&quot;
           AssemblyName=&quot;InjectModuleInitializer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=818425a64317679d&quot; /&gt;</pre>
</li>
<li>Add the AfterBuild target at the bottom of the file, or anywhere where &lt;target&gt; elements are allowed.
<pre class="brush: xml;">
&lt;Target Name=&quot;AfterBuild&quot;&gt;
    &lt;InjectModuleInitializer AssemblyFile=&quot;$(TargetPath)&quot; /&gt;
&lt;/Target&gt;
</pre>
<p>Or, if you want to explicitly specify the method to run:</p>
<pre class="brush: xml;">
&lt;Target Name=&quot;AfterBuild&quot;&gt;
    &lt;InjectModuleInitializer
        AssemblyFile=&quot;$(TargetPath)&quot;
        ModuleInitializer=&quot;SimpleTest.Program::Con&quot; /&gt;
&lt;/Target&gt;
</pre>
</li>
<p>And there you have it. You can <a href="/download/InjectModuleInitializer.exe">download the console program/MSBuild task</a> or <a href="/download/InjectModuleInitializer.zip">download the source code</a> and build it yourself. Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.einaregilsson.com/2009/12/16/module-initializers-in-csharp/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Easy way to have custom icons in Visual Studio AddIn</title>
		<link>http://tech.einaregilsson.com/2009/11/20/easy-way-to-have-custom-icons-in-visual-studio-addin/</link>
		<comments>http://tech.einaregilsson.com/2009/11/20/easy-way-to-have-custom-icons-in-visual-studio-addin/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 09:39:34 +0000</pubDate>
		<dc:creator>einar</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[extensions]]></category>
		<category><![CDATA[tips & tricks]]></category>

		<guid isPermaLink="false">http://tech.einaregilsson.com/?p=305</guid>
		<description><![CDATA[I&#8217;ve recently been developing a Visual Studio AddIn and I wanted to use custom icons for a command I had. Looking for a solution I found the offical MSDN article on the subject, that might possibly be the most misleading and useless article ever. Add the resource file in Visual Studio, then exclude from project, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently been developing a Visual Studio AddIn and I wanted to use custom icons for a command I had. Looking for a solution I found the <a href="http://msdn.microsoft.com/en-us/library/ms228771.aspx">offical MSDN article on the subject</a>, that might possibly be the most misleading and useless article ever. Add the resource file in Visual Studio, then exclude from project, rename your images to numbers, edit with Notepad and then build satellite assemblies on the commandline? Really? That is a horrible way to do it and not at all necessary. I&#8217;ve found a very simple and easy way to add these icons without all that hassle.</p>
<p><span id="more-305"></span></p>
<p>There are a couple of other articles out there that approach the problem in a different way. Roy Osherove has an <a href="http://weblogs.asp.net/rosherove/archive/2008/08/02/howto-set-custom-visual-studio-addin-menu-icons-without-a-satellite-dll.aspx">article</a> where he shows how you can add icons without having satellite assemblies for them, but that has &gt; 350 lines of code for loading the images yourself including P/Invokes and all sorts of stuff, and I didn&#8217;t really need such a heavyweight solution. To be fair, his solution does give you the ability to use .ico files as well, and offers transparency, but transparency can be achieved in an easier way.</p>
<p>I also found <a href="http://www.mztools.com/articles/2005/MZ2005007.aspx">another article</a> that shows how you can get transparency by using a special color that, as far as I know, is not documented anywhere officially. It also shows you how you can build a satellite assembly from Visual Studio without resorting to Notepad and the command line tools, but this approach uses a special project for the satellite assembly, which is completely unneccessary.</p>
<p>So, finally, my approach, which is really a refinement of the last article I mentioned. If your add-in is meant for only VS2008 then you can get away with having no satellite assembly, VS2008 falls back to looking in your main assembly for the resources if it doesn&#8217;t find a satellite assembly. If you want to support VS2005 you must have a satellite assembly for it to work.</p>
<p>So, assume we have a project named MyProject which will compile to an assembly called MyProject.dll. Here&#8217;s what you do:</p>
<ol>
<li>Add a new &#8216;resources&#8217; item to the project and give it the name &#8220;MyProject.en.resx&#8221;.</li>
<li>Go the properties for the item and set the &#8220;Custom Tool&#8221; field to nothing. This will remove the auto-generated code for the .resx file</li>
<li>Double click on the .resx file, this opens up the resource editor. There you can add an existing image (Add Resource-&gt;Add existing file). The image should be a 16&#215;16 pixel bitmap image. It must be in True Color format. True Color is the same as a 24-bit bitmap.</li>
<li>If you want transparency in your image then use the special color: Red:0 , Green:254, Blue:0 . Note that it really is 254, NOT 255.</li>
<li>In the resource editor, give your image a name that is a number, e.g. 1. Note that you did not have to change the filename of your image file, just its name in the resource file.</li>
<li>Now add your command in your add-in file like so:
<pre class="brush: csharp;">
commands.AddNamedCommand2(_addInInstance, &quot;MyProject&quot;,
      &quot;MyProject&quot;, &quot;Executes the command for MyProject&quot;,
      false,
      1,
      ref contextGUIDS,
      (int)vsCommandStatus.vsCommandStatusSupported +
      (int)vsCommandStatus.vsCommandStatusEnabled,
      (int)vsCommandStyle.vsCommandStylePictAndText,
      vsCommandControlType.vsCommandControlTypeButton);
</pre>
<p>There you must send in <strong>false</strong> and then the number you gave the icon in your .resx file, e.g. 1.</li>
</ol>
<p>Now when you compile your solution, a satellite assembly with the name MyProject.resources.dll will automatically be created and put in a &#8220;en&#8221; subfolder of your output folder. If you only want to support VS2008 and don&#8217;t want satellite assemblies then you can name the .resx file just MyProject.resx instead, then no satellite assemblies will be created and the resources will be embedded in the main assembly.</p>
<p>And that&#8217;s it. Add more resources in Visual Studio, have things compile automatically and don&#8217;t touch command line tools, notepad, hundreds of lines of custom code or anything like that. I *think* it is enough to just have the &#8220;en&#8221; resources dll even if you use another locale, I&#8217;m pretty sure Visual Studio falls back to that if it doesn&#8217;t find a satellite assembly in your current culture. At least I have my Windows set up for Danish, but my &#8220;en&#8221; satellite assembly works just fine for me. Although, there doesn&#8217;t exist a Danish version of Visual Studio, maybe this works differently for localized Visual Studio, e.g. the German version. If someone has one of those and can test I&#8217;d love to know whether it falls back to &#8220;en&#8221; if nothing else is available. If it doesn&#8217;t then just create a few more MyProject.de.resx, MyProject.es.resx etc. to get more satellite assemblies. But like I said before, VS2008 and later doesn&#8217;t need this, so for that case just have the one MyProject.resx file.</p>
<p>I&#8217;ve made the small MyProject example and it can be <a href="/download/MyProjectAddIn.zip">downloaded here</a>. Let me know if this works (or doesn&#8217;t) for you. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.einaregilsson.com/2009/11/20/easy-way-to-have-custom-icons-in-visual-studio-addin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ZenCoding Visual Studio AddIn</title>
		<link>http://tech.einaregilsson.com/2009/11/12/zen-coding-visual-studio-addin/</link>
		<comments>http://tech.einaregilsson.com/2009/11/12/zen-coding-visual-studio-addin/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 23:05:08 +0000</pubDate>
		<dc:creator>einar</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[ZenCoding]]></category>
		<category><![CDATA[extensions]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[utilities]]></category>

		<guid isPermaLink="false">http://tech.einaregilsson.com/?p=289</guid>
		<description><![CDATA[4 Feb 2010: I&#8217;m no longer working on this addin and cannot provide support for failed installations. I gave some information about possible causes for failed installations in this comment, you can see if that helps, or discuss with other users in the comments. There are unlikely to ever be new versions of this addin [...]]]></description>
			<content:encoded><![CDATA[<p><strong>4 Feb 2010:</strong> I&#8217;m no longer working on this addin and cannot provide support for failed installations. I gave some information about possible causes for failed installations in <a href="http://tech.einaregilsson.com/2009/11/12/zen-coding-visual-studio-addin/#comment-70702">this comment</a>, you can see if that helps, or discuss with other users in the comments. There are unlikely to ever be new versions of this addin published by me, but Boris Sevo has forked the project and has a version with a newer zencoding library at <a href="http://zencoding.codeplex.com/">http://zencoding.codeplex.com/</a>. So go there for updates <img src='http://tech.einaregilsson.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The original blog post about the architecture of the addin is now completely out of date as 90% of the addin is now written in IronPython with just a tiny shim layer of C# to instantiate the IronPython classes. I&#8217;ll probably write a blog post about that architecture seperately (or generally about how to write addins for VS in IronPython). Those interested in the architecture can download the source and look at it.</p>
<p>A nice tutorial with screenshots on how to setup the keyboard mappings and use the addin has just been posted at <a href="http://www.netsi.dk/wordpress/index.php/2009/12/02/zen-coding-a-very-fast-way-of-generating-html-elements-in-your-editor/">http://www.netsi.dk/wordpress/index.php/2009/12/02/zen-coding-a-very-fast-way-of-generating-html-elements-in-your-editor/</a> so go there for your setup instructions. <del>And there is now a dedicated rss feed for updates at <a href="http://tech.einaregilsson.com/zcupdates.aspx ">http://tech.einaregilsson.com/zcupdates.aspx </a>so subscribe to that to be notified of new versions. Eventually I&#8217;ll put an update check in the addin itself.</del></p>
<p><strong>ZenCoding.VisualStudio v1.1.0.333</strong></p>
<p><a title="MSI installer for the add-in" href="http://tech.einaregilsson.com/download/ZenCoding.VisualStudio.msi">DOWNLOAD ADD-IN</a> || <a title="Download zip file with source code" href="http://tech.einaregilsson.com/download/ZenCoding.VisualStudio.zip">DOWNLOAD SOURCE</a></p>
<p><span id="more-289"></span><strong>RELEASE NOTES:</strong></p>
<p><strong>Version 1.1.0.333, 02.12.2009:</strong></p>
<p>This release adds the following features</p>
<ul>
<li>Uses latest version of zencoding python library</li>
<li>Wrap with abbreviation command</li>
<li>Use, create, edit, delete custom snippets (Tools-&gt;Options-&gt;ZenCoding)</li>
<li>Icons for commands</li>
<li>Some bug fixes</li>
</ul>
<p>Also a total rewrite with everything now written in IronPython</p>
<p><strong>Version 1.0, 12.11.2009:</strong></p>
<p>Initial release, features:</p>
<ul>
<li>Expand abbreviation</li>
</ul>
<p><strong>Original blog post follows:</strong></p>
<p>Earlier this week, while reading <a href="http://secretgeek.net">Leon Bambrick&#8217;s blog</a> I learned about a set of plugins, named &#8220;zen-coding&#8221;, which expand snippets of css-selector like code into full blown html and/or css elements. <a href="http://secretgeek.net/zen_coding.asp">Leon&#8217;s article</a> explains it better and there is also some documentation on the <a href="http://code.google.com/p/zen-coding/">official zen-coding page</a>. Anyway, this plugin is available for a number of text editors and IDE&#8217;s but not for Visual Studio. I use Visual Studio a lot and wanted zen-coding in there, so I decided to try and whip up a small add-in for it.</p>
<p>The original library is available both as JavaScript and Python. I really didn&#8217;t want to port or alter anything in the original code, since for future versions I want to be able to just drop in a couple of files from the original library and rebuild the add-in. The obvious choice then was to see if the library would work with IronPython. Fortunately the zen-coding library is just basic string manipulation and worked perfectly with IronPython right out of the box.</p>
<p>The next challenge was figuring out how to call into that from the add-in, which I wanted to write in C#. The library contained two functions I needed to be able to call. That turned out to be surprisingly easy. <del>I made a wrapper class, ZenCodingEngine, which has two delegates with the correct method signatures, and then in its constructor I ran some custom python import code, and got references to the functions I needed and assigned them to my delegates.</del> I changed that approach in the latest version and moved almost all of the logic into Python instead. Now the C# AddIn is very thin, it basically just receives events from VS and invokes a single exec_command() method that is defined in a python script. The interesting parts of that code are below:</p>
<pre class="brush: csharp;">
private void ReloadPython()
{
  ScriptEngine engine = Python.CreateEngine();
  ScriptScope scope = engine.CreateScope();
  string folder = Path.GetDirectoryName(new
    Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath);
  List searchPaths = new List&lt;string&gt;(engine.GetSearchPaths());
  searchPaths.Add(folder);
  engine.SetSearchPaths(searchPaths);
  scope = engine.ExecuteFile(Path.Combine(folder, &quot;vs_zen_coding.py&quot;));
  engine.SetVariable(scope, &quot;App&quot;, _applicationObject);
  execCommand = engine.GetVariable&lt;Func&lt;bool&gt;&gt;(scope, &quot;exec_command&quot;);
}

public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
  handled = false;
  if (!CanExecuteCommand(commandName, executeOption))
  {
    return;
  }

  try
  {
    #if RELOAD_EVERY_TIME
    ReloadPython();
    #else
    if (execCommand == null)
    {
      //Load first time, to avoid making the VS startup slower
      ReloadPython();
    }
    #endif

    execCommand();
  }
  catch (Exception ex)
  {
    DisplayError(ex);
  }
  handled = true;
}</pre>
<p>The ReloadPython() method is not called on startup, instead it is called the first time the command is called. IronPython performs well, but there is still some startup cost and I don&#8217;t want to add that to the startup time of Visual Studio. Instead you pay the price the first time you actually need it. Then we have the Exec method which is from a VS interface and is called when the command is invoked. There I use a compilation constant, RELOAD_EVERY_TIME, to check if I should reload my python script every time I invoke the command. This has proved to be INCREDIBLY useful, instead of constantly starting VS up again and again I just edit my python script, save it and the next time I execute the command the new code is used. And of course I turn this constant off for release builds.</p>
<p>Another nice trick to play around with the VS API, start up an IronPython shell and type:</p>
<div style="background-color:black; color:white;">
&gt;&gt;&gt; from System.Runtime.InteropServices import Marshal<br />
&gt;&gt;&gt; app = Marshal.GetActiveObject(&#8221;VisualStudio.DTE.9.0&#8243;)<br />
&gt;&gt;&gt; app.ActiveDocument.Name<br />
&#8216;ZenCodingAddIn.cs&#8217;
</div>
<p>This gets you a reference to the running instance of VS2009 which you can then experiment with.</p>
<p>You can download <a href="/download/ZenCoding.VisualStudio.msi">an installer</a> for the add-in or get <a href="/download/ZenCoding.VisualStudio.zip">the source</a>. The add-in is licensed under the GPL v3, the same license the zen-coding library uses. The add-in works for Visual Studio 2005, 2008 and 2010 beta 2.</p>
<p>Now, once you&#8217;ve installed the add-in, nothing happens. Well, actually what happens is there&#8217;s a new command available in Visual Studio, named <strong>ZenCoding.Expand</strong>, or <strong>ZenCoding.VisualStudio.ZenCodingAddIn.Expand</strong>, depending on where you are looking for it. (The keyboard mapping uses the full command id, but when adding it to a toolbar you get a shorter friendly name for it). By default it is not mapped to any keyboard combination. This is because <del>it&#8217;s late and I can&#8217;t be bothered to figure it out</del> I strongly believe that add-ins should not force a keyboard shortcut on you, possibly overriding something you have set yourself. So, map the command to your preferred keyboard shortcut (mine is Ctrl+E,Ctrl+K). Or you can drag the command  onto a toolbar, which is fairly useless, but possible.</p>
<p>Enjoy!</p>
<p><strong>UPDATE 13.11.2009: </strong> The main zen-coding developer also told me that I&#8217;m using an older version, the latest version has a lot more features, including user defined snippets. I&#8217;ll start looking at that when I have time, which won&#8217;t be just yet. </p>
]]></content:encoded>
			<wfw:commentRss>http://tech.einaregilsson.com/2009/11/12/zen-coding-visual-studio-addin/feed/</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>URL-2-Titlebar Firefox Add-on</title>
		<link>http://tech.einaregilsson.com/2009/09/25/url-2-titlebar-firefox-add-on/</link>
		<comments>http://tech.einaregilsson.com/2009/09/25/url-2-titlebar-firefox-add-on/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 11:48:04 +0000</pubDate>
		<dc:creator>einar</dc:creator>
				<category><![CDATA[extensions]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mozilla]]></category>

		<guid isPermaLink="false">http://tech.einaregilsson.com/?p=275</guid>
		<description><![CDATA[Recently I got a request in the mail from a user of one of my Firefox add-ons. He asked me if I could make an add-on that displayed the url of the current tab in the titlebar instead of the actual title of the page being shown. I&#8217;m not interested in creating more add-ons for [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I got a request in the mail from a user of one of my Firefox add-ons. He asked me if I could make an add-on that displayed the url of the current tab in the titlebar instead of the actual title of the page being shown. I&#8217;m not interested in creating more add-ons for Firefox or Thunderbird, they take up quite a lot of time with user requests, getting approved by <a href="http://addons.mozilla.org">the Mozilla addons site</a>, etc. That is why I&#8217;ve <a href="/projects/abandoned/">discontinued</a> 6 out of the 9 add-ons I&#8217;ve created. But anyway, I knew that it would be trivial to make this add-on so I decided to help this person out.<span id="more-275"></span></p>
<p>You can <a href="/download/url2titlebar.xpi">download the add-on</a> here. This add-on will never be updated or published on AMO, it is offered strictly as-is. The one thing I found interesting about this was figuring out how to do the absolute minimum to get this add-on working. There is no localization, no folder structure, just three files, install.rdf, chrome.manifest and url2titlebar.xul. Put those into a zip file, rename it to .xpi and you have your extension. These of course are not best practices in extension development, just an exercise in making the simplest extension possible. Below is the full content of the three files:
</p>
<h5>url2titlebar.xul</h5>
<pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;overlay xmlns=&quot;http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul&quot;&gt;
  &lt;script&gt;
    window.addEventListener('load', function() {
      function setTitle() {
        document.title = gBrowser.selectedBrowser.contentDocument.location;
      }
      gBrowser.tabContainer.addEventListener('TabSelect', setTitle, false);
      document.addEventListener('pageshow', setTitle, false);
      setTitle();
    },false);
  &lt;/script&gt;
&lt;/overlay&gt;
</pre>
<h5>chrome.manifest</h5>
<pre class="brush: plain;">
content url2titlebar file:./
overlay chrome://browser/content/browser.xul chrome://url2titlebar/content/url2titlebar.xul
</pre>
<p><strong>install.rdf</strong></p>
<pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;RDF xmlns=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;
 xmlns:em=&quot;http://www.mozilla.org/2004/em-rdf#&quot;&gt;
  &lt;Description about=&quot;urn:mozilla:install-manifest&quot;&gt;
    &lt;em:id&gt;url2titlebar@einaregilsson.com&lt;/em:id&gt;
    &lt;em:name&gt;URL-2-Titlebar&lt;/em:name&gt;
    &lt;em:version&gt;0.0.1&lt;/em:version&gt;
    &lt;em:creator&gt;Einar Egilsson&lt;/em:creator&gt;
    &lt;em:description&gt;Set the title of the window to the current url&lt;/em:description&gt;
    &lt;em:targetApplication&gt;
      &lt;Description&gt;
        &lt;em:id&gt;{ec8030f7-c20a-464f-9b0e-13a3a9e97384}&lt;/em:id&gt; &lt;!-- firefox --&gt;
        &lt;em:minVersion&gt;3.0&lt;/em:minVersion&gt;
        &lt;em:maxVersion&gt;3.5.*&lt;/em:maxVersion&gt;
      &lt;/Description&gt;
    &lt;/em:targetApplication&gt;
  &lt;/Description&gt;
&lt;/RDF&gt;
</pre>
<p>So, there you have it, the simplest possible Firefox add-on. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.einaregilsson.com/2009/09/25/url-2-titlebar-firefox-add-on/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Chord Image Generator</title>
		<link>http://tech.einaregilsson.com/2009/07/23/chord-image-generator/</link>
		<comments>http://tech.einaregilsson.com/2009/07/23/chord-image-generator/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 15:45:33 +0000</pubDate>
		<dc:creator>einar</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Guitar]]></category>

		<guid isPermaLink="false">http://tech.einaregilsson.com/?p=260</guid>
		<description><![CDATA[One of my non-programming related hobbies is playing guitar. I&#8217;ve used a lot of chord sheets and tablature from the internet and have often wanted to be able to print it out in a nicer format than plain ASCII. Chord definitions in online tablatures are usually written something like (xx0232) (a D chord), but I [...]]]></description>
			<content:encoded><![CDATA[<p>One of my non-programming related hobbies is playing guitar. I&#8217;ve used a lot of chord sheets and tablature from the internet and have often wanted to be able to print it out in a nicer format than plain ASCII. Chord definitions in online tablatures are usually written something like (xx0232) (a D chord), but I wanted to be able to get these nice chord diagrams like they have in the guitar magazines. So, I wrote my own little online chord image generator.<br />
<span id="more-260"></span><br />
Actually what I originally planned to do was create a whole chord sheet editor online, which would accept plain text song files and convert them into nicely formatted sheets ready for printing. They would include non monospace fonts while still having the chords line up correctly with the lyrics, chord diagrams at the top and a nice header with the name and artist. But, since I don&#8217;t have that much free time and thought I&#8217;d probably never complete that project I just created the chord image generator itself. Others can then maybe use it for something like my idea.</p>
<p>After I had written the chord image generating code itself I decided to make a little test app for it, both to teach people the correct format and just to play with. That little application can be found at <a href="http://chords.einaregilsson.com/">http://chords.einaregilsson.com/</a>. The chord images can have muted and open strings, finger positions, display the beginning fret for chords higher than the first five frets and display below the image which fingers are used for which string. They can also be generated in ten different sizes.</p>
<p>Lets look at some examples. The format of an url for a chord is: </p>
<p style="padding-left:10px;">http://chords.einaregilsson.com/[chordname]/[fretpositions]/[fingers]/[size] </p>
<p>So, for a normally fingered E chord the url would be:</p>
<table style="vertical-align:middle; border-style:none;">
<tr>
<td style="width:90px;"><img src="http://chords.einaregilsson.com/E/022100/-231--/2""/></td>
<td><a href="http://chords.einaregilsson.com/E/022100/-231--/2">http://chords.einaregilsson.com/E/022100/-231&#8211;/2</a>
</td>
</tr>
</table>
<p>The name is a simple string. The only thing to remember there is that if you want to use the # symbol you must encode it as %23, because otherwise the browser will not send the rest of the url to the server. If you have two chords with the same name you can differentiate them by naming for example one E5 and the other E5<sup>II</sup>. This is done by writing the name as E5_II, with an underscore before the superscript. Below is an example of a C# chord in size 5</p>
<table style="vertical-align:middle; border-style:none;">
<tr>
<td style="width:90px;"><img src="http://chords.einaregilsson.com/C%23/x4666x/-1333-/5"/></td>
<td><a href="http://chords.einaregilsson.com/C%23/x4666x/-1333-/5">http://chords.einaregilsson.com/C%23/x4666x/-1333-/5</a>
</td>
</tr>
</table>
<p>The fret positions run EAGDBE, use X for muted strings, 0 for open strings and other numbers for fret positions. If you are writing a chord that uses fret positions on and over the 10th fret you must write all the positions with a dash between them. A D bar chord on the 10th fret would then be written as </p>
<table style="vertical-align:middle; border-style:none;">
<tr>
<td style="width:90px;"><img src="http://chords.einaregilsson.com/D/10-12-12-11-10-10/134211" /></td>
<td><a href="http://chords.einaregilsson.com/D/10-12-12-11-10-10">http://chords.einaregilsson.com/D/10-12-12-11-10-10/134211</a>
</td>
</tr>
</table>
<p>The fingering positions also run EAGDBE. Use T for thumb, 1 for index finger, 2 for middle finger, 3 for ring finger and 4 for pinky. Use a dash, -, when no finger is on a particular string. Bar chords are inferred, if you write that you are using the same finger for different strings on the same fret, then a line will be drawn through them to indicate a barred chord. An example of that is the D chord above.</p>
<p>The size is just a number from 1-10. I like size 2 the best myself, and that is the default.</p>
<p>You can cut as much off the back of the url as you want. That is, you can skip the size, fingering positions and even fret positions, and they will use defaults instead. Default size is 2, default fingerings mean that no fingerings are written, and default fret positions are none. So, for example the following four urls are all legal (although the last one is not really a D chord since it contains no fret positions):</p>
<table style="vertical-align:middle; border-style:none;">
<tr>
<td style="width:90px;"><img src="http://chords.einaregilsson.com/D/xx0232/---132/2"/></td>
<td><a href="http://chords.einaregilsson.com/D/xx0232/---132/2">http://chords.einaregilsson.com/D/xx0232/&#8212;132/2</a>
</td>
</tr>
<tr>
<td style="width:90px;"><img src="http://chords.einaregilsson.com/D/xx0232/---132"/></td>
<td><a href="http://chords.einaregilsson.com/D/xx0232/---132">http://chords.einaregilsson.com/D/xx0232/&#8212;132</a></td>
</tr>
<tr>
<td style="width:90px;"><img src="http://chords.einaregilsson.com/D/xx0232"/></td>
<td><a href="http://chords.einaregilsson.com/D/xx0232">http://chords.einaregilsson.com/D/xx0232</a></td>
</tr>
<tr>
<td style="width:90px;"><img src="http://chords.einaregilsson.com/D"/></td>
<td><a href="http://chords.einaregilsson.com/D">http://chords.einaregilsson.com/D</a></td>
</tr>
</table>
<p>You are free to link to images directly on http://chords.einaregilsson.com from your own website, although I make no guarantees about uptime, performance or anything like that. The images are cached for a week, so loading time should be fast after the first time.</p>
<p>The code for this was written in C# and is licensed under the GPL. The main class is called ChordBoxImage and it can save the generated image in a variety of formats to any output stream. The code for the image generator as well as the little test web site can be <a href="http://tech.einaregilsson.com/download/Chords.zip">downloaded here</a>. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.einaregilsson.com/2009/07/23/chord-image-generator/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ZenPhoto Uploader</title>
		<link>http://tech.einaregilsson.com/2009/07/20/zenphoto-uploader/</link>
		<comments>http://tech.einaregilsson.com/2009/07/20/zenphoto-uploader/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 20:47:29 +0000</pubDate>
		<dc:creator>einar</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[zenphoto]]></category>

		<guid isPermaLink="false">http://tech.einaregilsson.com/?p=255</guid>
		<description><![CDATA[The photo album software I use to store my photos on the web is ZenPhoto. It is a very nice photo gallery system, with themes, lots of plugins, nice administrative interface and plenty of other good stuff. The only problem I had with it was getting my photos uploaded. Sure, they offer a web interface, [...]]]></description>
			<content:encoded><![CDATA[<p>The photo album software I use to store my photos on the web is <a href="http://zenphoto.org">ZenPhoto</a>. It is a very nice photo gallery system, with themes, lots of plugins, nice administrative interface and plenty of other good stuff. The only problem I had with it was getting my photos uploaded. Sure, they offer a web interface, or you can upload a zip file, or use FTP but I usually need to preprocess my photos a bit. Rotate them, throw out the ones I don&#8217;t want to upload, and most of all I need to make them smaller, uploading them in the size I use on my camera takes forever. So, I decided to make a simple program to do these things for me.<br />
<span id="more-255"></span><br />
I had previously used the program <a href="http://www.ornj.net/webalbum/">Web Album Generator</a> to make static html albums. I really liked its interface so I mostly copied it for my own program, ZenPhoto Uploader. Theres a list of the images on the left side and on the right side is a toolbar with all available operations, a big preview screen and textboxes for adding titles and descriptions.<br />
<a href="http://tech.einaregilsson.com/wp-content/uploads/2009/07/zp.jpg"><img src="http://tech.einaregilsson.com/wp-content/uploads/2009/07/zp-300x224.jpg" alt="" title="ZenPhoto Uploader screenshot" width="300" height="224" class="aligncenter size-medium wp-image-256" /></a></p>
<p>The program is ONLY meant for uploading albums for the first time, not for working with albums once they are uploaded. The main features of the program are:</p>
<ul>
<li>Create new albums (with descriptions) and upload images (obviously)</li>
<li>Resize photos before uploading</li>
<li>Rotate photos</li>
<li>Order photos in album</li>
<li>Remove photos from album and optionally delete the file itself</li>
<li>Save titles and descriptions for photos</li>
<li>Keyboard shortcuts for almost all actions</li>
</ul>
<p>The program is very much &#8220;me-ware&#8221;. I made it to scratch my own itch, it may not fit or feel right to anyone else. It was thrown together and is fixed as I run into bugs while using it. It may well contain errors and might crash horribly. That said, everyone is welcome to use it and improve upon it if they wish. Just know that <strong>you are using this at your own risk. I cannot be held liable for any damages or problems this program may cause. It contains commands that you can use to delete photos from your hard disk, use it carefully and think about what you are doing</strong>.</p>
<p>Probably my favorite feature of the program is the ability to do everything from the keyboard. The available shortcuts are:</p>
<ul>
<li>CTRL+U: Open the upload dialog</li>
<li>CTRL+UP, CTRL+DOWN: Move to previous/next photo even though the listbox is not selected</li>
<li>CTRL+SHIFT+UP, CTRL+SHIFT+DOWN: Move a photo higher or lower in the list</li>
<li>CTRL+T: Give focus to the Title textbox</li>
<li>CTRL+D: Give focus to the Description textbox</li>
<li>CTRL+LEFT, CTRL+RIGHT: Rotate the currently selected photo</li>
<li>DEL: Remove or delete the currently selected photo. There is a confirmation dialog that asks if you want to remove the photo from the album, or delete the photo. Do not choose &#8220;delete&#8221; unless you really want to delete the photo from your hard disk forever!</li>
</ul>
<p>The source is available in SVN at <a href="http://einaregilsson.googlecode.com/svn/dotnet/ZenPhotoUploader/">http://einaregilsson.googlecode.com/svn/dotnet/ZenPhotoUploader/</a> and is licensed under the <a href="http://www.gnu.org/licenses/gpl-3.0.html">GPL v3.0</a>. It is written in C# and requires .NET 3.5 to compile. There is a build.bat file in the root folder that can be used to build the program.</p>
<p>Finally, you can <strong><a href="/download/ZenPhotoUploader.exe">DOWNLOAD ZenPhotoUploader</a></strong> here, it is a single executable, no dependencies other than the .NET framework 2.0 or higher. The only version of ZenPhoto I&#8217;ve tested it against is v1.2.2, others may not work. Enjoy, and let me know if you have any problems with it.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.einaregilsson.com/2009/07/20/zenphoto-uploader/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Instant Rimshot</title>
		<link>http://tech.einaregilsson.com/2009/06/20/instant-rimshot/</link>
		<comments>http://tech.einaregilsson.com/2009/06/20/instant-rimshot/#comments</comments>
		<pubDate>Sat, 20 Jun 2009 08:52:20 +0000</pubDate>
		<dc:creator>einar</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[utilities]]></category>

		<guid isPermaLink="false">http://tech.einaregilsson.com/?p=234</guid>
		<description><![CDATA[It&#8217;s been a while since I&#8217;ve written anything here, I&#8217;ve been working on my master project like crazy, have a 6 month old baby and so haven&#8217;t had much time for programming pet projects. Tonight I spent a half hour making perhaps the most useless application I&#8217;ll ever make. It&#8217;s based on the single-serving website [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I&#8217;ve written anything here, I&#8217;ve been working on my master project like crazy, have a 6 month old baby and so haven&#8217;t had much time for programming pet projects. Tonight I spent a half hour making perhaps the most useless application I&#8217;ll ever make. It&#8217;s based on the single-serving website <a href="http://instantrimshot.com">http://instantrimshot.com</a> which only has one huge red button, if you press it a rimshot sound is played. I thought it might be fun to have that available as a keyboard shortcut in windows, and then I started wondering how it could be done in C#.</p>
<p><span id="more-234"></span></p>
<p>The only way to get a global keyboard working in .NET is by calling into the Win32 API. To register a global hotkey there is the aptly named function <a href="http://www.pinvoke.net/default.aspx/user32/RegisterHotKey.html">RegisterHotKey</a>. That requires you to have a window handle however, and I wanted to make the application as simple as possible, so I used a lower level API call,<br />
<a href="http://www.pinvoke.net/default.aspx/user32/SetWindowsHookEx.html">SetWindowsHookEx</a> which lets you get notified of all keyboard activity on the system. I then check what keys are pressed and when the combination Ctrl+Shift+I is pressed the sound is played. There is only one way to exit the app, and that is by pressing the keyboard combination Ctrl+Shift+Alt+I, that cleans up the hook before exiting. So, the code is shown below, you can <a href="http://tech.einaregilsson.com/download/InstantRimshot.zip">download the source</a> or just <a href="http://tech.einaregilsson.com/download/InstantRimshot.exe">download the program itself</a>. Enjoy!
</p>
<pre class="brush: csharp;">
using System;
using System.IO;
using System.Media;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

class InstantRimshot {

    const int WH_KEYBOARD_LL = 13;
    const int WM_KEYDOWN = 0x100;

    delegate int Hook(int code, IntPtr wParam, IntPtr lParam);

    [DllImport(&quot;user32.dll&quot;)]
    static extern IntPtr SetWindowsHookEx(int code,
                                          Hook func,
                                          IntPtr hInstance,
                                          int threadID);

    [DllImport(&quot;user32.dll&quot;)]
    static extern int UnhookWindowsHookEx(IntPtr hookHandle);

    [DllImport(&quot;user32.dll&quot;)]
    static extern int CallNextHookEx(IntPtr hhook,
                                     int code,
                                     IntPtr wParam,
                                     IntPtr lParam);

    static bool IsPressed(Keys check) {
        return ((Control.ModifierKeys &amp;#038; check) == check);
    }

    static void Main() {

        Stream sound = Assembly.GetExecutingAssembly()
            .GetManifestResourceStream(&quot;InstantRimshot.rimshot.wav&quot;);
        SoundPlayer player = new SoundPlayer(sound);
        player.Load();
        IntPtr hookHandle = IntPtr.Zero;
        hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL,
            delegate(int code, IntPtr wParam, IntPtr lParam) {
                if (code &gt;= 0 &amp;#038;&amp; wParam == (IntPtr) WM_KEYDOWN) {
                    Keys vkCode = (Keys)Marshal.ReadInt32(lParam);
                    if (Keys.I == vkCode
                    &amp;#038;&amp; IsPressed(Keys.Control)
                    &amp;#038;&amp; IsPressed(Keys.Shift)) {
                        if (IsPressed(Keys.Alt)) {
                            UnhookWindowsHookEx(hookHandle);
                            Application.Exit();
                            return CallNextHookEx(hookHandle, code, wParam, lParam);
                        } else {
                            player.Play();
                        }
                    }
                }
                return CallNextHookEx(hookHandle, code, wParam, lParam);
            }, IntPtr.Zero, 0);
        Application.Run();
    }

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://tech.einaregilsson.com/2009/06/20/instant-rimshot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coco/R plugin for Visual Studio</title>
		<link>http://tech.einaregilsson.com/2009/03/20/cocor-plugin-for-visual-studio/</link>
		<comments>http://tech.einaregilsson.com/2009/03/20/cocor-plugin-for-visual-studio/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 21:43:42 +0000</pubDate>
		<dc:creator>einar</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Coco/R]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[compilers]]></category>

		<guid isPermaLink="false">http://tech.einaregilsson.com/?p=219</guid>
		<description><![CDATA[I&#8217;ve blogged before about the excellent Coco/R parser generator. I&#8217;m using it a lot in my masters project and I&#8217;m happy with it but there were a few things I wished worked differently. The main thing was that I wanted better Visual Studio integration. I had set up a pre-build event that generated the parser [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve <a href="http://tech.einaregilsson.com/2009/01/29/cocor-for-boo/">blogged before</a> about the excellent <a href="http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/">Coco/R parser generator</a>. I&#8217;m using it a lot in my masters project and I&#8217;m happy with it but there were a few things I wished worked differently. The main thing was that I wanted better Visual Studio integration. I had set up a pre-build event that generated the parser and scanner before every build. However there is obviously no need to re-generate the files unless the grammar file has changed. Generating on every build also had the effect that Visual Studio kept prompting me about reloading changed files and I had to build to see if there were any errors in my grammar. So, I decided to create a Visual Studio plugin for Coco/R myself.<span id="more-219"></span></p>
<p>Coco/R is open source and written in C# (at least one version of it) so it was easy to get the source. I then looked at a couple of tutorials on Visual Studio plugins and managed to hack together an plugin that works well enough for my needs. I also made a small change to the way Coco/R generates its parsers and scanners from frame files. Here are the features that are unique to the plugin:</p>
<ul>
<li>Works with Visual Studio 2005 and 2008</li>
<li>When you click &#8216;Add a new item&#8217; in a C# project, you&#8217;ll find a &#8216;Coco/R Attributed Grammar&#8217; option under My Templates at the bottom of the screen. The .atg file you get has a simple example grammar that just reads numbers or identifiers. I wanted this because everytime I create a new .atg I start by finding an old one and copying the basics from it.</li>
<li>Every time an .atg file is saved, the parser and scanner are re-generated. If the generated files are open then the AddIn closes them before re-generating, to avoid the dreaded &#8220;Files were reloaded&#8221; prompt.</li>
<li>Errors and warnings from Coco show up in Visual Studio&#8217;s error list window just like build errors as soon as you save the .atg file.</li>
<li>Instead of using frame files, the plugin uses partial classes for the parser and scanner. There are four files, Parser.cs, Parser.generated.cs, Scanner.cs and Scanner.generated.cs. This allows you to add stuff to your parser and scanner in an actual .cs file so you get the benefit of the Visual Studio editor, instead of having to write it in the .frame file or the .atg file.</li>
</ul>
<p>So, that&#8217;s it. You can <a href="http://tech.einaregilsson.com/download/CocoSetup.msi">download an MSI installer for it</a> and you can also view or checkout the source at <a href="http://einaregilsson.googlecode.com/svn/dotnet/CocoPlugin/">http://einaregilsson.googlecode.com/svn/dotnet/CocoPlugin/</a>. Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.einaregilsson.com/2009/03/20/cocor-plugin-for-visual-studio/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>JScript REPL</title>
		<link>http://tech.einaregilsson.com/2009/02/20/jscript-repl/</link>
		<comments>http://tech.einaregilsson.com/2009/02/20/jscript-repl/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 20:09:02 +0000</pubDate>
		<dc:creator>einar</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[tips & tricks]]></category>
		<category><![CDATA[utilities]]></category>

		<guid isPermaLink="false">http://tech.einaregilsson.com/?p=197</guid>
		<description><![CDATA[Lately I have been doing some COM automation stuff on Windows. I&#8217;ve been using JScript (Microsoft&#8217;s JavaScript implementation) since that&#8217;s available on all Windows machines, and the other option, VBScript, is horrible. Normally I would use Python and the win32com package, but I needed to make some scripts that could work on any box without [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I have been doing some COM automation stuff on Windows. I&#8217;ve been using JScript (Microsoft&#8217;s JavaScript implementation) since that&#8217;s available on all Windows machines, and the other option, VBScript, is horrible. Normally I would use Python and the win32com package, but I needed to make some scripts that could work on any box without installing Python first. JScript is a pretty nice language, but it doesn&#8217;t come with a <a href="http://en.wikipedia.org/wiki/Read-eval-print_loop">REPL</a> built in, which is very handy when you&#8217;re doing experimental stuff (REPL = Read-Execute-Print-Loop). Now, writing your own REPL in a dynamic language with an <strong>eval</strong> statement is pretty easy, so I did just that. It took about 30 lines, of which about 10 are just about printing evaluated expressions nicely. <span id="more-197"></span></p>
<p>Here&#8217;s how it works. If you enter a single line that ends with ; it is evaluated immediately. If it doesn&#8217;t start with if,while,var,try,do,with,function,switch,for or print it is assumed to be an expression and its value is printed to the screen. If a new line doesn&#8217;t end with ; is is assumed to be the beginning of a larger code block. In that case the script will keep reading in code without evaluating until either you end a line with ;; or you enter a line which consists of only one ;. The script also includes a convenience function called print() to print expressions. The script just uses a single variable, _$, so it won&#8217;t conflict with variables you define when using it. Writing a single line with just the word &#8216;exit&#8217; will stop the script. Below you can see an example of the usage of the REPL. This sample is actually a online version that I did for fun, you can write in any command in it and try it out, it works exactly the same as the real script, although the online version took quite a bit more code. It even has command history, activated with the up and down arrow keys. (There are some issues in Internet Explorer, tab key doesn&#8217;t work and strings with html entities my display incorrectly, because of <a href="http://stud3.tuwien.ac.at/~e0226430/innerHtmlQuirk.html">weird behaviour with &lt;pre&gt; tags and the .innerHTML property).</a></p>
<p><a href="http://tech.einaregilsson.com/download/jsrepl.js">Download script</a> | <a href="http://tech.einaregilsson.com/download/jsrepl.js.html">View script syntax highlighted</a></p>
<p><iframe src="http://tech.einaregilsson.com/repl.html" style="width:620px; height:400px;overflow-x:hidden; border-style:none; border:solid 0px black;" frameborder="0"></iframe></p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.einaregilsson.com/2009/02/20/jscript-repl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>While Compiler for the .NET Platform</title>
		<link>http://tech.einaregilsson.com/2009/02/06/while-compiler-for-the-dotnet-platform/</link>
		<comments>http://tech.einaregilsson.com/2009/02/06/while-compiler-for-the-dotnet-platform/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 14:12:34 +0000</pubDate>
		<dc:creator>einar</dc:creator>
				<category><![CDATA[Boo]]></category>
		<category><![CDATA[While]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[compilers]]></category>

		<guid isPermaLink="false">http://tech.einaregilsson.com/?p=191</guid>
		<description><![CDATA[My masters project at DTU involves writing compilers for the .NET platform and since I had never written a compiler before I decided to start by writing a compiler for a simple language called While. This language is used in the Program Analysis course that is taught at DTU and has integer and boolean expressions, [...]]]></description>
			<content:encoded><![CDATA[<p>My masters project at DTU involves writing compilers for the .NET platform and since I had never written a compiler before I decided to start by writing a compiler for a simple language called While. This language is used in the Program Analysis course that is taught at DTU and has integer and boolean expressions, read and write commands, an if branching statement and a while looping statement. The compiler compiles this language and the programs can be run with the .NET CLR or Mono. The programs can also be debugged using a free graphical .NET debugger. I put the project up on Google Code, I think it is a fairly nice example of a simple compiler for .NET. It is currently written in <a href="http://boo.codehaus.org">Boo</a> but will soon be rewritten in C#. The compiler and its source code is available at <a href="http://while-language.googlecode.com">http://while-language.googlecode.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.einaregilsson.com/2009/02/06/while-compiler-for-the-dotnet-platform/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
