chylex - software development and game modding projects

Your browser does not seem to support modern web features.

TweetDuck is an open-source desktop client for the TweetDeck website by Twitter. A major update came out recently that removed a huge amount of horrible code, so I decided to do a write-up of some of the worst code I've written throughout the development.

To implement the large amount of features and enhancements TweetDuck provides, a lot of reverse-engineering and understanding of both the original JavaScript code on the TweetDeck website, as well as the Chromium Embedded Framework (CEF) the client is based on, is required... you would hope... because this blog post shows the exact opposite of that!

So buckle up, and get ready to see lots of disgusting code! And we're starting with...

Migration from the official discontinued client

TweetDuck was meant to replace the official TweetDeck client, officially releasing the same day the official client was officially discontinued. This was an opportunity to make TweetDuck not only seamlessly import your old profile, but also to uninstall the old client, which included replacing the old client's icons on the desktop, and in the taskbar if pinned. Unsurprisingly, just like a perfectly orchestrated symphony playing an ode to half-baked similes, the migration was absolutely flawless as you can see on the following demonstration:

Now, this code didn't come from a misunderstanding, it's just not something I'd recommend doing, and having bugs in code that uninstalls other programs and casually messes about with the desktop and registry is a really bad time. Let's look at one of the iterations of it, as the code was updated many times throughout the development, often removing some of the functionality in exchange for easier sleep.

The migration begins by copying all the important files and folders, closing the TweetDeck process if it's still running, and then it starts the purge...

Updating shortcut icons

In order to update shortcuts, a reference to Shell32 COM library was added (and wrapped in a custom LnkEditor class) to edit shortcut files. After we edit the shortcuts, we force Windows to refresh all icons.

[DllImport("Shell32.dll")]
public static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

public static IEnumerable<string> GetLnkDirectories(){
    yield return Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
    yield return Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory);
    yield return Environment.ExpandEnvironmentVariables(@"%APPDATA%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar");
}
// update the lnk files wherever possible (desktop icons, pinned taskbar, start menu)
foreach(string location in GetLnkDirectories()){
    if (string.IsNullOrEmpty(location))continue;

    string linkFile = Path.Combine(location, "TweetDeck.lnk");

    if (File.Exists(linkFile)){
        LnkEditor lnk = new LnkEditor(linkFile);
        lnk.SetPath(Application.ExecutablePath);
        lnk.SetWorkingDirectory(Environment.CurrentDirectory);
        lnk.SetComment(Program.BrandName+" client for Windows");
        lnk.Save();

        string renamed = Path.Combine(location, Program.BrandName+".lnk");

        try{
            if (!File.Exists(renamed)){
                File.Move(linkFile, renamed);
            }
            else{
                File.Delete(linkFile);
            }
        }catch{
            // eh, too bad
        }
    }
}

NativeMethods.SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero); // refreshes desktop

Uninstalling the original client

For the final stage of migration, we find the original client's GUID in one of the several registry locations that store uninstall data, and then feed it to msiexec to force a quiet uninstall.

public static bool RunUninstaller(string guid, int timeout){
    try{
        Process uninstaller = WindowsUtils.StartProcess("msiexec.exe", "/x "+guid+" /quiet /qn", true);

        if (uninstaller != null){
            if (timeout > 0){
                uninstaller.WaitForExit(timeout); // it appears that the process is restarted or something that triggers this, but it shouldn't be a problem
            }

            uninstaller.Close();
        }

        return true;
    }catch(Exception){
        return false;
    }
}

public static string FindProgramGuidByDisplayName(string displayName){
    Predicate<RegistryKey> predicate = key => displayName.Equals(key.GetValue("DisplayName") as string, StringComparison.OrdinalIgnoreCase);
    string guid;

    return ​FindMatchingSubKey(Registry.LocalMachine, @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall", predicate, out guid) ||
           FindMatchingSubKey(Registry.LocalMachine, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", predicate, out guid) ||
           FindMatchingSubKey(Registry.CurrentUser, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", predicate, out guid)
           ? guid : null;
}

private static bool FindMatchingSubKey(RegistryKey keyHandle, string path, Predicate<RegistryKey> predicate, out string guid){
    string outputId = null;

    try{
        RegistryKey parentKey = keyHandle.OpenSubKey(path, false);
        if (parentKey == null)throw new InvalidOperationException();

        foreach(RegistryKey subKey in parentKey.GetSubKeyNames().Select(subName => parentKey.OpenSubKey(subName, false)).Where(subKey => subKey != null)){
            if (predicate(subKey)){
                outputId = subKey.Name.Substring(subKey.Name.LastIndexOf('\\')+1);
                subKey.Close();
                break;
            }

            subKey.Close();
        }

        parentKey.Close();
    }catch(Exception){
        guid = null;
        return false;
    }

    return (guid = outputId) != null;
}

Unfortunately, the one flaw with it was that while testing everything, I eventually managed to uninstall and delete all instances of the original client from all of my computers, and couldn't inspect it in detail later to avoid writing so much bullshit code (and the rest of this blog post).

NativeMethods.SimulateMouseClick

There's something incredibly satisfying about the ability to steal control away from the user, and force their peripherals to obey you, the all mighty programmer. However, it's probably not a great thing to have in a Twitter client.

public const int MOUSEEVENTF_LEFTDOWN = 0x02;
public const int MOUSEEVENTF_LEFTUP = 0x04;
public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
public const int MOUSEEVENTF_RIGHTUP = 0x10;

public enum MouseButton { Left, Right }

[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

public static void SimulateMouseClick(MouseButton button){
    int flagHold, flagRelease;
    
    switch(button){
        case MouseButton.Left:
            flagHold = SystemInformation.MouseButtonsSwapped ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN;
            flagRelease = SystemInformation.MouseButtonsSwapped ? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP;
            break;
            
        case MouseButton.Right:
            flagHold = SystemInformation.MouseButtonsSwapped ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN;
            flagRelease = SystemInformation.MouseButtonsSwapped ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
            break;
            
        default: return;
    }
    
    mouse_event(flagHold, Cursor.Position.X, Cursor.Position.Y, 0, 0);
    mouse_event(flagRelease, Cursor.Position.X, Cursor.Position.Y, 0, 0);
}

Scrolling mouse wheel above an unfocused notification

Sometimes tweets get too large and the notification window has a scrollbar. Surely it would be nice if it was possible to scroll without having to manually click on the window first, right?

Thankfully, Windows lets you hook global mouse events, so it's possible to detect any mouse activity and even cancel it (ooo, scary!). This hook callback listens for mouse wheel events, checks if the cursor is above the notification window, makes sure it's not already focused, and then... uh...

private IntPtr MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam){
    if (wParam.ToInt32() == NativeMethods.WM_MOUSEWHEEL && browser.Bounds.Contains(PointToClient(Cursor.Position)) && !ContainsFocus){
        // fuck it, Activate() doesn't work with this
        Point prevPos = Cursor.Position;
        Cursor.Position = PointToScreen(new Point(0, -1));
        NativeMethods.SimulateMouseClick(NativeMethods.MouseButton.Left);
        Cursor.Position = prevPos;
        return NativeMethods.HOOK_HANDLED;
    }
    
    return NativeMethods.CallNextHookEx(mouseHook, nCode, wParam, lParam);
}

Yeah. Well, it turns out CEF has a somewhat hidden method to pass a mouse wheel event into the window. Though I do wonder what exactly is the point of Windows protecting against unwanted focus stealing, when you can simply force a click on the window border.

private IntPtr MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam){
    if (wParam.ToInt32() == NativeMethods.WM_MOUSEWHEEL && browser.Bounds.Contains(PointToClient(Cursor.Position)) && !ContainsFocus){
        browser.GetBrowser().GetHost().SendMouseWheelEvent(0, 0, 0, NativeMethods.GetHookWheelDelta(lParam), CefEventFlags.None);
        return NativeMethods.HOOK_HANDLED;
    }
    
    return NativeMethods.CallNextHookEx(mouseHook, nCode, wParam, lParam);
}

The only extra requirement here was extracting the wheel delta value, which says the direction and distance of the scroll. In a global mouse hook, this data is present in a structure pointed at by lParam. This still required some native code interop, but it was rather nice:

[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT{
    public POINT pt;
    public int mouseData;
    public int flags;
    public int time;
    public UIntPtr dwExtraInfo;
}

public static int GetHookWheelDelta(IntPtr ptr){
    return Marshal.PtrToStructure<MSLLHOOKSTRUCT>(ptr).mouseData >> 16;
}

Stealing focus from example notification

Opening Settings and clicking the Notifications tab displays an example notification window which, despite several attempted measures, keeps stealing focus (so now we have the exact opposite problem with windows stealing focus). To prevent that, here is an incredible hack that detects when the example notification comes into focus, and then forces a click on the Settings window to steal it back:

private void notification_Activated(object sender, EventArgs e){
    if (Cursor.Position == initCursorPosition && initCursorPosition != ControlExtensions.InvisibleLocation){
        Timer delay = WindowsUtils.CreateSingleTickTimer(1);
        
        delay.Tick += (sender2, args2) => { // here you can see a disgusting hack to force the freshly opened notification window out of focus
            NativeMethods.SimulateMouseClick(NativeMethods.MouseButton.Left); // because for some reason, the stupid thing keeps stealing it
            delay.Dispose(); // even after using ShowWithoutActivation, the CreateParams bullshit, and about a million different combinations
        }; // of trying to force the original form back into focus in various events, so you will have to fucking deal with it, alright

        delay.Start();
    }
    
    notification.Activated -= notification_Activated;
}

Thankfully, after not giving up on finding better solutions, I came across the idea to hide the window as soon as it steals focus. This is okay, because the notification window will become visible again once the browser inside it loads, but for that it uses a special flag which ensures that the window shows on top without stealing focus every time a notification comes in.

private void notification_Activated(object sender, EventArgs e){
    notification.Hide();
    notification.Activated -= notification_Activated;
}

Uploading images from clipboard

This is an incredibly useful feature held together by some of the most convoluted code I've ever written. In order to upload an image, the following sequence of events happens in the code:

  1. Pressing CTRL+V (or clicking Paste) triggers an event in JavaScript, which sends a message to C# code
  2. C# checks whether the clipboard contains an image, and if so, it creates a temporary PNG file and sends a message back to JS
  3. Due to a short delay after the user input and Chromium's evil protection schemes, it's now impossible to trigger the upload using JS code, so we have to force a click on the Add images button:
    1. If the user is replying to someone, the upload button is not visible, so we click the Popout button which switches into the New Tweet panel which has all the buttons; the switch happens with an animation, so we have to wait until it's finished using a timer that periodically checks the animation state (for reliability)
    2. If the screen is small, the button may be out of view so we find its location and scroll it into view
    3. Finally, I send a message back to C# which uses SimulateMouseClick to click on the upload button
  4. When an upload is triggered, CEF intercepts it and allows my code to tell it which files to upload; this is where we give it the temporary image file
  5. Finally, a temporary event in JS detects a new upload, and restores the scroll offset & focus back into the text input box

Here is only a fraction of the code that makes it all work:

var lastPasteElement;
var prevScrollTop;

var getScroller = function(){
  return $(".js-drawer").find(".js-compose-scroller").first().children().first();
};

var clickUpload = function(){
  $(document).one("uiFilesAdded", function(){
    getScroller().scrollTop(prevScrollTop);
    $(".js-drawer").find(".js-compose-text").first()[0].focus();
  });

  var button = $(".js-add-image-button").first();

  var scroller = getScroller();
  prevScrollTop = scroller.scrollTop();

  scroller.scrollTop(0);
  scroller.scrollTop(button.offset().top); // scrolls the button into view

  var buttonPos = button.children().first().offset(); // finds the camera icon offset
  $TD.clickUploadImage(Math.floor(buttonPos.left), Math.floor(buttonPos.top));
};

app.delegate(".js-compose-text,.js-reply-tweetbox", "paste", function(){
  lastPasteElement = $(this);
  $TD.tryPasteImage();
});

window.TDGF_tryPasteImage = function(){
  if (lastPasteElement){
    var parent = lastPasteElement.parent();

    if (parent.siblings(".js-add-image-button").length === 0){
      var pop = parent.closest(".js-inline-reply,.rpl").find(".js-inline-compose-pop,.js-reply-popout");

      if (pop.length === 0){
        lastPasteElement = null;
        return;
      }

      pop.click();

      var drawer = $(".js-drawer");
      var counter = 0;

      var interval = setInterval(function(){
        if (drawer.offset().left >= 195){
          clickUpload();
          clearInterval(interval);
        }
        else if (++counter >= 10){
          clearInterval(interval);
        }
      }, 51);
    }
    else{
      clickUpload();
    }

    lastPasteElement = null;
  }
};
public void TryPasteImage(){
    form.InvokeSafe(() => {
        if (Clipboard.ContainsImage()){
            Image img = Clipboard.GetImage();
            if (img == null)return;

            try{
                Directory.CreateDirectory(Program.TemporaryPath);

                ClipboardImagePath = Path.Combine(Program.TemporaryPath, "TD-Img-"+DateTime.Now.Ticks+".png");
                img.Save(ClipboardImagePath, ImageFormat.Png);

                form.OnImagePasted();
            }catch(Exception e){
                Program.Reporter.HandleException("Clipboard Image Error", "Could not paste image from clipboard.", true, e);
            }
        }
    });
}

public void ClickUploadImage(int offsetX, int offsetY){
    form.InvokeSafe(() => {
        Point prevPos = Cursor.Position;
        
        Cursor.Position = form.PointToScreen(new Point(offsetX, offsetY));
        NativeMethods.SimulateMouseClick(NativeMethods.MouseButton.Left);
        Cursor.Position = prevPos;
        
        form.OnImagePastedFinish();
    });
}

At first, I just replaced SimulateMouseClick with CEF's own SendMouseClickEvent, which does the same thing but somewhat safer. However, while writing this blog post and after some digging and reverse-engineering, I managed to replace over a hundred lines of code with this...

var uploader = $._data(document, "events")["uiComposeAddImageClick"][0].handler.context;

app.delegate(".js-compose-text,.js-reply-tweetbox", "paste", function(e){
  for(let item of e.originalEvent.clipboardData.items){
    if (item.type.startsWith("image/")){
      $(this).closest(".rpl").find(".js-reply-popout").click(); // popout direct messages
      uploader.addFilesToUpload([ item.getAsFile() ]);
      break;
    }
  }
});

The main catch was the first line. There is a lot of code in the TweetDeck source that is "hidden away" from the global context, so you have to jump through hoops to get access to certain objects (for example, by using undocumented jQuery functions).

Still, I'm proud to say that the ~140 of lines of code (not even counting its dependencies, like SimulateMouseClick) have never failed a single image upload I've done.

Taking a screenshot

Another quite useful feature of TweetDuck is taking screenshots of individual tweets. You can do that by right-clicking on a tweet (even those under the Notifications column, with likes and retweets), and selecting Screenshot tweet to clipboard. Now, ignoring all of the other horrible code to make this work (such as using a very short timer to make sure the screenshot isn't just a white rectangle – mind that the timer had to be extended several times – this is how I originally made the actual screenshot part of it...

public void TakeScreenshotAndHide(){
    MoveToVisibleLocation();
    Activate();
    SendKeys.SendWait("%{PRTSC}");
    Reset();
}

In case it somehow isn't immediately clear and obvious, %{PRTSC} is basically Alt+PrintScreen, which takes a screenshot of the currently active window (see what it's getting at?)

Well, MSDN notes "reserved for future use" under PRTSC, so that's not a great sign. It also doesn't work at all if the window is out of view. Ironically, the "proper" solution is uh, this...

[DllImport("user32.dll")]
private static extern IntPtr GetWindowDC(IntPtr hWnd);

[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd);

[DllImport("user32.dll")]
private static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("gdi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);

public static IntPtr GetDeviceContext(Form form, bool includeBorder){
    return includeBorder ? GetWindowDC(form.Handle) : GetDC(form.Handle);
}

public static void RenderSourceIntoBitmap(IntPtr source, Bitmap target){
    using(Graphics graphics = Graphics.FromImage(target)){
        IntPtr graphicsHandle = graphics.GetHdc();

        try{
            BitBlt(graphicsHandle, 0, 0, target.Width, target.Height, source, 0, 0, 0x00CC0020);
        }finally{
            graphics.ReleaseHdc(graphicsHandle);
        }
    }
}

public static void ReleaseDeviceContext(Form form, IntPtr ctx){
    ReleaseDC(form.Handle, ctx);
}
public void TakeScreenshotAndHide(){
    MoveToVisibleLocation();
    
    bool border = Program.UserConfig.ShowScreenshotBorder;
    IntPtr context = NativeMethods.GetDeviceContext(this, border);
    
    if (context != IntPtr.Zero){
        using(Bitmap bmp = new Bitmap(border ? Width : ClientSize.Width, border ? Height : ClientSize.Height, PixelFormat.Format32bppRgb)){
            try{
                NativeMethods.RenderSourceIntoBitmap(context, bmp);
            }finally{
                NativeMethods.ReleaseDeviceContext(this, context);
            }

            Clipboard.SetImage(bmp);
        }
    }
    
    Reset();
}

The updated code is not only more reliable, but can also take screenshots when the window is out of view. Well, unless the Include Border In Screenshots option is enabled, which renders the window border in the screenshot, but the window has to be fully visible on the screen. The border also breaks on Windows 10, so in that case, the code is about as reliable as Windows 10 is polished.

Somewhere between starting to write this blog post and finishing it, I have decided that I cannot be bothered anymore and removed the Include Border In Screenshots option completely.

Getting volume mixer level for the app

When you create a new Windows Media Player COM object to play sound files in your app, it always defaults to a volume level of 50. However, if you change the volume of the player object in your code, it will change the volume level of your app in the Windows volume mixer. Thanks, Microsoft

FlowLayoutPanel shenanigans

Windows Forms is a bit, uh, either lacking or confusing when it comes to certain layout options. For the Plugin list, I wanted a layout that placed elements into a list, made them take up full width of the panel, and allowed vertical scrolling if it overflowed.

I used FlowLayoutPanel... maybe I shouldn't have, just for the amount of hacks I ended up deploying to fix or force various aspects of my vision.

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowScrollBar(IntPtr hWnd, int wBar, bool bShow);
class PluginListFlowLayout : FlowLayoutPanel{
    public PluginListFlowLayout(){
        FlowDirection = FlowDirection.TopDown;
        WrapContents = false;
    }

    protected override void WndProc(ref Message m){
        NativeMethods.ShowScrollBar(Handle, NativeMethods.SB_HORZ, false); // basically fuck the horizontal scrollbar very much
        base.WndProc(ref m);
    }
}
private void flowLayoutPlugins_Resize(object sender, EventArgs e){
    if (flowLayoutPlugins.Controls.Count == 0){
        return;
    }

    Control lastControl = flowLayoutPlugins.Controls[flowLayoutPlugins.Controls.Count-1];
    bool showScrollBar = lastControl.Location.Y+lastControl.Height >= flowLayoutPlugins.Height;
    int horizontalOffset = showScrollBar ? SystemInformation.VerticalScrollBarWidth : 0;

    flowLayoutPlugins.AutoScroll = showScrollBar;
    flowLayoutPlugins.VerticalScroll.Visible = showScrollBar;

    foreach(Control control in flowLayoutPlugins.Controls){
        control.Width = flowLayoutPlugins.Width-control.Margin.Horizontal-horizontalOffset;
    }

    flowLayoutPlugins.Focus();
}

Of course, all parts are important. Hacking in ShowScrollBar and calling it in WndProc (up to several hundred times a second) to disable the horizontal scrollbar which would pop up when resizing, forcing all elements to take up full width and manually checking if the scrollbar should be visible, and finally forcing focus into the panel which makes the mouse wheel work on it.

At the time of writing, this monstrosity has not been replaced with anything better.

Detecting new tweets

This one is from very, very early development, when I was kinda rushing to get things done... I wanted to replicate the original client's popup notification system, but without the time required to figure out how exactly they did that. Say hello to Mutation Observers...

var registerTweetObserverForColumn = function(column){
  if (column[0].hasAttribute("data-std-observed"))return;

  var mid = column;
  mid = mid.children().first();
  mid = mid.children().first();
  mid = mid.children(".js-column-content").first();
  mid = mid.children(".js-column-scroller").first();

  var container = mid.children(".js-chirp-container").first();
  if (container.length === 0)return;

  var scroller = container.parent();

  new MutationObserver(function(mutations){
    if (!container[0].hasAttribute("data-std-loaded")){
      container[0].setAttribute("data-std-loaded", "");
      return;
    }

    var data = TD.controller.columnManager.get(column.attr("data-column"));
    if (!data.model.getHasNotification())return;

    if (scroller.scrollTop() != 0)return;

    Array.prototype.forEach.call(mutations, function(mutation){
      Array.prototype.forEach.call(mutation.addedNodes, function(node){
        if (node.tagName !== "ARTICLE")return;

        onNewTweet(column,node);
      });
    });
  }).observe(container[0], {
    childList: true
  });

  column[0].setAttribute("data-std-observed", "");
};

(function(){
  var columns = $(".js-app-columns").first();

  var refreshColumnObservers = function(){
    columns.children().each(function(){
      registerTweetObserverForColumn($(this));
    });
  };

  new MutationObserver(refreshColumnObservers).observe(columns[0], {
    childList: true
  });

  refreshColumnObservers();
})();

So in order to detect new tweets, we add an observer that will notify our code every time a new element is added into a column, and also an observer to detect when a new column is added. This is not the only code that used MutationObservers – there was one for watching when the user changed the theme or font size, and until version 1.7.1, one was also used to detect when TweetDeck finished loading.

Also note how the code only shows notifications if the column is scrolled to the top, otherwise if you scrolled down too far and then scrolled back up, you would see notifications pop up for old tweets as they were loading back into view. Now, the replacement for all of that shows why it is important to learn the code you're working with:

$.subscribe("/notifications/new", function(obj){
  for(let index = obj.items.length-1; index >= 0; index--){
    onNewTweet(obj.column, obj.items[index]);
  }
});

Long lasting TODOs

As is the convention for any professionally managed project, TweetDuck also includes some carefully ignored TODO comments that sleep in the code for months. Just do a search for them every once in a while to make sure someone else didn't fix them before you.

Showing column name in notification window title - 1 year minus a couple days

(fixed by cursing at TweetDeck for making this feature so annoying to figure out)

$TD.onTweetPopup(html.html(), url, tweet.text.length); // TODO column

Wanting to make email links neater - 1 year minus a couple days

(fixed by removing the TODO)

public static void OpenExternalBrowser(string url){ // TODO implement mailto

Not bothering with IO exceptions in plugin manager - 10 months

(fixed by bothering the user with the exception reports instead)

try{
    script = File.ReadAllText(path);
}catch{
    // TODO
    continue;
}

Flickering tooltip - 2 months

(fixed by both removing the TODO, and hoping that nobody notices)

toolTip.Show(text, this, position); // TODO figure out flickering when moving the mouse

Actually useful code and tips you can use

Converting pascal case to screaming snake case

The docs just say "Converts pascal case to screaming snake case." and "<returns>string converted from pascal case to screaming snake case</returns>".

public static string ConvertPascalCaseToScreamingSnakeCase(string str){
    return Regex.Replace(str, @"(\p{Ll})(\P{Ll})|(\P{Ll})(\P{Ll}\p{Ll})", "$1$3_$2$4").ToUpperInvariant();
}

Arbitrary code execution exploit

If your app displays a remote website you're not in control of and give JavaScript access to a function that opens the external browser like this...

public static void OpenExternalBrowser(string url){
    using(Process.Start(url)){}
}

...it might be a good idea to check the URL first before something like <a href="c:/windows/system32/notepad.exe">hello there</a> sneaks into the website.

public static bool IsValidUrl(string url){
    Uri uri;

    if (Uri.TryCreate(url, UriKind.Absolute, out uri)){
        string scheme = uri.Scheme;
        return scheme == Uri.UriSchemeHttp || scheme == Uri.UriSchemeHttps || scheme == Uri.UriSchemeFtp || scheme == Uri.UriSchemeMailto;
    }

    return false;
}

Now, theoretically this would pretty much only be exploitable with the Plugin system which (besides the ACE) is quite well sandboxed. But there is no way a user would install a random unverified script off the internet, and on top of that, there is absolutely no way a big company like Twitter would suddenly add an XSS exploit to their website, right? ... sighs

Lazy exception catching

"Lazy" as in "lazy programmer", not "lazy evaluation". Visual Studio (or ReSharper) complains about empty catch blocks. You can easily suppress the complaints by adding a comment into the block, without putting any actual effort into, you know, actually handling the exception:

try{
    File.Delete(file);
}catch{
    // welp, too bad
}
try{
    File.AppendAllText(LogFile, build.ToString(), Encoding.UTF8);
}catch{
    // oops
}

If you need some more ideas, feel free to go the passive-aggressive route,

}catch{
    // didn't want that to work anyways
}

or the silent treatment,

}catch{
    //
}

or whatever else your heart desires.

}catch{
    // Somebody once told me the world was gonna throw me
    // I should have embraced Golang instead
}

Clever and insightful conclusion

// TODO add a clever and insightful conclusion

// In the meantime, don't write horrible code I guess.
// Or do, because it's fun to write blog posts about them, and then pretend that your next project is definitely not going to be like this.