Sunday, April 30, 2017

Export-WindowsImage preserves ESD format

Today I was converting an ESD file to a WIM so I could poke around inside it. Since I was in a PowerShell prompt, I figured I'd use the fancy DISM cmdlets instead of running the DISM executable. So I used Export-WindowsImage to extract the image of interest from the ESD. But when I tried to mount it with Mount-WindowsImage or with the appropriate switch of dism.exe, I got the error "an attempt was made to load a program with an incorrect format."

Strangely, using the export feature of the DISM program created a WIM that could be mounted successfully with either method. I conclude that the PowerShell cmdlet made another ESD file instead of a WIM (despite me giving it a file path ending with .wim), which can't be mounted directly.

Saturday, April 29, 2017

Google Analytics not getting hits despite the script being there? Check the encoding

A while back, I tinkered with Google Analytics for one of my web sites. I put the JavaScript fragment they gave me into the right place in the HTML, but no matter how I finagled it, Google said the property was missing its tracking code.

More recently, I had a similarly bizarre problem with reCaptcha. Eventually I figured out that the encoding of the HTML file was UTF-16LE, but changing it to UTF-8 made reCaptcha load. I checked today and Google Analytics is now working on that site as well. The encoding issue somehow caused the load of all external scripts to fail.

Friday, April 28, 2017

Watching for new processes with PowerShell

Suppose you want a PowerShell script to watch for new processes and do something when one starts. You can do something like this:

$query = New-Object System.Management.WqlEventQuery ("__InstanceCreationEvent", (New-Object TimeSpan (0, 0, 1)), 'TargetInstance isa "Win32_Process"')
$watcher = New-Object System.Management.ManagementEventWatcher
$watcher.Query = $query
$watcher.Options.Timeout = [System.Management.ManagementOptions]::InfiniteTimeout
While ($true) {
    $evt = $watcher.WaitForNextEvent()
    # Do something about $evt
}

That script uses WMI to monitor for the creation of new process objects, with a timer resolution of one second, so you'll see all processes that live longer than a second. You can use the TargetInstance property on $evt to get information on the actual process.

Thursday, April 27, 2017

Starting programs with quoted arguments from a PowerShell subprocess may take a lot of quoting

One user wanted to launch an elevated (but not as the current user) MMC window with a certain console file whose path contains spaces. Their strategy was to use PowerShell to launch a PowerShell process as a different user that then ran MMC with administrative privilege and the target console file. The problem was that MMC couldn't open the file because the part of the path after the space got cut off; the quoting didn't help.

I don't know all the rules for escaping, so my first strategy was to just keep adding extra quotes to escape the existing quotes. That eventually worked, but it took nine quote characters on each side of the argument, instead of the three that the question author had tried.

start-process powershell 'start-process mmc.exe """""""""c:\administrative tool\console1.msc""""""""" -verb runas' -credential domain\user

Wednesday, April 26, 2017

When JavaScript files mysteriously fail to load only on some HTML pages

I've been trying to get a contact form onto one of my web sites, and since I would prefer that my e-mail not be flooded with spam, I added reCaptcha to the page. It was very easy to set up, and it worked as intended when testing on my local IIS server as an ASPX page.

My web host, however, does not support ASP.NET, so I have a script that converts a master page plus loose ASPX files into HTML files. I found that the reCaptcha control simply did not appear on the web host, nor did it appear when opening the local HTML file. It didn't even work when I copy-pasted the entire client HTML from the working ASPX page over the contents of the HTML file. It reported a SyntaxError on the first line of Google's script. This happened the same in all browsers I checked.

After being 100% baffled for hours, I finally noticed a tiny, tiny difference between working and non-working documents: the "encoding" status bar field in Notepad++. The working ASPX document was UTF-8; the non-working HTML files were UTF-16LE. Copying the working markup from IIS didn't have an effect because I pasted it into an already-UTF-16LE document instead of making a new file and saving over the old. Once I re-encoded the HTML file and saved, reCaptcha showed up.

I adjusted the script to produce UTF-8 files with the -Encoding parameter on Out-File.

Tuesday, April 25, 2017

Policy Plus - Creators Update ADMX files

Microsoft released the 1703 update to Windows 10 (the Creators Update) recently, and it includes a handful of new Group Policy settings. Therefore, there are new ADMX files, and Policy Plus needs to be able to download them.

So a few days ago, I went hunting for the official download page (I think that's the one, but the site is unavailable at the moment, so I can't check). Then I found the link to download the MSI directly and updated the Acquire ADMX Files feature to use that one. Fortunately, the MSI has the exact same folder structure inside it; all I had to do was change the download URL.

The change is live on GitHub.

Sunday, April 23, 2017

20K on Super User

When I woke up this morning, I found a series of inbox notifications of people congratulating me on reaching 20,000 reputation on Super User. I had been making slow progress from 19K to 20K due to real life obligations, but I just inched past that line sometime during the night, by two points! Since I'm right on the edge, it's possible that I could briefly dip back down, but since I will continue to participate, I expect to keep ascending.


I am the 72nd user to reach this milestone.

Wednesday, April 19, 2017

Copying a directory structure with symbolic links

Suppose you have a big folder structure with some directory symbolic links referring to other parts of the structure. You want to copy this whole arrangement such that the symbolic links in the new structure refer to the corresponding new folders, as opposed to blindly duplicating the link. As far as I can tell, there isn't a convenient way to do that.

So today, I wrote a fairly short but somewhat tricky script in PowerShell to do the job. It takes the source folder and the destination (which should already exist but be empty), recursively copying all the real files and folders first, then creating new symbolic links with adjusted target paths. This was made dramatically easier by PowerShell's ability to manage symlinks with the New-Item cmdlet and the Target property on file system objects.

Tuesday, April 18, 2017

What controls the list of characters that stop Ctrl+Arrow movements?

In most Windows text fields, you can hold Control while pressing left or right to advance by a word instead of by a single character. Not all non-alphanumeric characters break up words, though. For example, the plus sign is a separator but the underscore is not.

This separation, as well as word wrapping, is managed by the text box's word-breaking procedure, a Win32 function. Windows supplies the one used by most text boxes, but applications can use the EM_SETWORDBREAKPROC window message to make an edit control use a different one. Therefore, if you want to change either of those features, you'd need to write a program that injects itself into each running application and changes the work-break procedure to one of your choosing.

Based on my Super User answer.

Sunday, April 16, 2017

Partially defining an ASP.NET page's title in a ContentPlaceHolder

I've recently been working on an ASP.NET web site that has a bunch of pages using a master page as a template. For the sake of deduplication, I'd prefer to put the site's name inside the <title> tag in the master but also allow specific pages to specify their titles. I tried this:

<head runat="server"><title>My Site - <asp:ContentPlaceHolder runat="server" ID="title"></asp:ContentPlaceHolder></title></head>

Then in an individual page, I had this:

<asp:Content ID="Content1" ContentPlaceHolderID="title" Runat="Server">Neat Page</asp:Content>

The goal was to get "My Site - Neat Page" showing as the title for that page. Alas, I got only "Neat Page".

Strangely, ASP.NET isn't really a fan of loose text inside <title> when there's a server-side control there too. The solution is to wrap the literal text in, well, a literal:

<head runat="server"><title><asp:Literal runat="server">My Site - </asp:Literal><asp:ContentPlaceHolder runat="server" ID="title"></asp:ContentPlaceHolder></title></head>

Now each page gets the site name and its own name merged together.

Saturday, April 15, 2017

Windows can be like f.lux now

While poking around my display settings after the Windows 10 1703 update, I saw a new Night light entry. Like f.lux, it allows you to set a different color temperature for dark hours. I appreciate that being an OS feature, since every application that runs on startup is another delay between booting and working. It will only detect your sunset time if location services are on, but when I turned them on, it did not seem to determine my daylight hours. For now, I have the hours manually set. Strangely, my two identical monitors now show the same color quite differently. I'll see how this goes for a few days; there's always f.lux again if Windows doesn't handle it as I'd like.

Friday, April 14, 2017

New Windows builds break dark f.lux settings

I updated to Windows 10 1703 (Creators Update) yesterday, and tonight I noticed that my screen suddenly increased in brightness sometime after sunset. I use f.lux (which is great) to alter the color temperature of the screen at night. When I first installed it, it needed administrative permission to unlock the very low color temperatures, like Dim Incandescent, my preferred night level. Looking in the color temperature menu, I saw that the low levels were grayed out once again; it needed my permission to unlock them. Evidently, something about the Windows update process undoes the administrative action that allows the use of extreme color temperatures.

services.msc might not show the effective state if Registry tweaking is in play

A user had written a script to tweak the Registry in a way that changes a service's start type to Manual. When they tried to start it, though, net gave the spiel about it being disabled (or one of its required devices being disabled). The Services MMC snap-in reported the new start type, so it looked like the Registry change did the job.

I did some investigation and found that a once-disabled now-enabled service won't actually start unless it's reconfigured the supported way. services.msc somehow knows about the Registry-tweaked state, but the Service Control Manager isn't fully in on the joke. Since the question author was writing a batch script, sc does the job.

Wednesday, April 12, 2017

Switchable door destinations in Keen Galaxy

In Keen 4-6, switches can extend or reduce the range of moving platforms. Internally, this works by inserting or removing the infoplane value that renders as a B block in level editors. The switch-flipping routine first checks whether there's a pathing arrow (by testing the tile ID range), and if there isn't one, it just XOR's the current infoplane value with 0x1F, the ID of the B block. When that happens on a link value, it has the effect of flipping the last five bits of the Y coordinate.

Therefore, it's possible to change a door's destination with an infoplane switch, but only vertically and only to certain Y coordinates. Somewhere online, there used to be a neat guide on setting this up, but it appears to have been lost and I cannot find an archived copy. I might write a full new one sometime.

Tuesday, April 11, 2017

Some file associations are not controlled by the usual place

Yesterday, I mentioned that file associations are managed by data accessible under HKEY_CLASSES_ROOT. A few extensions, though, get special treatment because programs really liked to mess with them instead of letting the user choose. Those can be found here:

HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts

Protected types have a UserChoice subkey with the file type ID and a hash. The hash is likely there to throw another roadblock up against developers of would-be poorly behaved applications.

On my main machine, the usual file association Registry entries associate .html with htmlfile (Internet Explorer), but the UserChoice subkey provides the real value: ChromeHTML.

Monday, April 10, 2017

Windows surprise: assoc utility doesn't look at per-user settings

Today I was investigating how file associations work, and I discovered an interesting product of the interaction between the assoc utility and the HKEY_CLASSES_ROOT view. HKCR is actually a merged view onto two different Registry branches, one per-user and one that applies to the machine. User settings take precedence. Explorer looks at HKCR (including per-user settings) to get the current file associations, but the assoc utility seems to operate only on the machine section.

Therefore, it's entirely possible to see a different result on the command line than is actually in effect. On my laptop, the utility says that the association for .html files is htmlfile, but for programs running as me, the association is ChromeHTML. (Note that there isn't a direct mapping of extensions to handlers; the extension is associated with a file type, which sets the handling command line.)

Sunday, April 9, 2017

WiFi connected but network not reachable? Reboot the access point

I recently dealt with a computer that couldn't reach the network while connected to a WiFi network. All the other machines around were working perfectly fine, but this one couldn't even get an address from DHCP. Rebooting and resetting the WiFi adapter did nothing. Eventually, I logged on to the web management panel of the Linksys LAPN600 access point to check for connections. The machine was there, and all access point settings looked right. I noticed that the device wanted a firmware update, so I had it install that, and in the process it rebooted. When it came back up, the problem was fixed. I'm not sure exactly what happens to APs after long uptimes, but apparently sometimes reboots are helpful.

Saturday, April 8, 2017

Policy Plus meets the world

Today I showed Policy Plus at my school's Tech Fair. There were a total of sixteen projects presented there, from students of all grade levels. One judge looked at programming and 3D art projects, while the other judge looked at everything else. When my time came, I demonstrated as many aspects of the application as possible while also making sure to briefly look at my non-program materials (FAQ document and outline of the standard workflow).

I also gave a brief edition of my spiel to various other people attending the event. A few seemed fairly impressed; one even planned to download and see about using it. In my spare time, I looked at some other projects. I was pleasantly surprised by their quality.

When I received my project's evaluation sheet, I was pleased to see that the judge wasn't very concerned about comments. The code file I showed (PolicyProcessing.vb, my personal favorite) only had short summaries of each chunk's purpose, but the comments rubric entry had the highest state circled, as did the rest of the relevant entries. My project earned one of ten slots to proceed to the regional version of this event.

Friday, April 7, 2017

Policy Plus - Sprinkle comments everywhere

The Tech Fair that I'm presenting Policy Plus at tomorrow wants all the programs to have commented code. I hadn't been commenting unless there was something weird going on that I would need a note to understand, so there were very few comments. So today, I went through and sprinkled comments everywhere explaining why each section is there. It's not nearly "understandable by a non-programmer" as the Fair seems to want, but that's to be expected.

I also put the two helpful documents (the lexicon and listing of components) in the GitHub repository; all these changes are live.

Thursday, April 6, 2017

How do programs create enormous temporary files so quickly?

Somebody wondered how Photoshop manages to create a 2GB temporary file immediately upon startup with virtually none of the disk thrashing one would expect from writing out gigabytes. The Windows function for doing that is SetEndOfFile, which sets the length of the file to the current position. That function updates the file metadata with the new length and commits the physical space on the disk, but the space is not zeroed out until data is written beyond the valid data length (which is not changed by this function).

For paging-esque storage, this method is to be preferred over sparse files, which do not commit the space ahead of time and therefore could produce out-of-disk-space errors in the middle of something important.

Wednesday, April 5, 2017

PowerShell bot for Stack Exchange chat

Some chat rooms on the Stack Exchange network have bots that post predefined messages in response to certain triggers. (A surprisingly high proportion of these resources are links to adorable cat pictures.) As a fun challenge for myself, I tried to write one such bot in PowerShell, and successfully made something functional though minimal. It's on GitHub.

I made sure to not use any parts that require Internet Explorer components, so the script works fine on non-Windows OSes. The few HTML parsings that need to be done are handled by regex.

Sunday, April 2, 2017

Converting ESD to WIM

Today I needed to deploy a Windows 10 image downloaded with the Media Creation Tool to a machine. Lacking a flash drive large enough to hold the ISO, I tried to use Windows Deployment Services. Unfortunately, the install image inside the ISO was in ESD format, not WIM, and therefore incompatible with WDS. Last time I hit this problem, I downloaded an Enterprise version from TechNet (which does include a WIM) because the only ESD conversion solution I could find involved a rather sketchy third-party utility.

Today, though, I found a wonderfully easy method that uses only Microsoft utilities. Once I extracted install.esd, this command did the job:
dism /export-image /SourceImageFile:install.esd /SourceIndex:1 /DestinationImageFile:install.wim /Compress:max /CheckIntegrity

The integrity-checking flag might not be strictly necessary. If the ESD holds multiple images (as mine did), DISM can list them and their indexes with:

dism /get-wiminfo /wimfile:install.esd

Note that older OSes' versions of DISM might not have the functionality needed for these commands to work. For example, Windows 7's doesn't seem to have /export-image. I tested these on Windows 10.

Saturday, April 1, 2017

When Windows claims "\WINDOWS\" is missing or corrupted

I have recently been trying to repair a Windows 10 machine that suddenly decided to stop booting, failing at startup with a message stating that a required file was missing or corrupted, with the error code 0xC000000D. What's strange is that it said \WINDOWS\ was the missing file. That directory is definitely there. None of these things helped:

  • Startup Repair
  • System Restore from a recovery environment (failed with an unspecified error)
  • chkdsk (made corrections but didn't change the error)
  • sfc offline
  • dism offline
  • Replacing the EFI files from a nearly-identical machine
  • Recreating the BCD store
I am at a loss as to what to do here. Currently the best option seems to be a reinstall - all the data is safe and has been copied off.