Tuesday, August 21, 2018

Using Powershell as a command / alias runner

I've been using powershell as a command runner for quite awhile.  Any time I want to automate something, I can write a powershell function (or a group of functions in a separate script file), add it to my profile, and it'll be available in any powershell command window.  I even get added benefits such as function completion.  I've named several functions beginning with "csm" and when I type csm + ctrl enter I get this:



To get this working, you must first create a profile:
  • At the powershell command prompt, run Test-Path $Profile.  If the result is true, then you have created a profile.  To see the path to your profile, just type $Profile.
  • If the result is false, run this command to create a profile:
    • New-Item -Path $Profile -Type File -Force.
  • I've no idea how to create it an a location you desire (I back mine up in place), but this will create a file like: C:\Users\[you]\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
  • Open your profile in the Powershell ISE.  Create functions to your heart's desire.  Of course you have access to all of powershell's built in commands as well.
  • If you get an error saying you can't run scripts, run this command: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned  More info here.
You will need to keep the concept of "dot raising" in mind.  This is a security measure, I believe.  So to launch an executable, you will need to write your function like this:

function start-git
{
    Set-Location C:\Dev
    . "C:\Program Files\Git\bin\bash.exe" #note the dot
}

If you want to pass parameters into your function, you can do that like:

function compare-files([string]$s1, [string]$s2)
{
    . "C:\Program Files (x86)\WinMerge\WinMergeU.exe" $s1 $s2
}

If you want to group related functions in a separate script, you reference it like this:
#########  WhateverFunctions.psm1
function whatever {}
Export-ModuleMember -function whatever
########## profile
Import-Module C:\WhateverFunctions.psm1

Friday, April 06, 2018

Detecting ActiveMQ Connection Interrupts using the .Net Wrapper

While using ActiveMQ (via the ActiveMQ NMS client) in a C# codebase, I had a very difficult time trying to figure out how to properly detect a lost connection to the ActiveMQ service.  Things that seemed like they should've worked included:
  • ((Apache.NMS.ActiveMQ.Connection)connection).ITransport.IsConnected.  This returns true when completely disconnected.
  • ((Connection)connection).ConnectionInterruptedListener.  This never fires under normal configuration (details here).
I had to hook into the ConnectionExceptionListener like yay:

MessageBroker

IConnectionFactory factory = new ConnectionFactory(messageQueueConfigurationDef.BrokerUri);
IConnection connection = factory.CreateConnection(userName, password);
connection.ExceptionListener += ConnectionExceptionListener;

private void ConnectionExceptionListener(Exception ex)
{
  if (connection != null)
  {
    // Release this handler.
    connection.ExceptionListener -= ConnectionExceptionListener;
  }
  Invalidate();  // invalidating connection related objects here.
}

Subscriber
In my subscriber, I had to use this mechanism for detecting disconnection (and waiting for initial connection if necessary):
int period = 60000;  // or some configured value
heartBeatTimer = new Timer(unused_state =>
{
  if (!MessageBroker.IsConnected)  // returns false if Invalidate() above was called.
  {
     Subscribe;                    // Will trigger a re-connect above.
  }
}, null, 0, period);

Friday, October 06, 2017

Re-map Right Windows key to Menu key on Windows

I purchased a decent mechanical keyboard; it's a ducky Shine 3.  Duckys (despite the strange name) seem to be very high quality mechanical keyboards.  This model, as with most of their models, has no menu / right-click key.  I use this key constantly.  Some of the other model's manuals indicate that there is some key-combination that will activate menu, but not this one.  This workaround will apply for any keyboard that lacks any built-in way to activate menu.
I don't use the right-windows key.  That key is in approximately the same spot as the menu key usually is (and I always look down to press the menu key), so I re-mapped that key to activate menu.

To get the proper value into the registry, I used SharpKeys.  That utility allows you to type in the keys you want to re-map, so I plugged in a different keyboard that actually had the menu key, typed in the keys to re-map, and saved the value to the registry (requires reboot after adding).  Thanks SharpKeys!

Here is all that is required in a .reg file in order to add this value to the registry:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,5d,e0,5c,e0,00,00,00,00

Monday, February 06, 2017

Will Web Applications be Fixed Soon?

I read recently that in-browser apps are extremely favored over native apps (people use their favorite social media app and maybe one other and don't bother with anything else). This makes sense; users are taking the path of least resistance - don't bother installing something unless you have to.
But yet, in-browser applications are so frequently busted. They even seem to get worse as time goes on in some cases. I used to listen to slacker and pandora in the browser. Slacker stopped working some time ago (in any browser), and pandora stopped working recently. I mean not working as in not at all - can't make it through more than one song without hanging the browser. So I started using spotify which seems to default to having you install a client. It works. You can even pause your song and it resumes at the exact place the next time you open the app. The UI is terrible IMO, but it works. Isn't this the goal, to actually work?
Web as a platform for applications still seems like a hack after all this time. I remember getting excited about Silverlight back in the day: yay, we can write an application and it will work like an application! It was a workaround for web as platform. Then Silverlight (and Flash) died.
Now Service Workers / WebAssembly seem to be the next candidate to overcome the web as platform hack. Will they enable applications to actually work in browsers, or will they go the way of flash? Both are starting out as actual standards, so they seem promising.
If they do catch on, won't that render most of the native app work obsolete?  Maybe these technologies can't help whatever broke slacker/pandora?  What other capabilities will remain un-achievable at that point?

Tuesday, December 27, 2016

Simplest F# Asynchronous Workflow Sample


Can't nobody tell me F# async is easy; it seems hard to me. I wanted to put together the simplest sample (but different from all the samples I've seen) so I could get a better understanding. Maybe thistle help someone else. I'm searching a file line by line to see if I can find a match. In this case there are only 4 lines in the file so I'm splitting the file into 2 chunks.  Each... async... thing (after watching a long video on C# async lately and ending up hopelessly confused about when actual new threads are created I've given up guessing) gets 2 lines. In this sample, it's pretty handy how it stops looking after finding a match.

open System.IO
open System

// So we don't just print "null" to console when not found.
let OptionToStr o =
  match o with
  | None -> "not found"
  | Some(o) -> o

// Because our line gets wrapped into an option twice (once in Seq.tryPick and again in Seq.tryFind).
let UnwrapOption o =
  match o with
  | None -> None
  | Some(o) -> o

// Some(matching line) if the current chunk contains our id
let ChunkContains (id:string) (chunk:string seq) =
  chunk
  |> Seq.tryPick ( fun line -> 
                   // Notice how it doesn't process all lines when it finds a match.
                   printfn "Current: %s" line
                   if line.Contains id then Some(line) else None )

// Skip n lines and call our search method for the current chunk
let ProcessFileChunkAsync (lines:string seq) skip (func: string seq -> string option) =
  async {         // Note: async is cranky.  You have to format the curly braces a certain way or compiler will complain with strange error.
    return lines  // return keyword required.
    |> Seq.skip skip
    |> Seq.truncate 2
    |> func       // 2nd parameter applied to previous partial application of ChunkContains below.
   }

[]
let main argv = 
  let lines = File.ReadAllLines @"c:\temp\4LinesOfTrash.txt"  // one of the lines is "hi mom"
  seq { 0 .. 1 }
  |> Seq.map ( fun i -> let chunkFun = ChunkContains "hi"   // find the line with "hi"; partial func application
                        ProcessFileChunkAsync lines (i * 2) chunkFun
             )
  |> Async.Parallel          // Fork
  |> Async.RunSynchronously  // Join: Take the async results and wait for them to complete.
  |> Seq.tryFind ( fun item -> Option.isSome item )
  |> UnwrapOption
  |> OptionToStr
  |> printfn "Result: %A"
  |> Console.ReadLine
  |> ignore
  0

Thursday, October 13, 2016

URL Redirecting in an OWIN Self-Hosted Web Application

Perhaps this will get old quick; I don't know. Had a small research task for this. In this case I'm using a couple WebAPI controllers along with OWIN to demo.

  1. Create new console application.
  2. Install nuget packages Microsoft.Owin.SelfHost, Microsoft.AspNet.WebApi.Owin
  3. Create RedirectMiddleware.cs like below (source)
  4. Create Startup.cs like below
  5. Make Program.cs (self-host starter) like below.
  6. Add a couple controller classes, I added AController and BController.

 public class RedirectMiddleware : OwinMiddleware
 {

  public RedirectMiddleware(OwinMiddleware next) : base(next)
  {
  }

  public async override Task Invoke(IOwinContext context)
  {
   var url = context.Request.Uri;
   var shouldRedirect = ShouldRedirect(url.AbsoluteUri);
   if (shouldRedirect.Item1)
   {
    // permanent redirect
    context.Response.StatusCode = 301;
    context.Response.Headers.Set("Location", shouldRedirect.Item2);
   }
   else
   {
    await Next.Invoke(context);
   }
  }

  private Tuple<bool, string> ShouldRedirect(string uri)
  {
   if (uri.EndsWith("A"))
   {
    return Tuple.Create(true, "/B");
   }
   else
   {
    return Tuple.Create(false, "");
   }
  }

 }

 class Startup
 {

  public void Configuration(IAppBuilder appBuilder)
  {
   // Setup WebAPI configuration
   var configuration = new HttpConfiguration();

   configuration.Routes.Add("API Default", new HttpRoute("{Controller}"));

   /// Register our middleware
   /// Order of registration is the order the middleware will execute in.
   appBuilder.Use();

   // Register the WebAPI to the pipeline
   appBuilder.UseWebApi(configuration);

   appBuilder.Run((owinContext) =>
   {
    owinContext.Response.ContentType = "text/plain";
    return owinContext.Response.WriteAsync("Controllers are /A and /B.  http://localhost:5000/A will take you to B");
   });
  }

 }

 class Program
 {
  static void Main(string[] args)
  {
   const string baseUrl = "http://localhost:5000/";
   using (WebApp.Start<Startup>(baseUrl))
   {
    Console.WriteLine("Hit me up @ http://localhost:5000.  Press Enter to shut down.");
    Console.ReadKey();
   }
  }
 }

Thursday, October 06, 2016

Powershell Tray Icon Sample

The powershell samples for popping a tray icon weren't complete.  Here is a simple example (pops for 5 seconds) that I'm using to regularly remind me to stand/stretch/focus my eyes on distant objects. I've wrapped it in a scheduled task that calls powershell passing this script as the arg starting every weekday at about the time I start work repeating every 20 minutes.

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$m = (Get-date).Minute

<# This is multi-line comment syntax #>
# Console.Write equivalent:
#Write-Host $m

$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$objNotifyIcon.Icon = "C:\Someplace\YourTrayIcon.ico"
$objNotifyIcon.BalloonTipIcon = "Warning"
$objNotifyIcon.BalloonTipTitle = "Hocus Focus"

if ($m -lt 30)
{
$objNotifyIcon.BalloonTipText = "Focus your eyes distant and blink frequently"
}
else
{
$objNotifyIcon.BalloonTipText = "Focus eyes & stretch too"
}

$objNotifyIcon.Visible = $True
$objNotifyIcon.ShowBalloonTip(1) #Not sure what the heck this millisecond param is even for; it stays until you hide it.

Start-Sleep -Seconds 5
$objNotifyIcon.Visible = $False