NuGet restore

NuGet is a package manager like NPM for node.js or Gem for Ruby, and it is a dominant one in .NET.

You can handle dependency packages in two ways. You download them from NuGet server but also store them in your source control. Or, you just remember what packages you use in your project, and restore them on build. Node and Ruby guys always go for the 2nd option. .NET people used to do the first one, but now prefer the 2nd option. I agree to the 2nd option, restoring packages on build, rather than storing them in git repository. Git is for source code, NuGet repository is for packages.

The Visual Studio on my work machine isn’t set up for NuGet restore. “Restore” option is disabled, and when I download and build an open-source project, it can’t restore the packages and can’t build the solution.

I’ve checked if there’s work-around. It seems that the latest NuGet.exe can restore packages in command-line, regardless of your VS settings, which makes sense to me, as NuGet shouldn’t depend on the settings of your IDE. So update NuGet.exe to the latest.

exec { .\Tools\NuGet\NuGet.exe update -self }

Create an environmental variable, EnableNuGetPackageRestore, to true, but just for Process, not for Machine, not to impact other projects.

[Environment]::SetEnvironmentVariable("EnableNuGetPackageRestore", "true", "Process")

Then, you can safely restore your packages in command-line.

exec { .\Tools\NuGet\NuGet.exe restore ".\Src\$name.sln" | Out-Default } "Error restoring $name"

So, all the code in one place

Write-Host "Restoring"
[Environment]::SetEnvironmentVariable("EnableNuGetPackageRestore", "true", "Process")
exec { .\Tools\NuGet\NuGet.exe update -self }
exec { .\Tools\NuGet\NuGet.exe restore ".\Src\$name.sln" | Out-Default } "Error restoring $name"
NuGet restore

Posh Git shows the current branch and the state of files in powershell prompt

It’s a set of PowerShell scripts that gives Git integration in PowerShell prompt.

https://github.com/dahlbyk/posh-git

The first thing you notice once you install it, is that it can show the current branch and the state of files, additions, modifications, and deletions within.

Another nice feature is tab completion.

For example,

git ch<tab> --> git checkout

You can install it via PsGet

Install-Module posh-git
Posh Git shows the current branch and the state of files in powershell prompt

Node.js의 힘, npm

Node.js, 이제는 모르는 사람이 없는 서버쪽 자바 스크립트 프로그래밍 언어 및 환경.

작년부터 Node.js를 개인 프로젝트에 조금씩 써보다가 이제는 거기에 꽂혀서 모든 개인 프로젝트를 Node.js로 하고 있다. 그런데 계속 쓰다보니, 이 npm이란 놈이 여간 기특하지 않은거다. Node Package Manager, 말 그대로 Node 관련 모든 패키지들이 모인 곳인데, 그야말로 무궁무진한 패키지들이 있다. 전에 Ruby 개발자들과 만나서 얘기할 때, 그 친구들이 농담식으로 “코드짜다는 일의 대부분이 패키지를 찾아서 설치하고 그걸 이용하는 것” 이라고 말하는 걸 들었는데, Node를 쓰면서 정말 실감이 난다. 웹 프로그래밍을 하려면 Express.js를 찾아 설치하고, 각종 미들웨어들을 설치한다. 로깅이 필요하면, bunyan이나 winston을 설치하고, azure-table storage를 설치해서 데이터를 저장하고 (회사 MSDN 계정에서 매달 Azure를 공짜로 쓸 수 있는 금액을 충전해줘서) 등등.

그런데 계속해서 npm에서 이것 저것 찾아서 쓰다보니, 점점 내가 만드느 코드들도 패키지 비슷하게 되어간다. C#에서는 그냥 Helper나 Util 등의 폴더에 넣어 쓰고말 코드를 패키지처럼 만들게 되고, 또 만들다 보면, 이걸 npm에 올려 공유하고 싶어진다. 함수가 어느정도 복잡해지면, 이제 이를 패키지로 만들고 싶어진다. 패키지가 일반적인 추상화 (Abstraction)의 패턴이 된다. 이는 C#으로 코딩할 때는 깨닫지 못하던 패턴이다.

RubyGems와 Ruby가 한 몸 이듯이 npm이 없다면 Node.js 역시 없다는 생각이 든다

Node.js의 힘, npm

The rising tide of shipping glitter bombs

It seems that people are suddenly mad with the sweet revenge of bombing people with glitter. Shipping enemies glitter is becoming world-wide phenomenon. This is the list of web sites that sell glitter, promising to bomb the buyer’s enemy.

The original stunt: http://www.shipyourenemiesglitter.com/

And a whole new industry appeared.

The rising tide of shipping glitter bombs

Sacrifice is noble, but what if the cause is not clear?

I saw American Sniper last week. Undoubtedly, it’s a great film to watch and it was heroic for Kyle to guard his fellow soldiers against the attack from the “savages”, yet the film is so dishonest of the history. Kyle sacrificed his life and family for the country, but unfortunately it turned out Iraq wasn’t responsible for 9/11 or any WMD.

american-sniper

from http://www.vox.com/2015/1/22/7859791/american-sniper-iraq

Sacrifice is noble, but what if the cause is not clear?

birdman and becoming polyglot

Birdman is an American black comdy that features a faded Hollywood actor famous for his superhero role. While seeing the film, I kind of thought I have something in common with the character. He doesn’t wanted to be labelled as Hollywood superhero junkie, but to be seen as an artist, a Broadway actor.

I like the word, “polyglot programming”. I’m fascinated by people who code in different language on cross-platforms. Though I mostly use C# and .NET framework on windows at work. I strive to be polyglot. Also I want to be seen as a polyglot developer, capable of using multiple sets of language. On my linkedin profile, I proudly wrote that I’ve got skills of F#, javascript (includindg Node.js), Python, and Ruby. I consciously spend time to learn those languages. For my side projects, I use Node.js, express, and angular. I wrote a couple of simple android apps in Java. I spent quite bit of time learning ruby, went through Ruby Koans twice, and did one project in ruby and rails.

However, I often did so, because I loved the glorious title of “polyglot programmer.” I had hope that one day I will be like a magician with spinning dishes on poles, using different languages and platforms skilfully.

At the end of the film, the actor finally accepts that he is a Birdman. Accepting the identity frees him. Working hard to be polyglot for the sake of its glory was tiring, I confess. It’s like you get exhausted if you try to be cool or impressive all the time. Like the birdman, I need to accept that I might not be polyglot, if being polyglot has minimum requirements, like you have to know at least 4 different major languages on different platforms. If the word, “polyglot”, enslaves you, I must fell. I don’t have to cool or awesome. I just want to be a programmer, who is good at what he’s doing. I don’t have to a guru. I’m happy to be a journeyman

A good developer would eventually be polyglot. You need a right tool for the job, and if you know more tools, and then you can do the job much better more effectively, For example,

“Using Java to solve a clearly functional problem, when Clojure would be simpler. Or building a Rails app when your users want the kind of fluid interface a single page JavaScript framework can give them.”(http://thoughtworks.github.io/p2/issue08/hire-polyglot/)

So, to be polyglot for the sake of being polyglot doesn’t give you much benefit. It may make you rather arrogant. Just try to know different languages, tools, and environments enough that you can decide which would be the best tool for the job you have now. Use the language and tool for job and deepen your understanding and knowledge along. Don’t be afraid of using different toolsets. Then along the journey, at some point, you will find you have become truly polyglot.

Being polyglot can’t be the purpose. It’s the end result you become, when you try to be good at your job.

birdman and becoming polyglot

Opening an office document from Code

It’s a simple job at a glance, and it should be. But we had a bug with that feature. You open a document on Huddle and it should be opened in an application that is associated with the file, for example, MS Word, if it is word document. You can do that if you have installed Huddle for Windows, which is a desktop application for Huddle.

It worked. Yet, customers often complained that the document opened in the background. When we open any document, it opens in the foreground on dev machine. so you are very tempted to say “it works on my machine!”

This is the code that opens the document. No magic, just simple process.Start()

var process = new Process
{
    StartInfo =
    {
        FileName = path,
        CreateNoWindow = true,
        UseShellExecute = true,
        LoadUserProfile = false,
        ErrorDialog = false,
        Verb = &amp;quot;open&amp;quot;
    },
    EnableRaisingEvents = true
};

process.Start();

The application that’s launched is supposed to be active in the foreground, and I’ve got that behaviour on my dev machine. Yet on non-dev machines, especially our product manager’s laptop, the document opened consistently in the background, especially behind Chrome browser when it was maximised.

So, we made a win api call to set it in the foreground.


[DllImport(&amp;quot;User32.dll&amp;quot;)]
private static extern Int32 SetForegroundWindow(IntPtr hWnd);

...
var handle = process.MainWindowHandle
SetForegroundWindow(handle);

Now it was working on one of my VMs (Virtual Machines) and I thought it should be working. However it was still failing on a laptop.
Why? A little more investigation reveals that process.MainWindowHandle doesn’t return the handle immediately. When MS Word splash screen pops up, the process to MS Word exists, but the main window is not fully loaded yet, so the handle was IntPtr.Zero. You have to wait until MainWindowHandle is populated, and it takes 3 to 6 seconds and up to 10 seconds, if you open Word first time on the day.

So, the last missing bit was waiting for the handle.

int threshold = 0;
while (process.MainWindowHandle == IntPtr.Zero)
{
    if (threshold &amp;gt; 100) break; 

    _log.DebugFormat(&amp;quot;Waiting for the document is fully loaded... - {0}&amp;quot;, threshold);
    Thread.Sleep(TimeSpan.FromMilliseconds(100));
    threshold++;
}

_log.DebugFormat(&amp;quot;Bringing the application (handle: {0}) to the front&amp;quot;, process.MainWindowHandle);
SetForegroundWindow(handle);

And happy developers and customers, finally

Update as of Fri.19/12/2014

The journey didn’t end there unfortunately. The issue was deeper than I previously assumed.

Opening documents in the background had a mixture of causes.

  1. If there’s any Excel document, Excel opens all subsequent documents are in the same instance, just flashing the icon since Windows 7
  2. Event SetForegroundWindow doesn’t work, if the process that’s running the command is not in the foreground. So you have to set your process foreground first, if you want to set any other process you spawn foreground.

To sort them out, I took a different approach. First, I gave up the simple and elegant Process.Start() with UseShellExecute option. Instead, I query windows registry and find the associated application with the file extension.

[Flags]
public enum AssocF : uint
{
    None = 0,
    Init_NoRemapCLSID = 0x1,
    Init_ByExeName = 0x2,
    Open_ByExeName = 0x2,
    Init_DefaultToStar = 0x4,
    Init_DefaultToFolder = 0x8,
    NoUserSettings = 0x10,
    NoTruncate = 0x20,
    Verify = 0x40,
    RemapRunDll = 0x80,
    NoFixUps = 0x100,
    IgnoreBaseClass = 0x200,
    Init_IgnoreUnknown = 0x400,
    Init_FixedProgId = 0x800,
    IsProtocol = 0x1000,
    InitForFile = 0x2000,
}

public enum AssocStr
{
    Command = 1,
    Executable,
    FriendlyDocName,
    FriendlyAppName,
    NoOpen,
    ShellNewValue,
    DDECommand,
    DDEIfExec,
    DDEApplication,
    DDETopic,
    InfoTip,
    QuickTip,
    TileInfo,
    ContentType,
    DefaultIcon,
    ShellExtension,
    DropTarget,
    DelegateExecute,
    SupportedUriProtocols,
    Max,
}

// from http://www.pinvoke.net/default.aspx/shlwapi/AssocQueryString.html
[DllImport(&quot;Shlwapi.dll&quot;, CharSet = CharSet.Unicode)]
static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, ref uint pcchOut);

public string GetApplicationPath(string extension)
{
    const int S_OK = 0;
    const int S_FALSE = 1;

    uint length = 0;
    uint ret = AssocQueryString(AssocF.None, AssocStr.Executable, extension, null, null, 
         ref length);
    if (ret != S_FALSE)
    {
        throw new InvalidOperationException(&quot;Could not determine associated string&quot;);
    }

    var sb = new StringBuilder((int)length); 
    ret = AssocQueryString(AssocF.None, AssocStr.Executable, extension, null, 
          sb, ref length);
    if (ret != S_OK)
    {
        throw new InvalidOperationException(&quot;Could not determine associated string&quot;);
    }

    return sb.ToString();
}

You get the application and run it with Process.Start. You pass the file name as argument. In case of office documents, you can add “/x” switch, so that it creates a new instance all the time, not reusing the existing one.

var extension = Path.GetExtension(path);
try
{
    string application = _windowManager.GetApplicationPath(extension);
    var process = new Process
    {
        StartInfo =
        {
            FileName = application,
            Arguments = GetArguments(application, path),
            WindowStyle = ProcessWindowStyle.Normal
        }
    };

    _log.Debug(string.Format(&quot;Starting {0}&quot;, path));

    var huddleWinHandle = Process.GetCurrentProcess().MainWindowHandle;
    _windowManager.MinimiseWindow(huddleWinHandle);
    _windowManager.BringToFront(huddleWinHandle);
    process.Start();
}
...

private string GetArguments(string application, string path)
{
    if (application.ToLower().Contains(&quot;microsoft&quot;))
    {
        return &quot;/x \&quot;&quot; + path + &quot;\&quot;&quot;;
    }

    return &quot;\&quot;&quot; + path + &quot;\&quot;&quot;;
}

Why do you minimise the window of the current process before setting it foreground? For some reason, SetForegroundWindow didn’t work consistently, if you process main window is in normal mode, hidden behind other windows. When it was minimised programatically and set to foreground, it was always brought to the front.

So, to summarise how to open documents in the foreground,

  1. Set your application to the foreground first by minimising the window and then bringing it to the front
  2. Find the associated application with the file and start it as new instance.
  3. Before you start another process, make sure your process in the foreground first. Only foreground process can make an attached process run in the foreground. There are more rules in setting a process in the foreground.
Opening an office document from Code