Various technical articles, IT-related tutorials, software information, and development journals
Monday, November 27, 2017
Keen Modding Live - Edit level metadata
Today I implemented an API endpoint for Keen Modding live that allows users to change the metadata of levels they own. It supports altering the name, canonical version ID (after checking that the specified version actually belongs to the level), description, and zone ID (again, after verifying that the zone exists). The next step is to add a level properties window to Abiathar Live Studio so that these settings can be changed from the desktop. I should also eventually implement similar functionality on the site.
Sunday, November 26, 2017
Policy Plus gets a mention
I got curious about the recent uptick in Policy Plus issue filings, so I did some searching to see if it was mentioned anywhere. Sure enough, I found a fairly new mention on the Microsoft Partner Network. A few posts down the page, a Microsoft support engineer noted that Policy Plus can be used on Windows 10 Home to make a relevant Group Policy adjustment. Apparently, at least one person inside Microsoft knows about the tool.
Saturday, November 25, 2017
Modern Windows apps can be launched by protocol
Today I stumbled upon the fact that even simple, non-Internetty modern/Metro Windows apps can be associated with URI protocols. For example, the Calculator will come up if you run calculator:// from the Run dialog - or even from Chrome's address bar.
You can explore protocol registrations in the Registry under this key:
HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId
Each application's subkey has an ActivatableClassId, which contains one subkey for each protocol. The protocol name is stored in the Name value of the CustomProperties subkey.
You can explore protocol registrations in the Registry under this key:
HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId
Each application's subkey has an ActivatableClassId, which contains one subkey for each protocol. The protocol name is stored in the Name value of the CustomProperties subkey.
Friday, November 24, 2017
Policy Plus - Fix crash after searching for policies
A helpful Policy Plus user reported a crash bug today. If the search feature is used to locate a policy before the user opens any categories and the setting editor window is closed with the OK button, Policy Plus will crash with a NullReferenceException. This happens because the UI-smoothness-enhanced ShowSettingEditor function tries to determine whether the current category is still visible, but if no categories have been visited, that variable is null and things break.
Adding a null check fixed the problem. The Debug build has been updated.
Adding a null check fixed the problem. The Debug build has been updated.
Thursday, November 23, 2017
Recovering a GPO from the Registry with Policy Plus
If the POL files become corrupted, as they did for one user, Group Policy tools may be unable to open them. In particular, Policy Plus will be unable to start. It is still possible to use Policy Plus to save the policy data from the Registry and incorporate it back into a POL file.
First, move the Registry.pol files out of the folder(s) corresponding to the affected section(s) in C:\Windows\System32\GroupPolicy. If you're not sure which sections are affected, do them both - it doesn't matter where; we're just making a backup in case you want to do something with the originals.
Policy Plus will now be able to launch; it will create a blank POL file to replace the ones we moved. Use File | Open Policy Resources to open the Local Registry for the affected section(s). Use Share | Export POL to gather the policy-relevant Registry branches into a POL file for each section. This works because even though the POL is damaged, the Registry settings contained therein are likely still safe in the Registry. Make sure to save different POL files if you're doing both sections.
Use File | Open Policy Resources again to open the Local GPO. Use Share | Import POL for each affected section to bring in the appropriate POL file you created just now. Then you can use File | Save Policies to commit the newly restored GPO POLs.
First, move the Registry.pol files out of the folder(s) corresponding to the affected section(s) in C:\Windows\System32\GroupPolicy. If you're not sure which sections are affected, do them both - it doesn't matter where; we're just making a backup in case you want to do something with the originals.
Policy Plus will now be able to launch; it will create a blank POL file to replace the ones we moved. Use File | Open Policy Resources to open the Local Registry for the affected section(s). Use Share | Export POL to gather the policy-relevant Registry branches into a POL file for each section. This works because even though the POL is damaged, the Registry settings contained therein are likely still safe in the Registry. Make sure to save different POL files if you're doing both sections.
Use File | Open Policy Resources again to open the Local GPO. Use Share | Import POL for each affected section to bring in the appropriate POL file you created just now. Then you can use File | Save Policies to commit the newly restored GPO POLs.
Wednesday, November 22, 2017
Policy Plus - Fixing things when refreshing
Today I noticed that there are a handful of other events in Policy Plus that should have the possibility of moving up the category tree if the current category no longer contains any policies visible under the filter. Fixing that was just a matter of replacing an UpdateCategoryListing call with one to MoveToVisibleCategoryAndReload.
I also noticed recently that OKing out of the setting editor dialog refreshes the category listing and puts the scrollbar back to the top, losing the focus on the selected policy. This is somewhat jarring, so today I fixed it. UpdateCategoryListing now preserves both the scroll position and the selected policy if the current category is unchanged.
These changes are live on GitHub.
I also noticed recently that OKing out of the setting editor dialog refreshes the category listing and puts the scrollbar back to the top, losing the focus on the selected policy. This is somewhat jarring, so today I fixed it. UpdateCategoryListing now preserves both the scroll position and the selected policy if the current category is unchanged.
These changes are live on GitHub.
Tuesday, November 21, 2017
Policy Plus - Resizable setting editor
Today I finished implementing this feature request on Policy Plus, making the setting editor dialog resizable. I considered using a fancy layout panel to handle the expansion of the two halves of the form when the form gets wider, but instead I just went for a bit of math in the Resize handler. It determines how much extra width is present now relative to the original size, then evenly distributes that extra to the two halves. Finally, it calls the method that reassigns the maximum size of each element-based control. This all leads to a very smooth resizing experience, even more so than in the original LGPE.
Monday, November 20, 2017
Policy Plus - Remove horizontal scrollbars
A Policy Plus user noticed that, unlike that of the official Local Group Policy Editor, Policy Plus's setting editor window cannot be resized. Resizing Policy Plus's might be desirable because a horizontal scrollbar sometimes appears in the extra options panel, which requires the user to scroll it to see the ends of the controls. I investigated and found that this happens when there are so many controls that a vertical scrollbar appears, taking away a little piece of horizontal space for the already-dimensioned controls, creating a horizontal scrollbar. I addressed this by keeping a list of resizable controls and adjusting their MaximumSize when the table size changes and after the extra options space is set up. I have not yet made the full form resizable, but this change should provide most of the convenience.
Sunday, November 19, 2017
Policy Plus - Filter by configured policies
A Policy Plus user suggested that the filtering feature be extended with the ability to show policies that are configured - either enabled or disabled, but not unconfigured. This makes a lot of sense, e.g. one might want to easily look over all the customizations applied via Group Policy. Today I implemented that request. There is now a Configured option in the Current state dropdown in Filter Options that works as requested.
The changes are live on GitHub.
The changes are live on GitHub.
Saturday, November 18, 2017
Measuring page size with Edge
Today I needed to determine how much total bandwidth it took to load a given page. Conveniently, the developer tools in Microsoft Edge can show this. On the Network tab, there is an item in the status bar that shows how much data has been transferred. You can also filter the requests by type (e.g. image) to see how much is taken by each kind of resource.
Friday, November 17, 2017
Keen Modding Live - Log files cleanup
I noticed recently that using the Test feature in Abiathar Live Studio (to actually play the level one's developing) results in the DOSBox output and error log files being sprayed into the project working directory, not the test environment. The problem was that Abiathar keeps the current directory the same as the directory containing the ADEPS, and the current directory is inherited by subprocesses like DOSBox unless another is specified. Fixing the problem was just a matter of manually setting the new DOSBox process's current directory to the test directory.
Wednesday, November 15, 2017
Keen Modding Live - Studio settings
Previously I wrote some code for Abiathar Live Studio that detects the DOSBox installation and, if it can't find the EXE automatically, asks the user to specify it in Settings. Until today, there was actually no way to use a custom DOSBox path because the Settings item did nothing. Now, there's a little dialog that allows the user to change the DOSBox installation used or the temporary directory.
Monday, November 13, 2017
Keen Modding Live - Play any version
For a while now, Keen Modding Live has supported multiple versions of a given level, but there was no way to actually play any version except the current one. Today I adjusted the player page to take a version ID rather than a level ID. Since people might want to share links to the level in its most recent version, the page can also take a level ID, in which case it automatically redirects to the current version. Now I need to implement a way to explore the versions of a given level.
Sunday, November 12, 2017
Policy Plus - Check for functional Group Policy infrastructure
Last time I worked with Policy Plus, I found that there isn't a clean way of detecting whether the current Windows installation has functional Group Policy infrastructure. That led to Policy Plus failing to actually apply the POL settings to the Registry in certain environments. I was hesitant to use a table of SKUs because new Windows editions might add new entries, so my table would need to be continually maintained. Today, though, I noticed on that MSDN page that GetProductInfo will map the current operating system product to a product that existed when the supplied OS version did. I took advantage of that get a product that Vista knew about, thereby covering all Windows versions that Policy Plus can run on.
I also found another bug: PolFile.WillDeleteValue incorrectly interpreted a deleter value's presence to mean that the value will not be deleted, which is obviously a problem. I corrected that and published these fixes to GitHub.
I also found another bug: PolFile.WillDeleteValue incorrectly interpreted a deleter value's presence to mean that the value will not be deleted, which is obviously a problem. I corrected that and published these fixes to GitHub.
Saturday, November 11, 2017
Keen Modding Live - Publish
A pretty important part of Abiathar Live Studio is the ability to actually publish the level to Keen Modding Live without the friction of going to the web site and picking the files. Today I implemented the Publish feature, which prompts for the level title, the zone, and the description, then uploads all the necessary files. On subsequent publications of the same level, it doesn't prompt for anything and instead uploads a new version. I think this is pretty slick.
It was a little tricky to implement the POST upload because .NET 4.0 doesn't seem to have a way to do multipart/form-data requests without crafting the entire body manually, which I really didn't want to deal with. .NET 4.5 makes this pretty easy, but Abiathar targets .NET 4.0 so that it can run on Windows XP. I discovered today, though, that loading a higher-targeted DLL at runtime actually works fine if the system has the more updated Framework. Abiathar Live Studio is now targeting .NET 4.5, but can still be loaded by Abiathar on Windows Vista and newer.
It was a little tricky to implement the POST upload because .NET 4.0 doesn't seem to have a way to do multipart/form-data requests without crafting the entire body manually, which I really didn't want to deal with. .NET 4.5 makes this pretty easy, but Abiathar targets .NET 4.0 so that it can run on Windows XP. I discovered today, though, that loading a higher-targeted DLL at runtime actually works fine if the system has the more updated Framework. Abiathar Live Studio is now targeting .NET 4.5, but can still be loaded by Abiathar on Windows Vista and newer.
Keen Modding Live - Zones
My vision for Keen Modding Live includes the concept of different stages of level readiness. Some authors might have a beta version ready to be played, but not suitable for listing in the main marketplace. Today I started implementing "zones" to which levels can be assigned. There are currently three: Showtime, Beta, and Developing (names yet to be finalized). Showtime will be the primary zone for players browsing the site; people will be able to explore the others if they want. At publication time, level authors select the zone - this is implemented now. Soon there will be a way to reassign the zone of a level, e.g. once it's ready for the general public.
Thursday, November 9, 2017
Policy Plus - Windows 10 1709 ADMX definitions
I realized a few days ago that with Windows 10 1709 released to the public, people might want to use the new Group Policy settings it introduces. So I went and found the official MSI package, made sure it still has the same directory structure as the previous packages, and updated Policy Plus to get the new MSI.
In other news, a user actually ran into a problem that I speculated about: installing the Local Group Policy Editor on Home editions with DISM results in a nonfunctional version of the official Group Policy editor that nevertheless confuses Policy Plus into thinking it's off the hook for applying the policies to the Registry (because secpol.msc then exists, even though it shouldn't on Home). I have not yet found a reliable way to check whether the current machine supports Group Policy, so I asked a question on Stack Overflow.
In other news, a user actually ran into a problem that I speculated about: installing the Local Group Policy Editor on Home editions with DISM results in a nonfunctional version of the official Group Policy editor that nevertheless confuses Policy Plus into thinking it's off the hook for applying the policies to the Registry (because secpol.msc then exists, even though it shouldn't on Home). I have not yet found a reliable way to check whether the current machine supports Group Policy, so I asked a question on Stack Overflow.
PowerShell surprise: script current directory is not the process current directory
PowerShell supports paths expressed relatively to the current directory. You can do things like gc .\mydoc.txt to get the contents of mydoc.txt in the current directory. Sometimes, though, using relative paths will mysteriously fail with a file-not-found error. This happens when a .NET I/O function is called before the path is resolved by PowerShell. Changing the current directory in script (the one that displays at the prompt) doesn't necessarily affect the process's current directory, which you can get with [System.IO.Directory]::GetCurrentDirectory().
Most commonly, the problem is that a script calls a .NET Framework function directly, but some third-party modules may forget to do the resolution before trying to use the path. To set the process's current directory, you can use [System.IO.Directory]::SetCurrentDirectory.
Most commonly, the problem is that a script calls a .NET Framework function directly, but some third-party modules may forget to do the resolution before trying to use the path. To set the process's current directory, you can use [System.IO.Directory]::SetCurrentDirectory.
Monday, November 6, 2017
Keen Modding Live - Log in on the desktop
Today I implemented the Keen Modding login flow in Abiathar Live Studio. Just like on the site, the user can enter their name and password. If there is no Keen Modding account by that name linked to Keen Modding Live, the program offers to link them and then proceeds to log in. The API key received from logging in is stored in the Registry so that the user doesn't have to log in at every Abiathar run. There's also a Log Out menu item if the user wants to invalidate the API key (or all API keys for their account).
With login implemented, the next step is to allow the user to publish their levels to the site.
With login implemented, the next step is to allow the user to publish their levels to the site.
Sunday, November 5, 2017
Keen Modding Live - Better login experience
Today I rearranged the authentication part of Keen Modding Live a bit. Now the Keen Modding authenticator indicates whether an account needs to be linked or the logon just failed. The login page uses that information to only show the Link Accounts button if makes sense to even try. This adjusted API will make for a convenient login experience in Abiathar Live Studio as well, which is my next thing to implement.
Saturday, November 4, 2017
Keen Modding Live - Easily test levels
Today I continued working on Abiathar Live Studio, the Abiathar extension that will serve as the desktop client for Keen Modding Live development of Galaxy and Dreams levels. When preparing the development environment for a new level, it now also downloads and unpacks the full episode package, staging it in the testing directory. I have it do this eagerly (at level creation) so that all necessary data is stored locally in case users want to test their levels when they don't have Internet access.
Speaking of testing levels, it now automatically detects the DOSBox installation so that zero configuration is needed in most cases. The user can select a difficulty under the Test menu; DOSBox immediately launches into the level. Under the hood, Abiathar Live Studio saves the project, copies the level files to the testing zone, writes the DIFFICU.LTY file, and starts DOSBox.
The list of which files are level files is stored in the project file in case the Internet goes out and the episode metadata becomes unavailable. Extra configuration options are stored in the project file through Abiathar's configuration section registration API: when the level project is created, Abiathar Live Studio injects the new configuration section, then gives Abiathar a config template object when the project file is opened later.
Speaking of testing levels, it now automatically detects the DOSBox installation so that zero configuration is needed in most cases. The user can select a difficulty under the Test menu; DOSBox immediately launches into the level. Under the hood, Abiathar Live Studio saves the project, copies the level files to the testing zone, writes the DIFFICU.LTY file, and starts DOSBox.
The list of which files are level files is stored in the project file in case the Internet goes out and the episode metadata becomes unavailable. Extra configuration options are stored in the project file through Abiathar's configuration section registration API: when the level project is created, Abiathar Live Studio injects the new configuration section, then gives Abiathar a config template object when the project file is opened later.
Keen Modding Live - Downloadable development environments
A goal of the Keen Modding Live editor-integrated desktop client is to make it extremely easy to start building a level. The user should just have to pick an episode, choose where to save their files, and be ready to go. Today I finished implementing the New Level feature. After the user makes their choices, it fetches the development package corresponding to the selected episode, extracts the package to the folder containing the new ADEPS file, and opens the ADEPS.
Development packages are different from normal episode packages in that development ones contain only the bare minimum complement of files needed to make Abiathar work: the ADEPS and nearly empty map files (a template). The other files needed to play the game are in the episode package. So far, I've just made the Keen 4 development package as a proof of concept; doing the others will be easy.
Development packages are different from normal episode packages in that development ones contain only the bare minimum complement of files needed to make Abiathar work: the ADEPS and nearly empty map files (a template). The other files needed to play the game are in the episode package. So far, I've just made the Keen 4 development package as a proof of concept; doing the others will be easy.
Wednesday, November 1, 2017
Keen Modding Live - Keeping session info
Dropbox and a few other websites have a section that allows the user to view and invalidate sessions that are logged in to their account. They keep track of the user agent used to sign in so that the user can tell which browser the login is from. That kind of fine-grained session management might be a little overboard for Keen Modding Live (the "log out" API endpoint already provides a way to end all sessions), but keeping track of user agent is very easy, and might be useful for the occasional curious user.
The "log in" API endpoint now remembers the user agent and the logon method (linked Keen Modding account vs. the not-yet-implemented e-mail/password option).
The "log in" API endpoint now remembers the user agent and the logon method (linked Keen Modding account vs. the not-yet-implemented e-mail/password option).
Subscribe to:
Posts (Atom)