Tahir Hassan's Blog

My Technical Notes

Wednesday, 22 March 2017

Using DebugView for Debugging AutoHotkey Scripts

DebugView is an application made by SysInternals that can be used to view debug messages produced by applications.

To create a debug message using AutoHotkey, use the `OutputDebug` command:


OutputDebug, Hello World

Because many other applications also produce debug messages, you want to be able to show only those messages produced by your AutoHotkey script. For this, you can wrap the above command in a function that prepends `[AHK] ` to messages to make them searchable:


DebugMsg(Msg) {
    OutputDebug, [AHK] %Msg%
}

This function is called by passing in a string argument, as below demonstrates. The result is that `[AHK] Hello World` will appear in DebugView's message list.


DebugMsg("Hello World")

Configuring DebugView

Filter to only include [AHK] messages

To configure DebugView to only show messages from AutoHotkey, first show the "DebugView Filter" dialog, by either doing `Ctrl-L` or Edit → Filter/Highlight. In this dialog, in the `Include` field, add `[AHK]*` and press OK. This will not filter existing messages in the list, only new ones.

Highlighting messages by color
To highlight messages containing some text by color, first select a Filter from the list, and then in the colored textbox below it, enter some text to highlight:

Strangely enough, in contrast to the filtering behavior only affecting newly captured messages, the highlighting affects existing messages too.

Other...

If DebugView is not capturing messages (with filter set as `*`), then you may have to run it as administrator.

Sunday, 19 March 2017

Resizing Images using ImageMagick on Windows

ImageMagick is a handy commandline tool for every major platform that can be used to resize images (among its other uses). To install it on Windows, the recommended installer `ImageMagick-<version>-Q16-x64-dll.exe` worked fine and added `magick.exe` to the `PATH`. The installer recommends installing GhostScript for processing PDF and GhostScript, but because we are only using it to resize images, there is no need to install it.

When resizing an image, it is worth thinking about how big you want the resized image to be. To simplify matters, you can think of the resized image as fitting into a rectangle of $n$ by $m$ pixels. When an image is resized, its aspect ratio is maintained, but it has to fit inside this rectangle.

For illustration purposes, we use `magick.exe` to create a sample image file, `wizard.jpg`:


magick.exe wizard: wizard.jpg

This image is $480$ by $640$ pixels in size. For simplicity, let's say that we wish to shrink it so that it fits inside a $400$ by $400$ square. Its larger side (vertical), which is $640$, becomes $400$, therefore this side has shrunk by a percentage, $400/640$, which is $.625$. Its horizontal therefore will be $480 * .625$, which is $300$. In summary, the resized image will be $300$ by $400$ pixels in size.

To shrink it to this size, do:


magick.exe wizard.jpg -resize 400x400 resized-wizard.jpg

Sources

Adding a `.cmd` wrapper for an executable

When wanting to invoke an `.exe` on the commandline without specifying its full path, the usual course of action is to modify the `PATH` environment variable to include the `.exe` file's directory. A simple alternative, as described here, is to to create a `.cmd` wrapper for the `.exe` and place it in a folder which is already on the `PATH` environment variable.

An example `git.cmd` file is shown below. As mentioned earlier, you must put this `.cmd` into a folder which is in `PATH` environment variable.


@echo off
"C:\Program Files\Git\bin\git.exe" %*

`@echo off` disables echoing, and `%*` passes along all incoming arguments to the `git` executable.

On the Windows command-line, whether CMD or PowerShell, you can invoke an `.exe`, `.bat` or `.cmd` without specifying the `.extension`.

Saturday, 18 March 2017

PowerShell: Get a Service's Description

The result of `Get-Service` is a set of `System.ServiceProcess.ServiceController` objects, a type which does not have a property for the description shown in the Windows Services Window. The below sample code shows how to get the description for of the `XboxNetApiSvc` service.


& {
    $svc = [System.Management.ManagementObject]::new("Win32_Service.Name='XboxNetApiSvc'")
    $svc["Description"];
    $svc.Dispose();
}

In order to get the description for a `ServiceController` object, pass in the object's `Name` property in place of `XboxNetApiSvc`.

Tuesday, 14 March 2017

Converting DocX to Markdown using Pandoc

Run the following command:


pandoc -s ".\mydoc.docx" -t markdown -o mydoc.md --wrap=none --extract-media .

Tuesday, 28 February 2017

GOAL, TASK, SUB*-TASK, STEP terminology

  • To accomplish your `GOAL`, you need to complete a series of `TASKs`, and each `TASK` has a series of `STEPs` to complete, to be performed in a specified order.
  • If something is a `STEP`, then its parent is a `TASK`, or a `SUB-TASK` or a `SUB-SUB-...-TASK`.
  • If something is a SUB<N>-TASK (with `N` > 2), then its parent is a SUB<N-1>-TASK.

Publishing `.xml` files from bin directory in `.pubxml` file

In the `.pubxml` file, before the </Project> end tag, add the following XML:


<Target Name="CustomCollectFiles">
  <ItemGroup>
    <_CustomFiles Include=".\bin\*.xml" />
    <FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
      <!--<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>-->
      <DestinationRelativePath>bin\%(Filename)%(Extension)</DestinationRelativePath>
    </FilesForPackagingFromProject>
  </ItemGroup>
</Target>
<PropertyGroup>
  <CopyAllFilesToSingleFolderForPackageDependsOn>
    CustomCollectFiles;
    $(CopyAllFilesToSingleFolderForPackageDependsOn);
  </CopyAllFilesToSingleFolderForPackageDependsOn>

  <CopyAllFilesToSingleFolderForMsdeployDependsOn>
    CustomCollectFiles;
    $(CopyAllFilesToSingleFolderForPackageDependsOn);
  </CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>

Note that the filter `.\bin\*.xml` can be customised to only include specific files.