The rising tide of shipping glitter bombs

Posted on Updated on

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.

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

Posted on Updated on

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

birdman and becoming polyglot

Posted on Updated on

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.

Opening an office document from Code

Posted on Updated on

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 = "open"
    },
    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("User32.dll")]
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 > 100) break; 

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

_log.DebugFormat("Bringing the application (handle: {0}) to the front", 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("Shlwapi.dll", 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("Could not determine associated string");
    }

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

    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("Starting {0}", 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("microsoft"))
    {
        return "/x \"" + path + "\"";
    }

    return "\"" + path + "\"";
}

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.

SRP (Single Responsibility) and encapsulation

Posted on Updated on

Single Responsibility is one of key principles in writing good code, I believe. So when you change a method or a class, you should have only one reason to change it. But at the same time, you don’t want to reveal too much details. You want to encapsulate the internals and nicely abstract your business logic.

This morning, I had a brief chat with a colleague about method encapsulation. I was saying the method was hiding too much and he called it encapsulation. This kind of chat happens often among developers. We didn’t come to conclusion and I thought about it afterward. This is my thought.

A method should do only one thing

For example,

  • contentStore.remove(doc)
  • metaDataStore.remove(doc)
  • raise(new UiDocumentDeletedEvent(doc))

The 3 lines of code are written separately and each call does only one thing. In my opinion, contentStore.remove() method shouldn’t hide the following two call inside its method call. contentStore.remove() should do only one thing it’s good at, which is removing the document from ContentStore.

Encapsulation

However, what if the 3 operations happen together very often. if it does, I think it’s the time to introduce a facade object (facade pattern) or a command and command handler. The command handler can have those 3 objects as dependencies and call them in sequence.

public class DocumentRemovedCommandHandler : IHandle<DocumentRemovedCommand> 
{
    ...
    public void Handle(DocumentRemovedCommand command)
    {
        _contentStore.remove(doc);
        _metaDataStore.remove(doc);
        _event.raise(new UiDocumentDeletedEvent(doc));
    }
}

So, in conclusion, use facade or command, if you want to perform a group of operations. Otherwise, do one thing at a time, well.

요즘 근황 (2014. 11월)

Posted on

며칠전에 Skype 채용 담당자로부터 메일이 왔다. Skype Web App 팀에서 사람을 구하고 있다고. 지금 회사인 Huddle도 마음에 들지만, 양파님의 블로그 글을 읽다보니 웬지 Skype에 가볼까 하는 생각도 생긴다. 근데 웬지 마소는 좀 지는 해 같아서. 이번에 구조 조정도 엄청하던데, 괜히 갔다가 피보는 것 아닐까 싶기도.

최근 Desktop 팀으로 옮겼다. 전에 있던 팀은 로그인 인증 (Authentication)과 Pipe and Filter를 이용한 파이프라인 시스템 관련하여 주로 작업하는 팀이었는데, 별다른 이유는 없고, 그냥 Desktop 개발을 한 번 해보고 싶었다. Windows와 Mac, Cross platform 개발을 하는 팀인데, C#, Mono, Webkit, javascript, CEX 등을 쓴다. 안 하던걸 하니 좀 재밌기도 하고, 새로운 사람들과 일하다 보니, 같은 회사인데도 상당히 다른 느낌이 들고 그래서 좋은 것 같다.

A simple script that cleans and builds visual studio solution with psake

Posted on

psake is a simple build automation tool written in powershell, and works well on Microsoft platform.

This is a really simple example that cleans bin folder, run msbuild to build the solution, and clean up pdb and xml files afterward.


properties {
    $BuildConfiguration = if ($BuildConfiguration -eq $null ) { "debug" } else {     
        $BuildConfiguration }
    $BuildScriptsPath = Resolve-Path .
    $base_dir = Resolve-Path ..
    $packages = "$base_dir\packages"
    $build_dir = "$base_dir\Sushiwa\bin"
    $sln_file = "$base_dir\Sushiwa.sln"
}

task default -depends CleanUp, Compile

task CleanUp {
    @($build_dir) | aWhere-Object { Test-Path $_ } | ForEach-Object {
    Write-Host "Cleaning folder $_..."
    Remove-Item $_ -Recurse -Force -ErrorAction Stop
    }
}

task Compile {
    Write-Host "Compiling $sln_file in $BuildConfiguration mode to $build_dir"
    Exec { msbuild "$sln_file" /t:Clean /t:Build /p:Configuration=$BuildConfiguration 
        /m /nr:false /v:q /nologo /p:OutputDir=$build_dir }

    Get-ChildItem -Path $build_dir -Rec | Where {$_.Extension -match "pdb"} | Remove-Item
    Get-ChildItem -Path $build_dir -Rec | Where {$_.Extension -match "xml"} | Remove-Item
}