Due the the COVID19 pandemic I am currently working from home, using Putty + ssh + Remote Desktop to log into and work on my office PC. For this to work, the office PC must be turned on and booted. So far I have let it running 24h which is really a waste of energy but since sometimes nobody is in the office at all, that was the most fool proof way.

Today I have had some time at my hands waiting for an Ubuntu server to finish installing, so I thought about alternatives.

• One would have been Wake on LAN (WOL), if the BIOS of my computer supported it, but unfortunately it doesn’t (see edit below).
• Waking up using the RTC (real time clock) is actually an option in the BIOS, but that would have woken it up every day rather than just on weekdays.

Finally I stumbled upon an article on How-To Geek about “How to Make Your PC Wake From Sleep Automatically“.

The Windows Scheduler has an option to wake up the computer to run a task. Note that it works only if the computer wasn’t turned off but rather sent into hibernation. So I set up a task that runs “cmd.exe” with the parameter “/c exit” weekly on Monday to Friday at 7:30. Of course I tested it first with a on time schedule and it worked fine.

So now I have sent my office PC into hibernation. We’ll see whether it is available on Monday when I want to log into it.

EDIT:
It turns out that my office PC supports WOL even though it’s not visible in the BIOS. But the network card properties under Windows have a setting for it:

So when I read the hint from Vandrovnik on the international Delphi Praxis forum, I ssh’d into the company intranet and was able to simply wake up my office PC using the wakeonlan tool installed on the remote logon computer:

Great, this is much more flexible than I thought.

I just had one of these dreaded occurrences where the hosts file did not work on a Windows XP installation. (Yes, you read that correctly: “Windows XP”. I still have got a few installations of that to maintain.)

I could not figure out what the problem was, so I turned to Google which found “hosts file ignored, how to troubleshoot?” on ServerFault. The accepted answer lists several steps to trouble shoot. The one that helped me was:

5. Permissions
Sometimes there are issues with permissions on the file, the file
attributes, and similar things. To recreate the file with default
permissions:

1. Create a new text file on your desktop.
2. Copy and paste the contents of your current hosts file into
3. Save the new text file and rename it to hosts.
4. Copy (do not move) the file to your
%SystemRoot%\System32\drivers\etc
directory, and overwrite the old file.

Last point is important: Copying works, moving doesn't.


Unfortunately the described steps did not work for me because I already had moved the hosts file from the desktop to c:\Windows\System32\drivers\etc so the original file and its permissions was already overwritten. What I did to solve this was:

1. Follow the steps 1 to 3 above.
2. Delete the original hosts file in the %SystemRoot%\System32\drivers\etc directory
3. Copy one of the other files in that folder (I used “services”) and rename the copy to “hosts”

Now ping works as expected and connecting to the Embarcadero License Server also does.

Since Microsoft will end the free support for Windows 7 in January 2020, we are updating all our computers to Windows 10 (I would really have liked to avoid that. Windows 7 is definitely not the best Windows ever but its annoyances are known. Windows 10 started to annoy me with new so called “features” immediately after the installation finished. But hey, that’s what you get when you make a living developing software for this stinking pile of sh*t. sorry excuse for an operating system.)

Anyway: As before, when I updated from Windows 8 to Windows 8.1, the Windows 10 update broke my Delphi 6 and 2007 installations. Fortunately my workarounds / fixes for Windows 8.1 also work for Windows 10. Also fortunately I blogged about them

so I could look them up.

Today I got one of these dreaded update reminders for software that I don’t really want to have on my computer (no, not Flash this time). So after procrastinating the inevitable for a few days I just now started the update. I got an interesting surprise:

What???!!!! Oracle doesn’t want me to keep Java on my computer, just because I haven’t used it for half a year? Is this the same company that boasts how many gazillion devices run Java?

Ok, guys, I’ll go for it and remove Java, but I am sure I will shortly find out which of the programs on my PC requires it and will no longer run because I uninstalled it.

(German proverb, roughly translates to: You get as old as a cow and still learn something new.)

I didn’t know about the Windows assoc command which lets you deal with file associations on the command line.

Found it via this post on StackOverflow.

So I don’t forget:
If the drivers for an FTDI USB-serial adapter don’t install resulting in an "unknown device", try to remove all other USB connected devices.

In my case it was a PeakCAN USB adapter, connected via a rather long USB extension cable, that caused the problem (not sure whether it was the adapter itself or the extension cable, that caused it, but I assume the latter, because these adapters usually don’t cause any trouble).

Temporarily disconnecting the cable let me install those USB serial adapter drivers.

The problem was reproducible: It happened after each reboot.

Another unproductive hour spent troubleshooting a Windows driver problem. I just hate Windows and its opaque driver installation method. Give me real error messages Microsoft, so I at least get a clue what’s wrong!

Many tools optionally add an “Open with [Name of tool]” entry to the context menu of the Windows Explorer. Some others don’t, even though it would be useful. Here is how to do it yourself:

1. Open any text editor (Notepad will do)
2. Copy and paste the following text into it:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\Open with [DisplayName]\command]
@="[Path\\to\\executable] %1"

3. Replace [DisplayName] with the name of the tool.
4. Replace [Path\\to\\executable] with the full path of the executable to open. Not that you must replace all backslashes with a dual backslash for this to work.
5. Save the file as “Add-Open-with-MyTool-to-Context-Menu.reg”. Make sure that it is saved as a .reg file, not as a .txt file! (One of the annoyances of Notepad.)
6. Open the created file with a double click and let the Registry Editor add it to the Registry

## Examples:

Windows Registry Editor Version 5.00



### Open with (portable) HxD

Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\shell\Open with HxD\command]
@="C:\\PortableApps\\HxD\\HxD64.exe %1"


HxD is a free and powerful hex editor and can be downloaded from https://mh-nexus.de/en/hxd/.

## Created entries

The created entries look like this:

In theory it is simple to install the dotNet 2.0 framework on Windows 10: Just go to “Programs and Features”, select “Turn Windows Features on or off”, set the checkmark for “.NET Framework 3.5 (includes .NET 2.0 and 3.0)”, press OK and let Windows download the necessary files from Windows Update.

Unfortunately this only works most of the time. If you are unlucky like me and it doesn’t, you will start an odyssey of downloading installers from Microsoft (which also fail, because they try to download files from Windows Update for whatever reason), using the dism tool and possibly Power Shell to install it offline (both of which failed too in my case) and then either despair or find a reference to the “Missed Features Installer”.

When I arrived there, I was very suspicious (and so should you!) of downloading and using such a 3rd party installer. I used the download from Computer Bild not because I think they are the most brilliant computer magazine in Germany (they are not) but at least I trust them not to distribute malware (which is more than I trust the computer magazine CHIP). In addition, I used Virus Total to scan the installer. It gave me a thumbs up, so I was brave enough to run it.

Guess what? It worked. I now have a working .NET 3.5 and 2.0 framework on my computer and could finally install the program I actually wanted to install: The AVT Universal Package for accessing a camera.

Sometimes your program needs to block the screen saver from automatically kicking in. My use case was that the program was recording data and whenever the screen saver was active, the data was lost (No idea why, it probably had something to do with the way HID is implemented in Windows.)
So I was looking for a way to fix that without forcing the user to turn off the screen saver. The methods that used to work under Windows XP no longer work in Windows 7 and later (I don’t care about Vista), so I googled and found this question on StackOverflow. The Windows API functions PowerCreateRequest + PowerSetRequest mentioned in the highest voted answer looked promising. Unfortunately they don’t seem to be available in Delphi (Delphi 2007, which I used for that project, is too old to know them, but I couldn’t find them in Delphi 10.3 either). The first task was therefore to get a function declaration for Delphi. Google didn’t help here which meant that I had to create them myself. Not a big deal:

type
TPowerCreateRequest = function(_Context: PReasonContext): THandle; stdcall;
TPowerSetRequest = function(_Handle: THandle; _RequestType: TPowerRequestType): LongBool; stdcall;
TPowerClearRequest = function(_Handle: THandle; _RequestType: TPowerRequestType): LongBool; stdcall;


I prefer loading such functions at runtime rather than the program not starting because some external reference is not avaiable. These functions are exported by kernel32.dll.

  FDllHandle := SafeLoadLibrary(kernel32);
if not Assigned(PowerCreateRequest) or not Assigned(PowerSetRequest) or not Assigned(PowerClearRequest) then
raise EOsFunc.Create(_('Could not initialize the PowerXxxxRequest functions from kernel32.'));


Usage is not without its own problems. First, I had to declare the constants and parameters:

const
POWER_REQUEST_CONTEXT_VERSION = 0;
POWER_REQUEST_CONTEXT_DETAILED_STRING = 2;
POWER_REQUEST_CONTEXT_SIMPLE_STRING = 1;
type
PReasonContext = ^TReasonContext;
TReasonContext = record
Version: ULONG;
Flags: DWORD;
case Boolean of
False: (
SimpleReasonString: PWideChar;
);
True: (
Detailed: record
LocalizedReasonModule: HMODULE;
LocalizedReasonId: ULONG;
ReasonStringCount: ULONG;
ReasonStrings: PPWideChar;
end;
);
end;
type
{\$MinEnumSize 4}
TPowerRequestType = (
PowerRequestDisplayRequired = 0,
PowerRequestSystemRequired = 1,
PowerRequestAwayModeRequired = 2,
PowerRequestExecutionRequired = 3);


Now, how do these functions work?

The first thing to do is creating a power request with PowerCreateRequest. This function requires a PReasonContext pointer which must be initialized correctly. The Version and Flags fields are simple: Assign one of the POWER_REQUEST_CONTEXT_xxx constants declared above. But what about the other fields? I decided to go with the simple case, that is: Set Flags to POWER_REQUEST_CONTEXT_SIMPLE_STRING and provide a value for SimpleReasonString.

var
FRequestHandle: THandle;
FContext: TReasonContext;
FReason: array[0..255] of WideChar;
// [...]
FContext.Version := POWER_REQUEST_CONTEXT_VERSION;
FContext.Flags := POWER_REQUEST_CONTEXT_SIMPLE_STRING;
FContext.SimpleReasonString := @FReason;
FRequestHandle := PowerCreateRequest(@FContext);
if FRequestHandle = INVALID_HANDLE_VALUE then
RaiseLastOSError;


Where FReason is an array of WideChar. My tests showed that the TReasonContext record and the reason string it points to must be available through the lifetime of the reason context. If it isn’t, the reason displayed by the powercfg tool (see below) will be corrupted. Therefore I did not use a WideString but a static array.

After the power request has been created, calls to PowerSetRequest and PowerClearRequest are possible.

  Win32Check(PowerSetRequest(FRequestHandle, PowerRequestDisplayRequired));


This call prevents the screen saver from starting automatically. A call to PowerClearRequest supposedly turns that off again (but I haven’t tested it).

I mentioned the powercfg tool above. It’s a Windows command line tool that among other functionality can display processes that have active power requests. e.g.

powercfg /requests
DISPLAY:
[PROCESS] \Device\HarddiskVolume2\Source\dzlib\tests\BlockScreenSaver\BlockScreenSaver.exe
test

SYSTEM:
None.

AWAYMODE:
None.

EXECUTION:
None.

PERFBOOST:
None.


The string “test” is the reason I passed to PowerCreateRequests.

I mentioned that failing to preserver the reason string results in a corrupted message in the display. It looked like this:

powercfg /requests
DISPLAY:
[PROCESS] \Device\HarddiskVolume2\Source\dzlib\tests\BlockScreenSaver\BlockScreenSaver.exe
?a?E?I???↑?E?↑?E?↑?E?↑?E?↑


Note that this tool requires administrator privileges (but power requests don’t).

I have added this code to my dzlib. It’s in u_dzOsUtils. There is also a simple test / demo program BlockScreenSaver.

If you would like to comment on this, go to this post in the international Delphi Praxis forum.

Microsoft Office has the annoying habit of adding itself to various places in the Windows user interface. One of them is the popup menu of the Windows Explorer. It adds one entry for each of the installed programs to the “New” submenu.

Have you ever used them? I have only used that submenu for creating folders, shortcuts and text files, but never ever (apart from trying it once I think) for creating new MS Office documents.

So I have removed these entries several times (every time having to google the process) but every update recreates the entries and today I’ve had enough.

So here is a cmd file which will delete them (works for Office 2016 only). You will have to run it as administrator to work.

@echo off
echo This batch file will delete the Registry entries for
echo the "New" submenu of Windows Explorer
echo added by MS Office 2016.
echo This batch file must be run as Administrator.
echo Continue?
pause
reg delete HKEY_CLASSES_ROOT\.docx\Word.Document.12\ShellNew /f
reg delete HKEY_CLASSES_ROOT\.xlsx\Excel.Sheet.12\ShellNew /f
reg delete HKEY_CLASSES_ROOT\.pptx\PowerPoint.Show.12\ShellNew /f
pause