PowerShell Start-Process without taking focus

Earlier this week I had a need to start a process from PowerShell and ensure that it did not take focus.  This doesn’t seem to be supported by the Start-Process cmdlet or any other mechanism built into PowerShell, so I quickly built this script to call into CreateProcess with SW_SHOWNOACTIVATE.  With the below function a process can be started without it stealing focus, though it will appear on top of the z-order.

function Start-Process2($FilePath, $Arguments) {
Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
 
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION {
    public IntPtr hProcess;
    public IntPtr hThread;
    public uint dwProcessId;
    public uint dwThreadId;
}
 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STARTUPINFO {
    public uint cb;
    public string lpReserved;
    public string lpDesktop;
    public string lpTitle;
    public uint dwX;
    public uint dwY;
    public uint dwXSize;
    public uint dwYSize;
    public uint dwXCountChars;
    public uint dwYCountChars;
    public uint dwFillAttribute;
    public STARTF dwFlags;
    public ShowWindow wShowWindow;
    public short cbReserved2;
    public IntPtr lpReserved2;
    public IntPtr hStdInput;
    public IntPtr hStdOutput;
    public IntPtr hStdError;
}
 
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES {
    public int length;
    public IntPtr lpSecurityDescriptor;
    public bool bInheritHandle;
}
 
[Flags]
public enum CreationFlags : int {
    NONE = 0,
    DEBUG_PROCESS = 0x00000001,
    DEBUG_ONLY_THIS_PROCESS = 0x00000002,
    CREATE_SUSPENDED = 0x00000004,
    DETACHED_PROCESS = 0x00000008,
    CREATE_NEW_CONSOLE = 0x00000010,
    CREATE_NEW_PROCESS_GROUP = 0x00000200,
    CREATE_UNICODE_ENVIRONMENT = 0x00000400,
    CREATE_SEPARATE_WOW_VDM = 0x00000800,
    CREATE_SHARED_WOW_VDM = 0x00001000,
    CREATE_PROTECTED_PROCESS = 0x00040000,
    EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
    CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
    CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
    CREATE_DEFAULT_ERROR_MODE = 0x04000000,
    CREATE_NO_WINDOW = 0x08000000,
}
 
[Flags]
public enum STARTF : uint {
    STARTF_USESHOWWINDOW = 0x00000001,
    STARTF_USESIZE = 0x00000002,
    STARTF_USEPOSITION = 0x00000004,
    STARTF_USECOUNTCHARS = 0x00000008,
    STARTF_USEFILLATTRIBUTE = 0x00000010,
    STARTF_RUNFULLSCREEN = 0x00000020,  // ignored for non-x86 platforms
    STARTF_FORCEONFEEDBACK = 0x00000040,
    STARTF_FORCEOFFFEEDBACK = 0x00000080,
    STARTF_USESTDHANDLES = 0x00000100,
}
 
public enum ShowWindow : short {
    SW_HIDE = 0,
    SW_SHOWNORMAL = 1,
    SW_NORMAL = 1,
    SW_SHOWMINIMIZED = 2,
    SW_SHOWMAXIMIZED = 3,
    SW_MAXIMIZE = 3,
    SW_SHOWNOACTIVATE = 4,
    SW_SHOW = 5,
    SW_MINIMIZE = 6,
    SW_SHOWMINNOACTIVE = 7,
    SW_SHOWNA = 8,
    SW_RESTORE = 9,
    SW_SHOWDEFAULT = 10,
    SW_FORCEMINIMIZE = 11,
    SW_MAX = 11
}
 
public static class Kernel32 {
    [DllImport("kernel32.dll", SetLastError=true)]
    public static extern bool CreateProcess(
        string lpApplicationName, 
        string lpCommandLine, 
        ref SECURITY_ATTRIBUTES lpProcessAttributes, 
        ref SECURITY_ATTRIBUTES lpThreadAttributes,
        bool bInheritHandles, 
        CreationFlags dwCreationFlags, 
        IntPtr lpEnvironment,
        string lpCurrentDirectory, 
        ref STARTUPINFO lpStartupInfo, 
        out PROCESS_INFORMATION lpProcessInformation);
}
"@
 
    $si = New-Object STARTUPINFO
    $pi = New-Object PROCESS_INFORMATION
 
    $si.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($si)
    $si.wShowWindow = [ShowWindow]::SW_SHOWNOACTIVATE
    $si.dwFlags = [STARTF]::STARTF_USESHOWWINDOW
 
    $pSec = New-Object SECURITY_ATTRIBUTES
    $tSec = New-Object SECURITY_ATTRIBUTES
    $pSec.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($pSec)
    $tSec.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($tSec)
 
    [Kernel32]::CreateProcess($FilePath, $Arguments, [ref] $pSec, [ref] $tSec, $false, [CreationFlags]::CREATE_NEW_CONSOLE, [IntPtr]::Zero, (pwd | select -exp Path), [ref] $si, [ref] $pi)
 
    #[System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
}
August 17, 2013

On switching to Android from Windows Phone

About a month ago I purchased a Galaxy S4 Android smartphone to replace my Lumia 920 Windows Phone. I didn’t take this decision lightly, and I do very much have a vested interest in seeing Windows Phone succeed in the marketplace. I feel I’ve gained quite a lot of perspective in the past few weeks after making this switch, and I’ve invested significant time in using the operating system and some of the different applications which it has to offer, especially focused on power user scenarios. While my reaction was initially very positive (as with many gadgets), over time I’ve come to a more balanced feeling on both platforms.

First, I’ll give a little background so you can understand where I’m coming from in terms of different platforms. I primarily use Windows on all devices, and I tend to avoid Google services with the exception of Maps/Search. I used to be a heavy Gmail user but switched to Office 365 last year after the Gmail web interface changed and became cumbersome. I’ve been using a smartphone since 2006, when I switched from a Motorola Razr to a Samsung Blackjack (Windows Mobile 6). Since then I’ve owned the following phones: iPhone, iPhone 3G, iPhone 4, Samsung Focus (WP7), HTC Titan (WP7), Lumia 920 (WP8), and now the Galaxy S4. I was exceedingly enthusiastic about the original iPhone and admittedly felt a sense of withdrawal when switching out of the Apple ecosystem and onto the first Windows Phone. I do not have adequate perspective on iOS versions higher than 4, so I won’t make too many corollaries to that ecosystem.

While I had briefly used Android phones running version 2.2/2.3, I did not feel that they provided a good enough experience to consider as a platform worth using every day. It’s important to me that the phone be quick and reliable, though I also did find that Android 2.x was not very attractive as well. Task killers and other such management software were seemingly required in the 2.x days, though I do realize that some asserted they were not necessary even at that point in time. It is irrelevant however, as I primarily felt that the UX was just not quick enough to prevent frustration with simple interface manipulation. Hardware-wise, I did find many Android smartphones to be acceptable. Many complain that only the iPhone “feels right” or other such vague complaints, but I have found the vast majority of mainstream phones to have a good physical feel and acceptable size/weight/etc. characteristics.

While I still like and appreciate the design of the Windows Phone software, I became increasingly frustrated with my Lumia 920 throughout the 6 months in which it was the only device that I carried. First and foremost, I found that the hardware design was simply fair. The body of the phone is sturdy, but I always find that gripping the device is challenging. The phone simply does not “stick” to my hand, and this was frequently frustrating as there was concern that it’d drop onto the ground. This problem actually plagued the original iPhone, and was corrected in the 3G edition, but was since undone in later versions as well. Perhaps I have different standards or there are other factors at play, but I simply felt that the phone was hard to hold confidently.

Software-wise, I found that while Windows Phone is very polished, it did not always enable me to get things done quickly or to execute long-running tasks. The system is designed around apps having very little say in when they execute and when they are suspended. In many ways this truly is advantageous, I can have complete confidence that when I turn off the screen and place the phone into my pocket, nothing is running and nothing is draining my battery. Some tasks can complete once the application has been closed, such as ongoing music or background upload/download. This is helpful and certainly these are necessary contracts, but there is another user confidence issue that comes about with selectively executing programs in the background. The issue is that when only certain tasks can complete after leaving the app, the user cannot predict which tasks will and will not be broken by switching away from the running application. There is even a second issue in that while applications can run “under” the lock screen, they will prompt to do so only once, and the application itself must decide whether or not running under the lock screen is necessary. Since the prompt only occurs once and I find myself to be fickle about allowing permissions without first understanding the ramifications, it’s unclear what the app will do when the screen is shut off. I’m not yet making a judgment call on which user confidence issue is worth addressing, but merely calling out that both approaches have a confidence problem that is to be reconciled or ignored.

After visiting a friend back home and briefly playing with his GS4, I was pretty blown away seeing the slickness of both the hardware and the system software. After doing a little research and determining that the S4 was currently best-in-class, I took the plunge and ordered one online. At the same time, I did some research on accessories (just for kicks initially), and also ordered a USB cable (to provide a full-sized USB port on the phone), and HDMI cable, and a Qi wireless charging adapter that fits snugly inside the phone. These accessories are hardly necessary but I wanted to see how powerful this platform could be, and all together it was pretty inexpensive.

The stock system software on the at&t GS4 works nicely. I did not have any serious problems with the included value-add apps, though most of them were ignored as they didn’t add value to the experience I wanted or the things I used the phone for. Samsung has included a number of “Smart”-branded features, all of which I found gimmicky and ultimately not useful. Actually, I was unable to even get the vast majority to work at all. Ultimately using your hand to scroll the phone is unlikely to be useful in all but the most contrived use cases. I did find it interesting how much of the tech journalism surrounding these features amounted to “These things don’t really work, but ‘A for effort’ anyway.” Regardless, they can all be switched off and fundamentally did not degrade the user experience. The one feature that I did appreciate (having since switched to Cyanogenmod) was the ability to run multiple apps on the screen at the same time. For those of us who want to use our phones more like a powerful pocket computer than a temporary view into our world, that’s a breath of fresh air. It wasn’t perfect and was actually a little bit confusing to set up, but it is a solid value-add.

After recognizing how much Samsung had changed Android (with TouchWiz), I wanted to take a look at what a Google experience looked like. I have a lot of respect for the engineering work going on at Google, so I did (and continue to) believe that their experience would be better. After surfing XDA and building a list of ROMs I wanted to try out, I was able to install 4 or 5 of them before arriving at a “pure Google” ROM and then finally Cyanogenmod. My opinion is that the vast majority of ROMs are unstable and broken in some way—I would not bother with them again, but Cyanogenmod has very high quality. The “pure Google” ROM was also very good, though Cyanogenmod has a number of options which I would not like to give up (for example, the built-in LED notification light configuration options). One caveat with the current Cyanogenmod build I’m using is that Miracast (Wireless Display) is no longer functional. This is disappointing but is something I can live with, other ROMs had major performance/battery problems or unworkable USB MTP mode, which is unacceptable.

Having settled on a ROM and installed many of my favorite apps, I turned my focus to organizing them. I’m not fond of the launcher choices on Android. Both the default launcher (Trebuchet) and popular third party ones (Nova, ADW, etc.) do not offer anything more than a surface to pin widgets, and a grid of icons. There is a high level of customization in terms of how folders work, the number of rows/columns and the orientation of pages, but fundamentally they feel like a different take on the same experience. I’m not proud to say that ultimately I have settled on Launcher8, which is a Windows Phone 8 Start screen imitation. Launcher8 is not without bugs, and due to my widget configuration UI lag is introduced, but I found it to be the only workable launching surface. Without having a grid system to align widgets to, they do not fit together well and are simply not visually pleasing. Many are confused when I attempt to explain this, but after assembling many information sources into compatible widgets, I simply found that a grid of icons with widgets mashed in didn’t provide an appropriate amount of information density. Again, I’m not happy that the WP8 imitation was the only workable solution, as my intent was never to make my Android phone look like a Windows Phone. It is however telling of the platform that I’m able to take one of the best features from a competitor and successfully make my experience whole. Furthermore, I found that the “app drawer” with pagination was unwieldy and hard to scan. Nova and other launchers thankfully support a one-dimensional list of apps, which Launcher8 also supports. Perhaps I’m just stuck in the Windows Phone design philosophy at this point, but I continue to feel that scanning discrete pages of apps is not a great experience on mobile devices.

I’ve found that many of the mainstream apps on Android are quite striking, with good UI design and great attention to the details. Twitter is beautiful and slick, taking many design cues from other platforms to create a really top-notch app. Some apps, like myAT&T still use the Android 2.x visuals, which are pretty displeasing, but the app itself is fully functional and it isn’t a much of a problem. In general the lack of consistency on Android is still very much prevalent, but I found that while the UI might be unexpected, it’s always easy to use and straightforward. When it comes to the UX of the device, the most striking thing I’ve found consistency-wise is how often the device will throw out technical jargon. I certainly do appreciate a device that puts me in control, though I wonder how workable this can be for the masses. I know many real people that find Android confusing, so I think the problem should not be understated, but the mainstream parts of the system work really well and are straightforward. Sometimes there is too much chrome, but often there is just the right amount to understand the context and next steps, which is appreciated.

One of the most interesting apps on Android that I’ve used is called Tasker. Tasker allows you to configure specific profiles based on contexts which the phone can monitor. For example the AC power charging state of the device, geographical location, events like “screen on” and so much more. These triggers can be used to launch tasks, which can in turn change state on the device, call web services, set variables, or update widgets (with the help of Minimalistic Text). Tasker is incredibly powerful and amazingly it is pretty straightforward to use given how much power it offers. I very much appreciate that I can set up a profile that says “if I’m near work, mute my phone” and “if I’m at home, turn the sounds on.” This example may seem trivial, and it actually is, but this is only scratching the surface of what is possible. Another profile I have set is “alarm done” which will use Text-to-Speech after calling a web service and give me a “morning briefing” with news and weather after my alarms is silenced. I could live without all of this, but again I appreciate the power this offers. For me, this is a platform differentiator.

My biggest complaint with Android is the email situation, specifically Exchange. I’ve tried just about every EAS/MAPI app in the Play Store, and found them all to be absolutely unacceptable. Either the UI is clunky or some key feature is completely missing. Initially I rejected Google’s built-in Email app because it enforced whole-device encryption, but after circling back through all of the other options, I’ve found that Google’s app is by far the best. This is a severe disappointment and regression from Windows Phone, where email is powerful and a joy to use. Note that I have no opinion on the Gmail app, since I no longer use nor want to use Gmail. I do suspect however that the Gmail app is a much better experience.

Additionally I feel that I can no longer have true confidence in my phone. It’s not that Android has failed me very many times, but I just have a hard time trusting it to be there in the way that I was always able to trust my iPhone or Windows Phone. While traveling across the country last week I took pause and also took along my Windows Phone, just in case. Thankfully I didn’t need it but it’s just hard to shake the feeling that the software on this device might just implode one day. Android provides you all the power to shoot yourself in the foot if you like (which, again, I do appreciate). Once I accidentally disabled the startup entry for the Alarms app, but that was completely my fault. Right now I see a random reboot roughly once per week, which is not great but most devices I’ve owned would reboot out of the blue at some semi-frequent pace. I’ll call that acceptable until it happens while I’m trying to answer a call. :)

I’m sticking with Android for now, but I’m still open to see what the next version of Windows Phone offers, and even iPhone if a large-screen variant comes into existence.

If you liked this post, you may also like Platform evolution in the mobile age

August 17, 2013

Programmatically update the mouse cursors with PowerShell

After updating the mouse cursors at HKEY_CURRENT_USER\Control Panel\Cursors, the system will not automatically reload them, it must be instructed to do so.  With the below PowerShell function, the system will reload the cursors and the changes made in the registry will be immediately reflected.

 
function Update-Cursors {
    add-type -MemberDefinition @"
[DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, uint pvParam, uint fWinIni);
 
const int SPI_SETCURSORS = 0x0057; 
const int SPIF_UPDATEINIFILE = 0x01; 
const int SPIF_SENDCHANGE = 0x02;
 
public static void UpdateCursors() {
    SystemParametersInfo(SPI_SETCURSORS, 0, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
}
"@ -Name CursorSPI -Namespace Temp
 
    [Temp.CursorSPI]::UpdateCursors()
 
}
August 17, 2013

Create a shortcut from PowerShell

To create a shortcut in PowerShell, the WScript.Shell COM object has a simple method (with additional properties not shown), which makes creating shortcuts programmatically simple.  Below are a couple of examples, New-FavoriteShortcut will create a shortcut on the left pane of the File Explorer, for quick access to folders, applications and documents.

function New-Shortcut($TargetPath, $ShortcutPath) {
    $WshShell = New-Object -comObject WScript.Shell
    $Shortcut = $WshShell.CreateShortcut($ShortcutPath)
    $Shortcut.TargetPath = $TargetPath
    $Shortcut.Save()
}
 
function New-FavoriteShortcut($TargetPath, $DisplayName) {
    $WshShell = New-Object -comObject WScript.Shell
    $Shortcut = $WshShell.CreateShortcut("$env:USERPROFILE\Links\$DisplayName.lnk")
    $Shortcut.TargetPath = $TargetPath
    $Shortcut.Save()
}
August 17, 2013

Reset the per-application volume preferences on Windows

Sometimes after messing with the per-application volume settings on Windows, you might find yourself wishing you could easily just reset all of them.  The UI can be tricky to get all of the volume sliders back up to 100%, so running these commands from an elevated command window is quite a bit easier.

NET STOP Audiosrv
NET STOP AudioEndpointBuilder
REG DELETE "HKCU\Software\Microsoft\Internet Explorer\LowRegistry\Audio\PolicyConfig\PropertyStore" /F
REG ADD "HKCU\Software\Microsoft\Internet Explorer\LowRegistry\Audio\PolicyConfig\PropertyStore"
NET START Audiosrv
August 17, 2013

WinUser.h constants in PowerShell

For those doing P/Invoke from PowerShell often, winuser.h is often necessary to find constants.

I ran a regex over the Windows 8.0 SDK winuser.h, and removed the macros that couldn’t be easily translated.  The result is a ps1 file that can be loaded into the global scope and then many oft-used constants are easily accessible.

The file is large, so download it here (save-as).

August 17, 2013

Use PowerShell to click a point on the screen reapeatedly

Here’s an auto-clicker script I’ve been sitting on for a while, which often comes in handy unexpectedly for all kinds of quick and dirty repetitive tasks.

To use it, move the mouse to the point on the screen where the click is desired, and then use the keyboard to start the script in a PowerShell window.  To stop the clicking, press the Windows key on the keyboard.  Note that this requires Windows 8 and will not work on Windows 7 or below.

Interval between clicks, Left/Right button and the ability to set “move to point before clicking” are supported.

[CmdletBinding()]
param($Interval = 5000, [switch]$RightClick, [switch]$NoMove)
 
[Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null
$DebugViewWindow_TypeDef = @'
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string ClassName, string Title);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out System.Drawing.Point pt);
 
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
 
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
 
public static void LeftClick(){
    mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
 
public static void RightClick(){
    mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
}
'@
Add-Type -MemberDefinition $DebugViewWindow_TypeDef -Namespace AutoClicker -Name Temp -ReferencedAssemblies System.Drawing
 
$pt = New-Object System.Drawing.Point
if ([AutoClicker.Temp]::GetCursorPos([ref]$pt)) {
    Write-host "Clicking at $($pt.X), $($pt.Y) every ${Interval}ms until Ctrl^C or " -NoNewline
    Write-Host -ForegroundColor Cyan "Start " -NoNewline
    Write-Host "is open."
    while($true) {
        $start = [AutoClicker.Temp]::FindWindow("ImmersiveLauncher", "Start menu")
        $fg = [AutoClicker.Temp]::GetForegroundWindow()
 
        if ($start -eq $fg) { 
            Write-Host "Start opened. Exiting"
            return 
        }
 
        if (!$NoMove) {
            [AutoClicker.Temp]::SetCursorPos($pt.X, $pt.Y) | Out-Null
        }
 
        if ($RightClick) {
            [AutoClicker.Temp]::RightClick()
        } else {
            [AutoClicker.Temp]::LeftClick()
        }
        sleep -Milliseconds $Interval
    }
}
August 17, 2013

Platform evolution in the mobile age

The notion of a platform has evolved dramatically since the popularity of networked computing in the 1990s. What was once a set of low-level services for discrete applications and experiences is now a high-level service and managing infrastructure for applications and their interactions. Where the platform and the applications running within it were a monolithic entity, the platform is now a service provided to the user which promises consistency and stability. Where applications once could interact with each other freely (sometimes with unexpected outcomes), modern platforms now tightly control how these applications interact with the system, the user, and each other. iOS 1.0 in 2007 marked the beginning of this new era, though there are certainly many examples of earlier platforms with similarities. For better or worse, this model has been emulated across the industry to varying degrees. As with any generational change, there are definite pros and cons with each model.

In many ways, this change was inevitable and driven by the commoditization of software, the transition from “application” to “app”—from an expensive, powerful piece of software to the bite-sized counterpart, usually leveraging web services to do heavy lifting or interact with other devices and software. Where desktop computers in the 90’s would have only several expensive software suites, our mobile devices today have hundreds of apps, many free or very low cost. Software that was once purchased in a box at a brick-and-mortar store and installed in minutes or hours, is now purchased (or not) over the internet, downloaded wirelessly, and installed in seconds. The cost of app acquisition is low and the number available is vast. Of course this leads to devices with many different applications, with varying purpose, interacting with the system, each other, and the user.

The trust model has also changed due to the globalization and decentralization of the industry. Anything that could once be purchased in a brick-and-mortar store would have a big company name behind it, with an implicit assurance of accountability. Today, any independent developer located anywhere around the globe can build an app and submit it to a store, where users can download it instantly. There is a still chain of accountability, but it isn’t nearly as strong as the old model.

The cost to develop software used to be astronomical, requiring thousands of dollars of hardware, books, potentially training, a high level of technical proficiency, and a very in-depth of understanding of the operating system. Modern programming languages and frameworks have removed much of the complexity in working with the system (even if the capabilities remain roughly as powerful), and modern hardware is inexpensive. With a search engine and the open web, training is free or unnecessary. The barrier to entry is substantially reduced along a number of dimensions; a dramatic reduction in cost to design, implement, and distribute software has occurred with the advent of centrally managed online stores (usually but not always by the platform vendor). There are also more developers than ever, producing more applications or varying quality and relative completeness. Due to this aspect, there may often exist many duplicate options and it isn’t immediately clear which one is best, or the best fit for a given user. This leads to the situation where the user will install many different options, removing (or not removing) all but the one deemed best. Platforms now more than ever must to be robust to frequent app installation and uninstallation operations, not leaving any extra files or registrations behind.

But with these new platform paradigms and restrictions, how can developers continue to innovate in novel ways? Sometimes the new paradigms can be beneficial to building new experiences and helping users complete tasks faster than ever. But sometimes, the killer app can’t be written because to do so would require the developer to violate the inherent laws programmed in by the platform vendor. Some examples of modern laws (commonly referred to as sandboxing) can be:

  • The app shall not interact with other apps on the system except through explicitly defined contracts (like protocol associations, so http:// can invoke Safari with a URL provided by another application)
  • The app shall not execute code when the app is not in the foreground.
  • The app shall not access personal data without consent from the user.

iOS 1.0 quickly gave rise to the concept of jailbreaking, which is modifying the software on the device to allow the user to violate the laws defined by the platform vendor. Geeks rejoiced as a powerful platform could again be used freely and without respect for the inherent laws defined by the vendor. But to jailbreak is also to remove some of the value proposition which led to the vendor to implement the laws in the first place. Without the vendor laws, apps can drain the battery or access data on the phone which the user hasn’t explicitly allowed (contacts, calendar, text messages, other personal information, etc.) Is it necessary that one (be it a user or a platform vendor) must decide between novel innovation on top of a flexible platform or novel innovation baked only into the platform?

With these modern platforms comes a realization that innovation is centralized by the platform vendor. Both updates to the platform itself and the laws are delivered explicitly by the vendor with no actual feedback from individual developers who build on top of the platform. Due to this, the vendor is now the single entity which needs to decide whether or not a feature or capability is “worthwhile.” This is done effectively inside a vacuum where ideas are considered worth addressing or not. It’s true that major platform vendors do have some of the most talented engineers and thinkers of our time, but the harsh reality is that these people will not have the perspective to understand the full breadth of possible innovation. Decisions are made that intentionally or unintentionally disallow certain kinds of experiences to be created. There are of course always good reasons for these decisions, be them technical or otherwise, but fundamentally it restricts the ability of developers to innovate on top of the platform.

The fact of the matter is that the entrepreneurial spirit of humans will always lead to great ideas that would not be funded by a committee. The true spirit of innovation is seeing the possibilities and designing outside of the box. How can this remain possible on a platform that doesn’t offer flexibility to developers? And how can a single entity (the vendor) take responsibility for the majority of the innovation? How could a single entity remain competitive and consistently innovate over time? The numbers don’t work, there will always be more people thinking creatively on the outside than those on the inside. The web was able to succeed and evolve due to the flexibility offered by the web standards and the platforms that browser vendors built on top of the browser itself. There are thriving extension ecosystems on top of each major browser which supports javascript-based extensions. These extensions vary in quality but each offer a unique experience and perspective on top of the browsing experience. Without an extension model, these browsers would offer less value to their users at each level of the skill ladder.

Ultimately it is unclear what impact these new platforms will have on general-purpose computing. While actual “general purpose” machines are moving to the wayside in many consumer scenarios, the tasks which users complete are still diverse and likely will remain diverse moving forward. Successful closed systems have existed and will continue to do so—for example game consoles—but these systems are often designed for unitasking and the inability to innovate cross-task is less critical to the user. On a gaming console the game itself has full authority to draw to the entire screen and consume hardware resources as needed, so innovation in many relevant ways is still possible. True, there could still be room for innovation to occur with games running resident services and perhaps making changes to the dashboard/launcher and beyond. Fundamentally if given access to resources, creative developers will leverage the capabilities in interesting ways.

I don’t condone those who don’t want to move forward, but I do feel that the restricted future is a potential centralization of authority that could lead to stagnation on popular platforms. Over the past decade we’ve seen the decentralization of software across the industry benefit users and developers alike, but the pendulum is seemingly swinging back toward tightly controlled platforms. It’s important that we find balance and enable innovation both within and on top of platforms.

August 17, 2013

Programmatically open RegEdit to a specific registry path

Here’s a quick PowerShell script to open RegEdit navigated to a specific path in the registry.  This can be handy as sometimes you are given a path but would like to explore/view/modify it in the RegEdit GUI.

We take advantage of the LastKey value to specify the location RegEdit should navigate to when opened, and then start a new instance of RegEdit using the -m switch to bypass the default single-instance behavior.  Without the -m switch, a currently-opened RegEdit will be focused, and the navigation will not occur.

[cmdletbinding()]
param($Key)
 
$Replacements = @{':'='' # Remove PowerShell syntax
                  'HKCU'='HKEY_CURRENT_USER'
                  'HKLM'='HKEY_LOCAL_MACHINE'
                  'HKU'='HKEY_USERS'
                  'HKCC'='HKEY_CURRENT_CONFIG'
                  'HKCR'='HKEY_CLASSES_ROOT'}
$Replacements.Keys | % {
    $key = $key.ToUpperInvariant().Replace($_, $Replacements[$_])
}
Write-Verbose "Open $Key"
sp HKCU:\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\ -Name LastKey -Value $Key -Force
regedit -m # Open new instance

Paste the above into Open-RegEdit.ps1.  Use it as such:

PS> .\Open-RegEdit.ps1 hkcu:\Software\ODBC -Verbose
VERBOSE: Open HKEY_CURRENT_USER\SOFTWARE\ODBC

And RegEdit will open at the desired location.

May 25, 2013

GVAutoResponder will no longer receive software updates

This mail went out to all GVAutoResponder users today.

From: David Amenta
Subject: GVAutoResponder will no longer receive software updates

Dear GVAutoResponder user,

I no longer have the bandwidth to properly support this product, so effective immediately GVAutoResponder is discontinued and will not receive any future updates.  The software will continue to work as-is indefinitely, until Google makes an API change which breaks the software.  When a breaking Google Voice API change occurs, I will not issue an update to resolve it.  Please understand that the support burden for maintaining this software far outweighs the value it generates for me, and this burden is in direct odds with my professional duties and goals.  I’ve done my best to respond swiftly as the API surface this software is built on has changed over the years, but no longer can I commit to that level of support.

Please work to ensure that you are not interrupted at that time.  I recommend http://www.twilio.com/ which has low rates on sending SMS messages, and similar software can be built cheaply on their platform.  For those that push Google Voice to the limit, a full API will be a breath of fresh air.

Thank you, I truly apologize for the inconvenience this causes you.

Dave

May 9, 2013