• Kirill Osenkov

    DateTime.UtcNow is generally preferable to DateTime.Now

    • 9 Comments

    This seems to be commonly known and accepted best practice to use DateTime.UtcNow for non-user facing scenarios such as time interval and timeout measurement.

    I’ve just done an audit of the Roslyn codebase and replaced most DateTime.Now calls with DateTime.UtcNow. I thought it’d be useful to post my changeset description here (although none of it is new – I just summarize some common knowledge readily available in the sources linked below).

    ====

    Replacing DateTime.Now with DateTime.UtcNow in most cases.

    We should be using DateTime.Now only in user-facing scenarios. It respects the timezone and Daylight Savings Time (DST), and the user feels comfortable when we show them the string that matches their wall clock time.

    In all other scenarios though DateTime.UtcNow is preferable.

    First, UtcNow usually is a couple of orders of magnitude faster, since Now is basically first calling UtcNow and then doing a very expensive call to figure out the time zone and daylight savings time information. Here’s a great chart from Keyvan’s blog (modified to avoid allocations of the Stopwatch object):

    image

    Second, Now can be a big problem because of a sudden 1-hour jump during DST adjustments twice a year. Imagine a waiting loop with a 5-sec timeout that happens to occur exactly at 2am during DST transition. The operation that you expect to timeout after 5 sec will run for 1 hour and 5 seconds instead! That might be a surprise.

    Hence, I'm replacing DateTime.Now with DateTime.UtcNow in most situations, especially polling/timeout/waiting and time interval measurement. Also, everywhere where we persist DateTime (file system/database) we should definitely be using UtcNow because by moving the storage into a different timezone, all sorts of confusion can occur (even "time travel", where a persisted file can appear with a future date). Granted, we don't often fly our storage with a supersonic jet across timezones, but hey.

    For precise time interval measurements we should be using System.Diagnostics.StopWatch which uses the high resolution timer (QueryPerformanceCounter). The resolution of both DateTime.Now and DateTime.UtcNow is very low – about 10 ms – this is a huge time interval!

    For a cheap timestamp, we should be generally using Environment.TickCount - it's even faster than DateTime.UtcNow.Ticks.

    I'm only leaving DateTime.Now usages in test code (where it's never executed), in the compiler Version parsing code (where it's used to generate a minor version) and in a couple of places (primarily test logging and perf test reports) where we want to output a string in a local timezone.

    Sources:

    * http://www.keyvan.ms/the-darkness-behind-datetime-now
    * http://stackoverflow.com/questions/62151/datetime-now-vs-datetime-utcnow
    * http://stackoverflow.com/questions/28637/is-datetime-now-the-best-way-to-measure-a-functions-performance

  • Kirill Osenkov

    Install-Package Roslyn

    • 1 Comments

    I am happy to announce that the core C# and VB compiler assemblies from our first Roslyn CTP are now published as a NuGet package! The package name is... drumroll... ‘Roslyn’!

    Aside: If you haven’t tried out NuGet yet, NuGet is definitely worth a try – it’s a simple to use but powerful package/library/dependency manager, and right now it’s the top free download in the Visual Studio 2010 Extension Manager:

    image

    Once you’ve installed NuGet, you can add the Roslyn package as a dependency to your project either using the Manage NuGet Packages dialog:

    image

    image

    or the PowerShell-based command line called the Package Manager Console:

    image

    The Roslyn package contains the six core assemblies:

    1. Roslyn.Compilers.dll
    2. Roslyn.Compilers.CSharp.dll
    3. Roslyn.Compilers.VisualBasic.dll
    4. Roslyn.Services.dll
    5. Roslyn.Services.CSharp.dll
    6. Roslyn.Services.VisualBasic.dll

    These are the exact binaries that we’ve shipped in the October 2011 CTP, packaged for your convenience. Note that the remaining content of the CTP, such as the IDE and refactoring support is not part of the package – you will still need the CTP to gain access to those.

    Also please keep in mind that the license doesn’t allow you to redistribute the Roslyn binaries with your projects at this time. But that’s just common sense – the compilers are still at a pretty early (preview-only) stage with about half the language not supported yet. You wouldn’t want to ship these binaries to customers just yet, because we don’t even guarantee that whatever compiles produces correct IL!

    I invite you to use the Roslyn forum if you have questions or feedback. Thanks!

  • Kirill Osenkov

    Roslyn CTP

    • 5 Comments

    For the past year and a half or so I’ve been working on the QA team for the Roslyn project. The goal of our project is (simply put) to make our managed compilers and language services actually managed :-)

    I’m happy to announce that we’ve released our first CTP today and it is available for immediate download at http://msdn.com/roslyn.

    I’ve posted a more detailed overview of the release over on the Visual Studio blog. Now that we can actually talk about our work, I expect to blog more about Roslyn and otherwise keep in touch with the developer community. I’ll be also tweeting more about Roslyn (@KirillOsenkov). I suggest that we use the #RoslynCTP hashtag on Twitter for Roslyn-related discussions (#Roslyn is already taken by the actual city of Roslyn).

    We will also be participating on the Roslyn forum, and closely monitoring the Connect bugs and suggestions.

    Below I want to show a few demos of what Roslyn can do. I’ll start with excerpts from one of the samples that we ship (APISampleUnitTests) – a set of unit-tests that demonstrates the usage of the compiler API. To me, there’s no better way to learn an API surface than by reading the unit-tests that cover it.

    Have you ever needed a full-fidelity, high performance C# parser?

    [TestMethod]
    public void TextParseTreeRoundtrip()
    {
        string text = "class C { void M() { } } // exact text round trip, including comments and whitespace";
        SyntaxTree tree = SyntaxTree.ParseCompilationUnit(text);
        Assert.AreEqual(text, tree.ToString());
    }

    Or perhaps you prefer VB?

    <TestMethod()>
    Sub TextParseTreeRoundtrip()
        Dim code =
    <code>
    Class C
      Sub M()
      End Sub
    End Class ' exact text round trip, including comments and whitespace
    </code>.GetCode()
     
        Dim tree = SyntaxTree.ParseCompilationUnit(code)
        Assert.AreEqual(code, tree.Text.ToString())
    End Sub
    

    You can also parse a stand-alone expression:

    ExpressionSyntax expression = Syntax.ParseExpression("1 + 2");
    

    Want to do LINQ queries over your code?

    [TestMethod]
    public void FindNodeUsingQuery()
    {
        string text = "class C { void M(int i) { } }";
        SyntaxNode root = Syntax.ParseCompilationUnit(text);
        var parameterDeclaration = root
            .DescendentNodes()
            .OfType<ParameterSyntax>()
            .First();
        Assert.AreEqual("i", parameterDeclaration.Identifier.ValueText);
    }
    

    Or transform your code using Visitors?

    [TestMethod]
    public void TransformTreeUsingSyntaxRewriter()
    {
        string text = "class C { void M() { } int field; }";
        SyntaxTree tree = SyntaxTree.ParseCompilationUnit(text);
        SyntaxNode newRoot = new RemoveMethodsRewriter().Visit(tree.Root);
        Assert.AreEqual("class C { int field; }", newRoot.GetFullText());
    }
     
    private class RemoveMethodsRewriter : SyntaxRewriter
    {
        protected override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
        {
            return null;
        }
    }

    What about executing custom code (scripting)?

    [TestMethod]
    public void SimpleEvaluationUsingScriptEngine()
    {
        ScriptEngine engine = new ScriptEngine();
        int result = engine.Execute<int>("1 + 2");
        Assert.AreEqual(3, result);
    }
    

    Or compiling a program end-to-end?

    [TestMethod]
    public void EndToEndCompileAndRun()
    {
        var expression = "6 * 7";
        var text = @"public class Calculator
    {
    public static object Evaluate()
    {
    return $;
    } 
    }".Replace("$", expression);
     
        var tree = SyntaxTree.ParseCompilationUnit(text);
        var compilation = Compilation.Create(
            "calc.dll",
            options: new CompilationOptions(assemblyKind: AssemblyKind.DynamicallyLinkedLibrary),
            syntaxTrees: new[] { tree },
            references: new[] { new AssemblyFileReference(typeof(object).Assembly.Location) });
     
        Assembly compiledAssembly;
        using (var stream = new MemoryStream())
        {
            EmitResult compileResult = compilation.Emit(stream);
            compiledAssembly = Assembly.Load(stream.GetBuffer());
        }
     
        Type calculator = compiledAssembly.GetType("Calculator");
        MethodInfo evaluate = calculator.GetMethod("Evaluate");
        string answer = evaluate.Invoke(null, null).ToString();
     
        Assert.AreEqual("42", answer);
    }
    

    Have you ever wanted to write your .bat files in C#, with IntelliSense and full compiler support?

    image

    image

    There’s more. Stay tuned!

  • Kirill Osenkov

    How to get DTE from Visual Studio process ID?

    • 4 Comments

    DTE is an automation framework that is used to programmatically control Visual Studio, often from another process. It internally uses COM remoting to execute commands from another process on the VS UI thread.

    A while back I have written about How to start Visual Studio programmatically and get the DTE object to control the devenv.exe process. But how to get the DTE object to automate an already running Visual Studio instance? Or how to get the DTE object to automate Visual Studio started from an experimental hive (using the /rootsuffix command line option)?

    Here’s the code (need to reference EnvDTE, which is a PIA, no pun intended):

    using System;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;
    using EnvDTE;
     
    public class AutomateVS
    {
        [DllImport("ole32.dll")]
        private static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);
     
        public static DTE GetDTE(int processId)
        {
            string progId = "!VisualStudio.DTE.10.0:" + processId.ToString();
            object runningObject = null;
     
            IBindCtx bindCtx = null;
            IRunningObjectTable rot = null;
            IEnumMoniker enumMonikers = null;
     
            try
            {
                Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx));
                bindCtx.GetRunningObjectTable(out rot);
                rot.EnumRunning(out enumMonikers);
     
                IMoniker[] moniker = new IMoniker[1];
                IntPtr numberFetched = IntPtr.Zero;
                while (enumMonikers.Next(1, moniker, numberFetched) == 0)
                {
                    IMoniker runningObjectMoniker = moniker[0];
     
                    string name = null;
     
                    try
                    {
                        if (runningObjectMoniker != null)
                        {
                            runningObjectMoniker.GetDisplayName(bindCtx, null, out name);
                        }
                    }
                    catch (UnauthorizedAccessException)
                    {
                        // Do nothing, there is something in the ROT that we do not have access to.
                    }
     
                    if (!string.IsNullOrEmpty(name) && string.Equals(name, progId, StringComparison.Ordinal))
                    {
                        Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject));
                        break;
                    }
                }
            }
            finally
            {
                if (enumMonikers != null)
                {
                    Marshal.ReleaseComObject(enumMonikers);
                }
     
                if (rot != null)
                {
                    Marshal.ReleaseComObject(rot);
                }
     
                if (bindCtx != null)
                {
                    Marshal.ReleaseComObject(bindCtx);
                }
            }
     
            return (DTE)runningObject;
        }
     
        static void Main(string[] args)
        {
            var devenv = System.Diagnostics.Process.Start("devenv.exe");
     
            DTE dte = null;
            do
            {
                System.Threading.Thread.Sleep(2000);
                dte = GetDTE(devenv.Id);
            }
            while (dte == null);
     
            dte.ExecuteCommand("View.CommandWindow");
            dte.StatusBar.Text = "Hello World!";
            System.Threading.Thread.Sleep(2000);
            dte.ExecuteCommand("File.Exit");
            devenv.WaitForExit();
            Marshal.ReleaseComObject(dte);
        }
    }
    

    When Visual Studio starts (regardless if it was passed the /rootsuffix command line argument), it places itself onto the Running Object Table (aka ROT). We know the moniker that the Visual Studio process will use to identify itself (it’s !VisualStudio.DTE.10.0:1234, where 1234 is the devenv.exe process ID). We then enumerate though all the objects in the ROT and find the one with the right moniker.

    Then you can just keep using the DTE object as if you’re writing a macro (Visual Studio macros also use DTE to automate VS).

  • Kirill Osenkov

    How Microsoft Names Releases… And What You Can Do About It

    • 0 Comments

    image

    Microsoft® SQL Server® 2008 R2 SP1 Feature Pack CTP1.

    Scott Hanselman wrote a blog post called Request for Comments: Issues with .NET and Microsoft Product Versioning. He welcomes your feedback either in his blog comments or a Twitter Poll for you to spread around.

  • Kirill Osenkov

    In ngen’ed assemblies, static field initializers don’t run until the field is first accessed

    • 3 Comments

    Interesting fact that I discovered today: usually, static field initializers run whenever the parent type is first loaded. However when you ngen the assembly, apparently you can load the type and work with it – static field initializers will only be executed immediately before you actually access the field.

    I’ve run into this by having a static Stopwatch timer = Stopwatch.StartNew(); in one of my types. It was supposed to measure an application’s startup time, but I noticed that after NGEN’ing the assembly the timer always returned a value close to 0.

    Here’s the code to verify this behavior:

    using System;
     
    class Program
    {
        private static int field = Initialize("Field initializer");
     
        static void Main(string[] args)
        {
            Initialize("Main");
            field = 1; // touch the field
        }
     
        private static int Initialize(string message)
        {
            Console.WriteLine(message + ": " + DateTime.Now.Ticks.ToString());
            return 0;
        }
    }

    This works the same for .NET 4.0 SP1 for Debug/Release and x86/x64. I didn’t try other frameworks/OS/platforms.

    Here’s the output from the console:

    E:\>NgenedStaticFieldInitializers.exe
    Field initializer: 634462768999291588
    Main: 634462768999321594
    
    E:\>NgenedStaticFieldInitializers.exe
    Field initializer: 634462769013544438
    Main: 634462769013574444
    
    E:\>ngen install NgenedStaticFieldInitializers.exe
    Microsoft (R) CLR Native Image Generator - Version 4.0.30319.1
    Copyright (c) Microsoft Corporation.  All rights reserved.
    Installing assembly E:\NgenedStaticFieldInitializers.exe
    1>    Compiling assembly E:\NgenedStaticFieldInitializers.exe (CLR v4.0.30319) .
    ..
    1>NgenedStaticFieldInitializers, Version=1.0.0.0, Culture=neutral, PublicKeyToke
    n=null 
    
    E:\>NgenedStaticFieldInitializers.exe
    Main: 634462769095630852
    Field initializer: 634462769095660858
    
    E:\>NgenedStaticFieldInitializers.exe
    Main: 634462769108903506
    Field initializer: 634462769108933512
  • Kirill Osenkov

    Tabula

    • 5 Comments

    Another announcement for geometry enthusiasts today. David Hartmann, an experienced math teacher and my active co-developer on the Live Geometry project, has released a professional geometry learning software: Tabula.

    http://numeracyworks.com/

    Tabula is written in Silverlight 4 and is based on our Live Geometry engine, however it takes it way further in terms of features, usability and being a great professional product for students, teachers and hobbyists. Tabula introduces unique capabilities for interactive “paper folding”, taping, cutting and rearranging, as well as close-to-real-life tools like eraser, marker, compass, ruler, protractor, and so on. I encourage you to watch this short video that gives a great overview of Tabula’s possibilities:

    Tabula

    http://www.youtube.com/watch?v=9PM_PzQqK6Q

    I’ll also allow myself to steal some of David’s thunder and post the links to screenshots here:


    Compass and Mark on Segment

    Ruler and Measure of a Side

    Protractor and Measured Angle

    Folded Square

    Sine Function

    Constructed Pentagon

    Magic Square

    Pentominos

    Sierpinski's Triangle

    Custom Settings and Inspector Visible

    I’m very excited and enthusiastic about Tabula and I hope it will grow and develop. Dear readers, I’d like to ask you a personal favor at this time: if you like the project and would like to show your support, please help David spread the news! As always, let him or me know your opinion/questions/feedback. Thanks!

  • Kirill Osenkov

    Live Geometry for Windows Phone 7

    • 4 Comments

    I was really curious to try to write an app for WP7, but I didn’t have a whole lot of ideas. It’s hard to come up with something original when so many apps are already out there. And I don’t have capacity for a large complex app (if I had time for a very large app, I would write a decent GPS navigation software because it seems that Tomtom and Garmin aren’t in a rush to create a WP7 version of their systems).

    Nevertheless, since I have some experience with math educational software, I decided to leverage my http://livegeometry.codeplex.com open-source project to try and create an app with at least some educational value. Writing a full-blown live geometry app on the phone didn’t seem plausible to me since the screen real estate is very limited and I couldn’t figure out how to make the interaction usable. However it dawned on me that a little “fun facts” or “geometry gems” gallery would look quite nice on the phone.

    So here it is: http://social.zune.net/redirect?type=phoneApp&id=5e8194b7-d0ea-df11-9264-00237de2db9e

    (or just search for “Live Geometry” on Marketplace).

    It’s a collection of 35 interactive geometry drawings each of which illustrates a certain fact or a theorem of elementary geometry. As always you can drag the points around to experiment with the construction. Here are the screenshots that you will also see on the marketplace:

    StartSquaresAroundRhombusPythagoreanTheoremParabolaGraph

    CircumscribedCircleBezier

  • Kirill Osenkov

    Improved HTML Copy in the latest Productivity Power Tools

    • 2 Comments

    Executive summary: HTML Copy is an extension for Visual Studio 2010 (part of Productivity Power Tools) that automatically copies source code from the Visual Studio editor to clipboard in HTML format (in addition to the existing TEXT and RTF formats), preserving font and color information. It does so automatically every time you press Ctrl+C or otherwise invoke the Edit.Copy command, so there is no explicit way to invoke the feature (it has no UI of its own).

    In the latest release: all font and background color information is now correctly written to HTML, dark schemes such as those from http://studiostyl.es are now correctly supported. Format of the output markup is now customizable via a Tools Options page.

    Hint: if you don’t want to read all the long details below, but still interested or have a question, there’s an FAQ at the end of this post. Don’t miss it!

    Also see my previous posts about HTML Copy:

    Configuring the output via the Tools Options page

    I guess the biggest improvement in this version is that I finally added a Tools Options page that lets you customize the HTML markup that ends up on the clipboard:

    Tools Options page

    You can select how the snippet is prefixed (arbitrary markup, could be anything, e.g. custom JavaScript etc.) By default, I use <pre style=”...”>, because after looking at various blogs this is the most common way to format code. Moreover, you can insert the actual values for the font, foreground color and background color in curly braces. If you don’t want to have the values embedded, just remove the macro in curlies and hardcode your own value.

    Format for the colorized spans – use CSS or embed styles directly

    Colorized spans in code are encoded using the <span> tag – you can’t change that.

    However, you can choose whether to use CSS for classes (EmitSpanClass). If you select this one, highlighted spans from the editor will add the actual classification type of the span into the resulting HTML markup:

    <span class="keyword">public</span>

    The classification type is what the language service actually classifies the token as, so the full fidelity information from the compiler is preserved in your output HTML. For instance, DayOfWeek.Friday will be output as:

    <span class="User Types(Enums)">DayOfWeek</span><span class="operator">.</span><span class="identifier">Friday</span>

    Then you just have to define your own CSS for the various classification types that the compiler uses, and your code will be correctly colorized in the browser.

    If you don’t want to use separate CSS styles however, you have the option to embed the font and color information directly in your HTML. Set EmitSpanStyle to true (and EmitSpanClass to false), and you will produce stand-alone, independent HTML that doesn’t need any CSS:

    <span style="color:blue;">public</span>
    <span style="color:#2b91af;">DayOfWeek</span>.Friday

    Preserving full language fidelity from the Visual Studio editor

    HTML Copy has an advantage over other code formatting tools that colorize code for the web using their own, simple rules (often RegEx based). HTML Copy colorizes code exactly how Visual Studio editor displays it. Also, this works just as well for other code formats, such as HTML, VB, F# etc. As long as the VS editor has classified the text, we just grab that information and output it to clipboard while preserving the exact classification types and classification format definitions.

    The controversy around the <br> tag

    You have an option to replace line breaks with the <br> tag. Why? I had done some research to see how different RSS readers present formatted code and it turns out, if you use Outlook RSS Feed Reader, it has a bug where it just ignores line break characters inside <pre> tags and lumps all the code onto one long line which is word-wrapped. I’ve let the Office team know about the bug, but in the meanwhile, I decided to provide the option to use the <br> tag instead of line break in HTML. Downside of it is that in HTML source, your code looks like one long line, but the good news is that RSS Reader in Outlook then correctly displays the text. Other readers also correctly display <BR> tags inside <PRE> tags, so we should be good here, no?

    No.

    Internet Explorer doesn’t copy the <br> as a line break when selecting the code in the page and copying it to clipboard. Suppose you’re reading a blog and you would like to copy the code from the webpage. You select it, paste into notepad and you get one long line! That’s why, if you want your readers to be able to copy your code correctly from a webpage in IE, don’t use the <BR> tag, use the line break in HTML. I’ve let the IE team know about the bug (preserve line breaks when copying <BR> inside <PRE> to clipboard), but they didn’t fix it in time before IE9 shipped.

    The controversy around the space and &nbsp;

    A similar “surprise” was awaiting me when I installed Windows Live Writer 2011 to test HTML Copy with their latest version. Live Writer used to be the tool that I LOVED, because it was simple, did the right thing and was a pleasure to use.

    Enter Windows Live Writer 2011.

    When pasting HTML from clipboard using Ctrl+Alt+V, DOWN, ENTER, it apparently thinks that you pasted code from Word, and their special algorithm kicks in that is supposed to “fix” the tangled Word formatting. In reality however, they take the clean and well-formed HTML that I put to clipboard and mess it up beyond any recognition. In particular, if you were using spaces for indentation in your code, it will at random insert inexplicable &nbsp; all over the place. I’ve found that if I replace all my spaces with &nbsp; myself, then Live Writer at least has some mercy for the HTML markup and while still mangled, it displays more or less correctly in the browser, so I included the option. Naturally, I’ve done due diligence and informed the Live Writer team about this unfortunate behavior regression. Let’s see if they fix it as promptly as the Internet Explorer team did (ha-ha, my bitter sarcasm!).

    Bug fixes

    This release has a few bug fixes that I’ve accumulated from customer reports (thanks everyone for your feedback!). One good news is that I now correctly preserve the background color and font information, so the tool should now correctly work for folks with a dark scheme (sorry for the white on white stupidity – I should have known better!).

    Copy from Remote Desktop and other Windows Clipboard oddities

    One major thing that Ameen from the editor team helped me fix is that sometimes Copy just didn’t work inside Remote Desktop sessions. If you have HTML Copy installed, and press Ctrl+C inside remote desktop, and the code doesn’t get copied to clipboard – please just try copying it again a few times.

    The story (Raymond Chen style). Windows clipboard obviously needs to be available to all the processes, which, naturally, run concurrently. I would have thought that they have some sort of a reader-writer lock, a monitor, semaphore – anything. Well, no. If a process tries to access clipboard while the clipboard is already open, it just fails with CLIPBRD_E_CANT_OPEN. A good description of this can be found here or here for example.

    In brief, if you copy stuff to clipboard in remote desktop, shortly after you’re done, it will open the clipboard again to synchronize it back to the host machine. About the same time however, I come in and try to open the clipboard too (because I want to augment the TEXT and RTF formats already there with the new HTML format). Obviously, we both fail, and what do we both do? We both go sleep 100ms. Yes, that’s how the WinForms team and the WPF team worked around the lack of proper synchronization in Windows Clipboard. They retry 10 times and sleep for 100 milliseconds in between. The problem now is: they all wake up and try again at the same time. Better solution here would be at least to sleep a random number of milliseconds (module timer granularity), but alas this is not the case here.

    The way I wrote HTML Copy originally is that it was listening to the Edit.Cut and Edit.Copy VS commands, and after VS has put TEXT and RTF to clipboard, I happened to additionally put HTML on clipboard in a second transaction. Now I just completely suppress Visual Studio’s handling of the Cut and Copy commands, and copy all the formats, TEXT, RTF and HTML in one fell swoop. This should hopefully alleviate the problems connected with copying over remote desktop.

    The next most requested feature (not there yet)

    The request I’ve been hearing the most is to add some sort of a command, that wouldn’t put HTML to clipboard in a separate clipboard format parallel to text and RTF, but instead put the HTML tags to clipboard directly in text format, so that you can paste source yourself to a simple text box such as the one in Wordpress or other web-based tools.

    Obviously I can’t copy HTML markup to plain text clipboard during normal operation, because this would break copying code around in VS during programming (on second thought – hmm, maybe not such a bad idea after all??!)

    So I guess I need to mentally prepare myself for adding an actual Visual Studio menu item to explicitly copy HTML markup to clipboard in plaintext format. Let’s hope I get around to it before the next update of the Productivity Power Tools.

    FAQ

    How do I use HTML Copy?

    Provided you have installed Visual Studio 2010 and Productivity Power Tools, there are only two simple sides to it – Produce HTML and Consume HTML. You Produce HTML (or simply put it on clipboard) by copying code in the editor as you normally would (most people prefer Ctrl+C). You Consume HTML by pasting it in a program which has a “Paste Special” feature, such as Word, Outlook, OneNote or Windows Live Writer, and selecting HTML format instead of plain text format.

    How do I paste code in Windows Live Writer?

    Ctrl+Alt+V (or Ctrl+Shift+V on older versions) will pop up the Paste Special dialog. Then, select Keep Formatting (DOWN ARROW) and ENTER (if you don’t see Keep formatting there, it means HTML Copy didn’t work). Then you can switch to the Source view and actually examine the HTML. Caveat: Windows Live Writer 2011 mangles the HTML the moment you paste it, so please don’t blame me – I produce clean well-formed HTML without redundant tags. I also don’t use <font> tags, so if you see a <font> tag, it’s not me!

    How do I get the source for the HTML markup?

    You need a tool that lets you examine the clipboard, such as Clipview by Peter Büttner:

    image

    Don’t forget to push the View button in the top-left corner – the tool doesn’t refresh automatically! If you know a better way, please let me know!

    How does this compare to other tools?

    There are plenty existing tools out there to let you format code on your blog. Here are some links:

    SyntaxHighlighter by Alex Gorbatchev is very nice and seems to be popular. One minor thing with it is that it requires JavaScript (not all readers support it). Code will still display decently though, so it’s not a big issue. Another downside of tools like this – they do their own colorization, and don’t preserve the exact classification of the compiler. Thus, they’re less precise. But again, this is very minor – it works reasonably well in the general case.

    CopySourceAsHtml seems to be very nice (and HTML Copy is essentially the same thing, but Colin was first!) He did a fantastic job with the APIs we exposed at the time. We both colorize code correctly (like VS does), but we don’t output as neat functionality as SyntaxHighlighter (ability to copy/print code for example, which requires JavaScript). I also don’t support line numbers in HTML Copy.

    Paste from VisualStudio by Douglas Stockwell is a Windows Live Writer plug-in that takes RTF from clipboard and converts it to HTML. An advantage is that it preserves correct coloring from the editor, downside is that it’s only for Live Writer.

    Why did you decide to write yet another tool like this, with plenty of good tools already out there?

    Architecture. With the brand new editor in Visual Studio 2010, it’s design is so nice and pluggable, it allows extensions to easily add whatever formats to clipboard. However text and RTF were implemented in the box, but HTML wasn’t. I really wanted a tool like this to be in the box, so I looked around. Unfortunately, the implementation of CopySourceAsHtml (the best tool I’ve found) didn’t take advantage of the new editor APIs so I decided to write my own. Since Productivity Power Tools seemed like a good ship vehicle to give my implementation proper testing, I decided to do just that. Maybe if the tool is good enough one day, we’ll put this in the box.

    What are the known bugs and feature requests?

    1. Again, the biggest is showing raw HTML markup to the user.
    2. Then I have a request from Tomáš Skála to normalize indentation (should be something along the lines (no pun intended!) of while(lines.All(line => line.StartsWithSpace())) lines = lines.Select(line => line.TrimFirstSpace())
    3. Then I have a bug report from csrowell where Ctrl+L on two non-fully selected lines doesn’t fully delete both lines

    As always, please let me know your questions and comments if any. Thanks!

  • Kirill Osenkov

    Running .NET applications in-process using AppDomains

    • 6 Comments

    When testing a compiler for a managed language a very convenient end-to-end testing technique is to compile a test program, then run it and verify that it gives the expected output. Not only you cover all parts of the compiler in this manner (parser, binder and emitter), but also you verify that your compiler produces correct IL (otherwise the CLR won’t load and verify your assembly) and your final program has the expected behavior (output has to match).

    One downside is that if you have 50,000 test programs, you have to pay the process startup cost and the CLR startup cost 50,000 times. AppDomains to the rescue – they were originally designed as lightweight managed processes, so why not use them as such?

    To demonstrate this approach, we’re going to write a .NET program that can run any .NET Console application, intersept its output to the Console, and print it out for demo purposes. First of all, let’s create a C# console application that prints out “Hello World” and save it as Program.exe. Then let’s create a sample “verifier” program that will start and run Program.exe without spinning up a separate process and a separate CLR instance:

    using System;
    using System.IO;
    using System.Reflection;
     
    namespace AppDomainTools
    {
        public class Launcher : MarshalByRefObject
        {
            public static void Main(string[] args)
            {
                TextWriter originalConsoleOutput = Console.Out;
                StringWriter writer = new StringWriter();
                Console.SetOut(writer);
     
                AppDomain appDomain = AppDomain.CreateDomain("Loading Domain");
                Launcher program = (Launcher)appDomain.CreateInstanceAndUnwrap(
                    typeof(Launcher).Assembly.FullName,
                    typeof(Launcher).FullName);
     
                program.Execute();
                AppDomain.Unload(appDomain);
     
                Console.SetOut(originalConsoleOutput);
                string result = writer.ToString();
                Console.WriteLine(result);
            }
     
            /// <summary>
            /// This gets executed in the temporary appdomain.
            /// No error handling to simplify demo.
            /// </summary>
            public void Execute()
            {
                // load the bytes and run Main() using reflection
                // working with bytes is useful if the assembly doesn't come from disk
                byte[] bytes = File.ReadAllBytes("Program.exe");
                Assembly assembly = Assembly.Load(bytes);
                MethodInfo main = assembly.EntryPoint;
                main.Invoke(nullnew object[] { null });
            }
        }
    }
    

    This approach is especially beneficial if you have to run a lot of small programs – you save a lot on process startup costs and CLR startup costs. Note that I’m representing an assembly as a plain byte array – this allows us to avoid disk I/O if the assembly was just compiled and wasn’t even saved to disk, so you can compile and run it immediately, without ever writing the compiler’s output to disk.

    Also note that Launcher inherits from MarshalByRefObject – this allows us to pass data back and forth across AppDomain boundaries. If you like, just create an instance field in the Launcher class and it will get automatically serialized/deserialized when it passes through the DoCallback invocation point.

  • Kirill Osenkov

    Fix available for the VS 2010 context menu scrolling issue

    • 0 Comments

    http://blogs.msdn.com/b/visualstudio/archive/2010/10/14/hotfixes-available-for-scrolling-context-menu-problem.aspx

    Sorry we didn’t fix the bug before RTM, but better late than never... Hopefully the fix works fine for everyone.

  • Kirill Osenkov

    C# Syntax All-In-One file, attempt 3

    • 11 Comments

    OK, my dear readers, I’ve finally had a chance to incorporate your invaluable feedback (really, this is helpful to me in my work) from the previous two attempts to produce another iteration of the Most Complete C# Syntax Frankenstein Junkyard. Let’s see if we are still missing any syntax construct (that hits a new codepath in the parser, not including error tolerance cases):

    #error Error message
    #warning Warning message
    #pragma warning disable 414, 3021
    #pragma warning restore 3021
    #line 6
    #line 2 "test.cs"
    #line default
    #line hidden
    #define foo
    #if foo
    #else
    #endif
    #undef
    foo

    extern alias
    Foo;

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using M = System.Math
    ;

    #if DEBUG || TRACE
    using System.Diagnostics;
    #elif SILVERLIGHT
    using System.Diagnostics;
    #else
    using
    System.Diagnostics;
    #endif

    #region
    Region

    #region more
    using ConsoleApplication2.Test;
    #endregion
    using
    X = int1;
    using Y = ABC.X<int
    >;

    #endregion

    [
    assembly: System.Copyright(@"(C)""

    2009"
    )]
    [
    module: System.Copyright("\n\t\u0123(C) \"2009" + "\u0123"
    )]

    class TopLevelType : IDisposable
    {
       
    void IDisposable
    .Dispose() { }
    }

    namespace
    My
    {
       
    using
    A.B;

       
    interface CoContra<out T, in
    K> { }
       
    delegate void CoContra2<[System.Obsolete()] out T, in K> () where T : struct
    ;

       
    public unsafe partial class A
    : C, I
        {
            [DllImport(
    "kernel32", SetLastError = true
    )]
           
    static extern bool CreateDirectory(string
    name, SecurityAttribute sa);

           
    private const int global = int
    .MinValue - 1;

            [
    method: Obsolete
    ]
           
    public A([param: Obsolete] int
    foo) :
               
    base
    (1)
            {
            L:
                {
                   
    int i = sizeof(int
    );
                    ++i;
                }

    #if DEBUG
          Console.WriteLine(export.iefSupplied.command);
    #endif
                const int? local = int
    .MaxValue;
               
    const Guid? local0 = new Guid
    (r.ToString());

               
    var
    привет = local;
               
    var
    мир = local;
               
    var
    local3 = 0, local4 = 1;
                local3 = local4 = 1;
               
    var local5 = null as Action ?? null
    ;
               
    var local6 = local5 is Action
    ;

               
    var
    u = 1u;
               
    var
    U = 1U;
               
    long
    hex = 0xBADC0DE, Hex = 0XDEADBEEF, l = -1L, L = 1L, l2 = 2l;
               
    ulong
    ul = 1ul, Ul = 1Ul, uL = 1uL, UL = 1UL,
                    lu = 1lu, Lu = 1Lu, lU = 1lU, LU = 1LU;
               
    int
    minInt32Value = -2147483648;
               
    int
    minInt64Value = -9223372036854775808L;

               
    bool
    @bool;
               
    byte
    @byte;
               
    char @char = 'c', \u0066 = '\u0066', hexchar = '\x0130', hexchar2 = (char
    )0xBAD;
               
    string \U00000065 = "\U00000065"
    ;
               
    decimal
    @decimal = 1.44M;
                @decimal = 1.2m;
               
    dynamic
    @dynamic;
               
    double @double = M
    .PI;
                @double = 1d;
                @double = 1D;
                @double = -1.2e3;
               
    float
    @float = 1.2f;
                @float = 1.44F;
               
    int
    @int = local ?? -1;
               
    long
    @long;
               
    object
    @object;
               
    sbyte
    @sbyte;
               
    short
    @short;
               
    string @string = @"""/*"
    ;
               
    uint
    @uint;
               
    ulong
    @ulong;
               
    ushort
    @ushort;
               
               
    dynamic
    dynamic = local5;
               
    var
    add = 0;
               
    var
    ascending = 0;
               
    var
    descending = 0;
               
    var
    from = 0;
               
    var
    get = 0;
               
    var
    global = 0;
               
    var
    group = 0;
               
    var
    into = 0;
               
    var
    join = 0;
               
    var
    let = 0;
               
    var
    orderby = 0;
               
    var
    partial = 0;
               
    var
    remove = 0;
               
    var
    select = 0;
               
    var
    set = 0;
               
    var
    value = 0;
               
    var
    var = 0;
               
    var
    where = 0;
               
    var
    yield = 0;
                where = yield = 0;

               
    if
    (i > 0)
                {
                   
    return
    ;
                }
               
    else if
    (i == 0)
                {
                   
    throw new Exception
    ();
                }
               
    var o1 = new
    MyObject();
               
    var o2 = new
    MyObject(var);
               
    var o3 = new
    MyObject { A = i };
               
    var o4 = new
    MyObject(@dynamic)
                {
                    A = 0,
                    B = 0,
                    C = 0
                };
               
    var o5 = new
    { A = 0 };
               
    var dictionaryInitializer = new Dictionary<int, string
    >
                {
                    {1,
    ""
    },
                    {2,
    "a"
    }
                };
               
    float[] a = new float
    []
                {
                    0f,
                    1.1f
                };
               
    int
    [, ,] cube = { { { 111, 112, }, { 121, 122 } }, { { 211, 212 }, { 221, 222 } } };
               
    int
    [][] jagged = { { 111 }, { 121, 122 } };
               
    int[][,] arr = new int[5][,]; // as opposed to new int[][5,5]
                arr[0] = new int[5,5];  // as opposed to arr[0,0] = new int[5];
                arr[0][0,0] = 47;
               
    int[] arrayTypeInference = new
    [] { 0, 1, };
               
    switch
    (3) { }
               
    switch
    (i)
                {
                   
    case
    0:
                   
    case
    1:
                        {
                           
    goto case
    2;
                        }
                   
    case
    2 + 3:
                        {
                           
    goto default
    ;
                           
    break
    ;
                        }
                   
    default
    :
                        {
                           
    return
    ;
                        }
                }
               
    while
    (i < 10)
                {
                    ++i;
                   
    if (true) continue
    ;
                   
    break
    ;
                }
               
    do
                {
                    ++i;
                   
    if (true) continue
    ;
                   
    break
    ;
                }
               
    while
    (i < 10);
               
    for (int
    j = 0; j < 100; ++j)
                {
                   
    for
    (;;)
                    {
                       
    for (int
    i = 0, j = 0; i < length; i++, j++) { }
                       
    if (true) continue
    ;
                       
    break
    ;
                    }
                }
                label:
               
    goto
    label;
                label2: ;
               
    foreach (var i in
    Items())
                {
                   
    if
    (i == 7)
                       
    return
    ;
                   
    else
                        continue
    ;
                }
               
    checked
                {
                   
    checked
    (++i);
                }
               
    unchecked
                {
                   
    unchecked
    (++i);
                }
               
    lock
    (sync)
                    process();
               
    using (var
    v = BeginScope())
               
    using (A a = new
    A())
               
    using (A a = new A(), b = new
    A())
               
    using
    (BeginScope())
                   
    return
    ;
               
    yield return this
    .items[3];
               
    yield break
    ;
               
    fixed (int* p = stackalloc int
    [100], q = &y)
                {
                    *intref = 1;
                }
               
    fixed (int* p = stackalloc int
    [100])
                {
                    *intref = 1;
                }
               
    unsafe
                {
                   
    int* p = null
    ;
                }
               
    try
                {
                   
    throw null
    ;
                }
               
    catch (System.AccessViolationException
    av)
                {
                   
    throw
    av;
                }
               
    catch (Exception
    )
                {
                   
    throw
    ;
                }
               
    finally
                {
                   
    try { } catch
    { }
                }
               
    var
    anonymous =
                {
                    A = 1,
                    B = 2,
                    C = 3,
                };
               
    var query = from c in
    customers
                           
    let
    d = c
                           
    where d != null
                            join c1 in customers on c1.GetHashCode() equals
    c.GetHashCode()
                           
    join c1 in customers on c1.GetHashCode() equals c.GetHashCode() into
    e
                           
    group c by
    c.Country
                               
    into
    g
                               
    orderby g.Count() ascending
                                orderby g.Key descending
                                select new
    { Country = g.Key, CustCount = g.Count() };
                query =
    from c in
    customers
                       
    select c into
    d
                       
    select
    d;
            }
            ~A()
            {
            }
           
    private readonly int
    f1;
            [
    Obsolete
    ]
            [NonExisting]
            [Foo::NonExisting(var, 5)]
            [
    CLSCompliant(false
    )]
            [
    Obsolete, System.NonSerialized, NonSerialized, CLSCompliant(true || false & true
    )]
           
    private volatile int
    f2;
            [
    return: Obsolete
    ]
            [
    method: Obsolete
    ]
           
    public void Handler(object
    value)
            {
            }
           
    public int
    m<T>(T t)
             
    where T : class, new
    ()
            {
               
    base
    .m(t);
               
    return
    1;
            }
           
    public string
    P
            {
               
    get
                {
                   
    return "A"
    ;
                }
               
    set
    ;
            }
           
    public abstract string
    P
            {
               
    get
    ;
            }
           
    public abstract int this[int
    index]
            {
               
    protected internal get
    ;
               
    internal protected set
    ;
            }
            [
    method: Obsolete
    ]
            [
    field: Obsolete
    ]
            [
    event: Obsolete
    ]
           
    public readonly event
    Event E;
            [
    event
    : Test]
           
    public event Action
    E1
            {
                [
    Obsolete
    ]
               
    add { value = value
    ; }
                [
    Obsolete
    ]
                [
    return: Obsolete
    ]
               
    remove
    { E += Handler; E -= Handler; }
            }
           
    public static A operator
    +(A first, A second)
            {
               
    Delegate handler = new Delegate
    (Handler);
               
    return
    first.Add(second);
            }
            [
    method: Obsolete
    ]
            [
    return: Obsolete
    ]
           
    public static bool operator true
    (A a)
            {
               
    return true
    ;
            }
           
    public static bool operator false
    (A a)
            {
               
    return false
    ;
            }
           
    class C
            {
            }
        }
       
    public struct S
    : I
        {
           
    public
    S()
            {
            }
           
    private int
    f1;
            [
    Obsolete
    ]
           
    private volatile int
    f2;
           
    public abstract int
    m<T>(T t)
             
    where T : struct
            {
               
    return
    1;
            }
           
    public string
    P
            {
               
    get
                {
                   
    int
    value = 0;
                   
    return "A"
    ;
                }
               
    set
    ;
            }
           
    public abstract string
    P
            {
               
    get
    ;
            }
           
    public abstract int this[int
    index]
            {
               
    get
    ;
               
    internal protected set
    ;
            }
           
    public event
    Event E;
           
    public static A operator
    +(A first, A second)
            {
               
    return
    first.Add(second);
            }
           
    fixed int
    field[10];
           
    class C
            {
            }
        }
       
    public interface I
        {
           
    void A(int
    value);
           
    string
    Value
            {
               
    get
    ;
               
    set
    ;
            }
        }
        [
    type: Flags
    ]
       
    public enum E
        {
            A,
            B = A,
            C = 2 + A,

    #if DEBUG
        D,
    #endif

        }
       
    public delegate void Delegate(object
    P);
       
    namespace
    Test
        {
           
    using
    System;
           
    using
    System.Collections;
           
    public class Список
            {
               
    public static IEnumerable Power(int number, int
    exponent)
                {
                    Список Список =
    new
    Список();
                    Список.Main();
                   
    int
    counter = 0;
                   
    int
    אתר = 0;
                   
    while
    (++counter++ < --exponent--)
                    {
                        result = result * number + +number+++++number;
                       
    yield return
    result;
                    }
                }
               
    static void
    Main()
                {
                   
    foreach (int i in
    Power(2, 8))
                    {
                       
    Console.Write("{0} "
    , i);
                    }
                }
            }
        }
    }

    namespace
    ConsoleApplication1
    {
       
    namespace
    RecursiveGenericBaseType
        {
           
    class A<T> : B<A<T>, A<T>> where
    T : A<T>
            {
               
    protected virtual
    A<T> M() { }
               
    protected abstract
    B<A<T>, A<T>> N() { }
               
    static
    B<A<T>, A<T>> O() { }
            }

           
    sealed class B
    <T1, T2> : A<B<T1, T2>>
            {
               
    protected override
    A<T> M() { }
               
    protected sealed override
    B<A<T>, A<T>> N() { }
               
    new static
    A<T> O() { }
            }
        }

       
    namespace
    Boo
        {
           
    public class Bar<T> where T : IComparable
            {
               
    public
    T f;
               
    public class Foo<U> : IEnumerable
    <T>
                {
                   
    public void
    Method<K, V>(K k, T t, U u)
                       
    where
    K : IList<V>, IList<T>, IList<U>
                       
    where
    V : IList<K>
                    {
                        A<
    int
    > a;
                        M(A<B, C>(5));
                    }
                };
            };
        };

       
    class Test
        {
           
    void
    Bar3()
            {
               
    var x = new Boo.Bar<int>.Foo<object
    >();
                x.Method<
    string, string>(" ", 5, new object
    ());

               
    var q = from i in new int
    [] { 1, 2, 3, 4 }
                       
    where
    i > 5
                       
    select
    i;
            }

           
    public static implicit operator Test(string
    s)
            {
               
    return new
    ConsoleApplication1.Test();
            }
           
    public static explicit operator Test(string
    s)
            {
               
    return new
    Test();
            }

           
    public int
    foo = 5;
           
    void
    Bar2()
            {
                foo = 6;
               
    this.Foo = 5.GetType(); Test t = "sss"
    ;
            }

           
    public event EventHandler MyEvent = delegate
    { };

           
    void
    Blah()
            {
               
    int
    i = 5;
               
    int
    ? j = 6;

                Expression<
    Func<int
    >> e = () => i;
                Expression<
    Func<bool, Action>> e2 = b => () => { return
    ; };
               
    Func<bool, bool> f = delegate (bool
    a)
                {
                   
    return
    !a;
                };
               
    Func<int, int, int
    > f2 = (a, b) => 0;
                f2 = (
    int a, int
    b) => 1;
               
    Action
    a = Blah;
                f2 = () => {};
                f2 = () => {;};
            }

           
    delegate
    Recursive Recursive(Recursive r);
           
    delegate
    Recursive Recursive<A,R>(Recursive<A,R> r);

           
    public Type
    Foo
            {
                [
    Obsolete("Name", error = false
    )]
               
    get
                {
                   
    var result = typeof(IEnumerable<int
    >);
                   
    var t = typeof(int?) == typeof(Nullable<int
    >);
                    t =
    typeof(IEnumerable<int
    ?[][][]>);
                   
    return typeof(IEnumerable
    <>);
                }
               
    set
                {
                   
    var t = typeof(System.Int32
    );
                    t.ToString();
                    t =
    value
    ;
                }
            }

           
    public void
    Constants()
            {
               
    int
    i = 1 + 2 + 3 + 5;
               
    global::System.String s = "a" + (System.String)"a" + "a" + "a" + "a" + "A"
    ;
            }

           
    public void
    ConstructedType()
            {
               
    List<int> i = null
    ;
               
    int
    c = i.Count;
            }
        }
    }

    namespace
    Comments.XmlComments.UndocumentedKeywords
    {
       
    /// <summary>
        /// Whatever
        /// </summary>
        /// <!-- c -->
        /// <![CDATA[c]]> //
        /// <c></c> /* */
        /// <code></code>
        /// <example></example>
        /// <exception cref="bla"></exception>
        /// <include file='' path='[@name=""]'/>
        /// <permission cref=" "></permission>
        /// <remarks></remarks>
        /// <see cref=""/>
        /// <seealso cref=" "/>
        /// <value></value>
        /// <typeparam name="T"></typeparam>
        class /*///*/C
    <T>
        {
           
    void
    M<U>(T t, U u)
            {
               
    // comment
                /* *** / */
               
    /* //
                 */

                /*s*///comment
                // /***/
                /*s*/int /*s*/
    intValue = 0;
                intValue = intValue
    /*s*/
    + 1;
               
    string strValue = /*s*/"hello"
    ;
               
    /*s*/MyClass c = new
    MyClass();
               
    string verbatimStr = /*s*/@"\\\\"
    ;
            }
        }

       
    //General Test F. Type a very long class name, verify colorization happens correctly only upto the correct size (118324)
        class TestClassXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/*Scen8*/
    { }

       
    class TestClassXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX22/*Scen9*/
    { }

       
    class yield
        {
           
    void Foo<U>(__arglist
    )
            {
                C<U> c =
    null
    ;
                c.M<
    int>(5, default
    (U));
               
    TypedReference tr = __makeref
    (c);
               
    Type t = __reftype
    (tr);
               
    int j = __refvalue(tr, int
    );
                Params(a: t, b: t);
                Params(
    ref c, out
    c);
            }
           
    void Params(ref dynamic a, out dynamic b, params dynamic
    [] c) {}
           
    void Params(out dynamic a = 2, ref dynamic c = default(dynamic), params dynamic
    [][] c) {}

           
    public override string ToString() { return base
    .ToString(); }

           
    public partial void
    OnError();

           
    public partial void
    method()
            {
               
    int?[] a = new int?[5];/*[] bug*/ // YES []
                int[] var = { 1, 2, 3, 4, 5 };/*,;*/
                int i = a[i];/*[]*/
                Foo<T> f = new Foo<int>();/*<> ()*/
                f.method();/*().*/
                i = i + i - i * i / i % i & i | i ^ i;/*+ - * / % & | ^*/
                bool b = true & false | true ^ false;/*& | ^*/
                b = !b;/*!*/
                i = ~i;/*~i*/
                b = i < i && i > i;/*< && >*/
                int? ii = 5;/*? bug*/ // NO ?
                int f = true ? 1 : 0;/*? :*/   // YES :
                i++;/*++*/
                i--;/*--*/
                b = true && false || true;/*&& ||*/
                i << 5;/*<<*/
                i >> 5;/*>>*/
                b = i == i && i != i && i <= i && i >= i;/*= == && != <= >=*/
                i += 5.0;/*+=*/
                i -= i;/*-=*/
                i *= i;/**=*/
                i /= i;/*/=*/
                i %= i;/*%=*/
                i &= i;/*&=*/
                i |= i;/*|=*/
                i ^= i;/*^=*/
                i <<= i;/*<<=*/
                i >>= i;/*>>=*/
                object s = x => x + 1;/*=>*/
                Point point;
               
    unsafe
                {
                    Point* p = &point;
    /** &*/
                    p->x = 10;/*->*/
                }
                IO::BinaryReader br =
    null
    ;
            }

           
    struct Point { public int X; public int Y; public void ThisAccess() { this = this; } }
        }
    }
  • Kirill Osenkov

    Multiple variables in a using statement

    • 5 Comments

    Here’s a simple file copy program:

    using System;
    using
    System.IO;

    public class FileCopy
    {
       
    private static void Main(string
    [] args)
        {
           
    if
    (args.Length != 2)
            {
               
    Console.WriteLine("Usage: filecopy <source> <destination>"
    );
               
    return
    ;
            }

            Copy(args[0], args[1]);
        }

       
    private static void Copy(string source, string
    destination)
        {
           
    const int
    BufferSize = 64 * 1024;
           
    using (FileStream input = File.OpenRead(source), output = File
    .OpenWrite(destination))
            {
               
    var buffer = new byte
    [BufferSize];
               
    int
    bytesRead;
               
    while ((bytesRead = input.Read(buffer, 0, BufferSize)) != 0)
                {
                    output.Write(buffer, 0, bytesRead);
                }
            }
        }
    }

    I’ve only recently learned that you can use multiple local variable declarators in the using statement, separated by comma, as long as they are of the same type. In the spec, section 8.13 (The using Statement), it says:

    using-statement:

    using ( resource-acquisition ) embedded-statement

    resource-acquisition:

    local-variable-declaration

    expression

    A using statement of the form

    using (ResourceType r1 = e1, r2 = e2, …, rN = eN) statement

    is precisely equivalent to a sequence of nested using statements:

    using (ResourceType r1 = e1)

    using (ResourceType r2 = e2)

    using (ResourceType rN = eN)

    statement

    So we could rewrite our Copy method as follows:

        private static void Copy(string source, string destination)
        {
           
    const int
    BufferSize = 64 * 1024;
           
    using (FileStream input = File
    .OpenRead(source))
           
    using (FileStream output = File
    .OpenWrite(destination))
            {
               
    var buffer = new byte
    [BufferSize];
               
    int
    bytesRead;
               
    while ((bytesRead = input.Read(buffer, 0, BufferSize)) != 0)
                {
                    output.Write(buffer, 0, bytesRead);
                }
            }
        }

    Note however that due to how local-variable-declaration is defined in the language spec, multiple variables have to be of the same type, and you only specify this type once at the beginning of the first declarator.

  • Kirill Osenkov

    Free online function graphing with Silverlight

    • 7 Comments

    I see Jon Skeet has written a function graphing sample using DLR and Silverlight. It occurred to me that it would be very easy to create something like this using my Live Geometry framework.

    So here it is: http://graph.livegeometry.com. One difference is that I didn’t use DLR and Python, but wrote my own hand-written recursive descent parser for math expressions. One reason for this (except the fact that it was overdue for me to write a parser myself) is that I don’t think DLR will run on the Windows Phone 7 (since Expression.Compile() and Reflection.Emit are currently not supported on the phone). Also DLR is a bit on the heavy-side with > 1 MB increase of the .xap file.

    Sources, as usual, at CodePlex.

  • Kirill Osenkov

    What’s faster: string.Equals or string.Compare?

    • 20 Comments

    I just realized I was so busy lately that I haven’t blogged for a while!

    Here’s a quiz that left me clueless for some time (courtesy of our C# MVP Ahmed Ilyas):

    using System;
    using System.Diagnostics;

    public class Examples
    {
        public static void Main()
        {
            string stringToTest = "Hello";

            Stopwatch equalsTimer = new Stopwatch();
            equalsTimer.Start();
            stringToTest.Equals("hello", StringComparison.OrdinalIgnoreCase);
            equalsTimer.Stop();
            Console.WriteLine("Equals Timer: {0}", equalsTimer.Elapsed);

            Stopwatch compareTimer = new Stopwatch();
            compareTimer.Start();
            String.Compare(stringToTest, "hello", StringComparison.OrdinalIgnoreCase);
            compareTimer.Stop();
            Console.WriteLine("Compare Timer: {0}", compareTimer.Elapsed);
        }
    }

    On my machine, this prints out:

    Equals Timer: 00:00:00.0009247
    Compare Timer: 00:00:00.0000012

    We looked at the source code of string.Equals and string.Compare and it was essentially the same (modulo very minor details which shouldn’t cause issues).

    So what’s wrong? Why would the first call be 770 times slower than the second one? Jitting? No. Cache hit/miss? No.

    After a while, we figured it out [UPDATE: So I thought!]. The first method is a virtual instance method, so a callvirt is emitted by the compiler:

    callvirt instance bool [mscorlib]System.String::Equals(string, valuetype [mscorlib]System.StringComparison)

    While the second method is a static one, so the call instruction is used instead:

    call int32 [mscorlib]System.String::Compare(string, string, valuetype [mscorlib]System.StringComparison)

    In this case, the method body was insignificant compared to the costs of doing virtual dispatch vs. a direct call. If you’d measure this in a loop of 1000000, the results will average out. So will they average out if you compare long strings, when the method body execution time dwarfs the call costs.

    UPDATE: As always, Kirill jumps to conclusions too fast. Ahmed pointed out that if you swap the order of the calls, then the results are way different again! So it’s not the callvirt cost. Still puzzled, maybe it IS the JITter compiling the BCL code for the two method bodies.

    Interesting...

  • Kirill Osenkov

    HTML Copy extension from Pro Power Tools not working with Live Writer?

    • 1 Comments

    Dear readers,

    I've just returned from a nice vacation only to find a couple of reports that my HTML Copy extension for VS 2010 doesn't work on some users machines. Among the affected users is our corporate vice president of Visual Studio, Jason Zander, who is an avid technology adopter. Jason was playing with Pro Power Tools and found that after pressing Ctrl+C in VS 2010, Live Writer doesn't display the option to preserve HTML format in their Paste Special dialog:

    image

    I cannot reproduce this on my machines. If anyone experiences this issue and would like to help investigate this issue, I would appreciate if you could reach out so I can investigate and debug. We might have to use remote debugging and remote assistance.

    On the plus side, I've just fixed another bug reported by a user from China (article below in Chinese):

    http://www.cnblogs.com/nicch/archive/2010/06/13/vs2010_powertools_copyashtml_fix.html

    The bug was that the clipboard expects the HTML format be in UTF8 encoding, and the HTML fragment length specified in the HTML header needs to be in bytes, not char count:

    http://msdn.microsoft.com/en-us/library/aa767917(VS.85).aspx

    This resulted in copied fragments to be trimmed if they contained multibyte chars such as japanese or chinese characters. Here's the Connect bug about it that I fixed:

    https://connect.microsoft.com/VisualStudioJapan/feedback/details/576886/productivity-power-tools-html

    Many thanks to those who have reported it! You will see the fix in the next update of the Pro Power Tools.

    Thanks!

  • Kirill Osenkov

    WPF SendKeys or mocking the keyboard in WPF

    • 2 Comments

    This post will only be interesting for the few of those who test WPF UI in-process (i.e. not through out-of-process UI automation frameworks such as White). When using in-process testing, the test lives in the same AppDomain as the code under test and has direct access to all the APIs such as UIElement.RaiseEvent.

    With out-of-process testing, the test lives in a separate process from the application under test. In this case, the test sends the application automation requests (typically using the MSAA or the newer UI Automation library). These requests eventually end up going through the operating system's window messages. The downside of this approach is that since it almost fully emulates the user behavior, the tests are fragile because a sudden Windows Update dialog popup or a random message box from another application can steal the focus from the test application and confuse the test. That's why in-process tests are generally considered more reliable, since they will work even if the application is not focused or even not visible (in case of unit-test).

    Those who have written tests using WinForms before are familiar with the helpful SendKeys class in System.Windows.Forms. It works by going through the operating system's SendInput function and provides good approximation of how the actual user's input would be routed through the system. SendKeys can be used for both in-process and out-of-process testing.

    Another thing that WinForms has is the RaiseKeyEvent methods on Control with KeyEventArgs that easily allow you to mock keyboard events in-process, at the unit-testing level.

    WPF does not provide any alternative to the SendKeys class. It does provide a RaiseEvent method, however the KeyEventArgs class in WPF was explicitly designed in such a way to prevent mocking the modifier keys state. We can see that many people are looking to call RaiseEvent from their tests and provide mock key and modifiers, however it seems that no solution is currently available. See for example this StackOverflow question: http://stackoverflow.com/questions/1263006/wpf-send-keys-redux The official guidance from the WPF team is to go through the operating system and either add a reference to System.Windows.Forms.dll to use SendKeys or directly use the SendInput API to mock the keyboard.

    I've created a little project that works around this limitation and allows you to call RaiseEvent on your WPF controls from your unit-tests and fully mock the modifier key states (Ctrl, Alt, Shift). It implements the SendKeys DSL – a little mini-language to encode keystrokes. It does some very dirty reflection magic to workaround WPF's protection against mocking modifier key states, however it works and might be useful to some people. Warning: it is NOT a replacement for the WinForms SendKeys, it's a completely different thing.

    While it is not recommended for unit tests, it can do a decent job for integration tests, when you actually show your application's UI. Chances that you need this library are very low, but if you happen to need it, then it's probably handy.

    The source is at http://wpfsendkeys.codeplex.com

  • Kirill Osenkov

    Layout Designer prototype is now open-source on CodePlex

    • 0 Comments

    A while back I’ve published a preview of my WPF/Silverlight Layout Designer prototype in this blog post. If you had Silverlight 4 on your machine, you could preview it live from http://layout.osenkov.com.

    Many folks have asked for the source since then. I’m happy to announce that I’ve open sourced the project on CodePlex: http://layout.codeplex.com. I don't think I will have time to evolve it any further, because it already nicely demonstrates the concept and the idea that I wanted to convey. I’ll be happy if you find the techniques/source code useful – feel free to reuse any of it in your projects.

    As always with my hobby projects, there are no comments, no unit-tests, it doesn’t pass FxCop/StyleCop and comes with the usual caveat “AS IS”/”Written on a long weekend”. Please enjoy responsibly!

  • Kirill Osenkov

    EasyPainter and other WPF/Silverlight goodies from http://nokola.com

    • 1 Comments

    My fellow tester from the Visual Studio XAML Designer team has a very rich and interesting website: http://www.nokola.com

    One of his hobby projects is EasyPainter – an effect-oriented paint application in Silverlight: http://www.nokola.com/easypainter

    Also definitely check out his blog, he has a lot of interesting things: http://nokola.com/blog

    Enjoy!

  • Kirill Osenkov

    Jon Skeet’s C# In Depth, 2nd Edition

    • 1 Comments

    Jon has done it again :) Now with great new chapters on Dynamic, Code Contracts and more: http://manning.com/skeet2/

    C# In Depth was a great book to gain deep understanding of the C# language (up to version 3.0) and how to effectively use its features. The second edition is more complete with full coverage of C# 4.0 and new additions to the .NET Framework (Code Contracts). Code Contracts isn’t strictly a language feature but it’s definitely a great tool in any C# programmer’s toolset and as always, Jon covers it exceptionally well.

    The Second Edition is now available for pre-order. If you’re in the .NET online community, chances are that you’ll hear about the book when it gets released. I really recommend it.

  • Kirill Osenkov

    Notes from the Orlando User Group meeting

    • 3 Comments

    Last night we met with the Orlando .NET User Group. I had a blast! Esteban Garcia, Will Strohl and others did a great job organizing everything (thanks guys!). Very nice folks, great audience, and of course, we just loved Florida!

    Slides from my talk can be downloaded here.

    UPDATE: fixed the link, sorry about that.

    UPDATE 2: it seems that I can't get the MIME types right on my hosting provider. No time to figure it out now, have to put out a .zip file, sorry. Please unzip it to get to the PowerPoint.

    Florida first impressions:

    1. OMG I love it here! Palm trees, great weather, great architecture, great people.
    2. People live in paradise, vacation every day.
    3. (Especially if you like sauna)
    4. It rains every day, and this is a good thing (water evaporates because of the heat).
    5. I wish we had more time here.
  • Kirill Osenkov

    Quick update on the layout designer

    • 0 Comments

    Thanks everyone who commented on my previous post about the layout designer prototype. Hopefully I'll be able to put out the source code in the upcoming weeks. Watch this blog for announcements.

    I've been showing http://layout.osenkov.com to people and the feedback is generally positive. Although it's just a concept prototype and is nowhere near close a working XAML designer, it shows off a couple of ideas that I wanted to illustrate.

    Nikhil Kothari pointed me to his Silverlight Layout Panels project, which explores similar ideas. He has also found that the standard layout panels are missing certain details such as Spacing between children. Very nice ideas!

    Also I was blown away when Dustin Campbell has shown me the DevExpress demos:

    http://demos.devexpress.com/AgLayoutControlDemos/

  • Kirill Osenkov

    Copy Code in HTML format with Visual Studio 2010

    • 23 Comments

    Today Jason has announced the Visual Studio 2010 Productivity Power Tools – a set of VS 2010 extensions that we released to complement and enhance the built-in 2010 features. You can either install the Pro Power Tools from here or just go to the Tools –> Extension Manager and type "Pro Power Tools" in the search box:

    image

    For the Pro Power Tools, I wrote a feature to copy formatted source code to clipboard in HTML format. The traditional VS editor only copies the plain text and RTF formats to clipboard, and there are numerous tools available to convert RTF to HTML. With the Pro Power Tools installed, pressing Ctrl+C or otherwise copying the code editor selection to clipboard, it will place the formatted and colorized HTML fragment on clipboard, alongsize the plain text and RTF format.

    Then you can paste the code anywhere HTML is supported, such as Windows Live Writer:

    image

    Ctrl+Shift+V (Paste Special), Alt+K (Keep Formatting) and Enter to insert the colorized code to Live Writer.

    In a future version of the power tools I will introduce customization – you will be able to fully control what HTML gets generated:

    1. Prepend any HTML to the code fragment
    2. Append any HTML to the code fragment
    3. Prepend any HTML before every line of code
    4. Append any HTML after every line of code
    5. Include line numbers and the format string for them
    6. Replace the space with &nbsp;
    7. Replace the carriage return line feed with <br />
    8. Emit <span style="color: blue">void</span> vs. <span class="keyword">void</span>

    Also, the current version has a bug: Cut (Ctrl+X) doesn't place formatted HTML to clipboard, only Copy does. I forgot to hook up the Edit.Cut command and never got around to fixing it. I'll fix it for the next release though.

    Hope you like it, and as always, your feedback is appreciated!

    P.S. Here's the sample code formatted using the extension:

            private static string IntersperseLineBreaks(string text)
            {
                text = text.Replace("\n\r", "\n \r");
                return text;
            }
    You can View Source on this page, look for IntersperseLineBreaks and view the HTML that I generate. In a future release you will be able to customize the output of the tool, but for now this is what it defaults to.
  • Kirill Osenkov

    A prototype WPF/Silverlight layout designer

    • 14 Comments

    I’ve been thinking recently about how would I write a WPF UI designer that would specifically highlight the new WPF layout paradigm, and not try to mimic the old WinForms paradigm. The old VB6/WinForms designer was built around absolute positioning. It allowed for rapid WYSIWYG prototyping of interfaces, and the Dock/Anchor functionality provided a relatively cheap and easy support for scalable UI. The new WPF designer in Visual Studio is although very powerful, but some people find it difficult to quickly draft a scalable UI that produces clean XAML.

    So I wrote a concept prototype of how I would like to design WPF UI:

    http://layout.osenkov.com

    It runs right in the browser and requires Silverlight 4 (because it needs to copy the output XAML to clipboard). It only focuses on the basics and doesn’t have a lot of features (it’s just a prototype), but I think it can nicely convey my ideas. Nothing of it is new, and both Blend and VS designers support complex layouts with panels and such, but I still decided to write a simple designer without a lot of complex details.

    Let me know what you think!

    image

  • Kirill Osenkov

    Windows User Interface Guidelines

    • 4 Comments

    Have you ever designed a dialog and wondered what’s the right control size, spacing, font, layout etc? This respectable document (46 MB!) contains a wealth of such information:

    http://download.microsoft.com/download/e/1/9/e191fd8c-bce8-4dba-a9d5-2d4e3f3ec1d3/ux%20guide.pdf

    For example, did you know that the default size of a button (like OK and Cancel) needs to 73x21 pixels? Or that the vertical spacing between a label and a control needs to be 5 pixels? Here’s an excerpt from the document:

    image
Page 2 of 7 (154 items) 12345»