schtasks: foreground versus background

If you have domain user and specify it to schtasks, the task will run in the background [1]:

> schtasks /create /tn task /tr "%BIN%\mytask.bat" ... ^
  /ru DOMAIN\ettis /rp xxx
> schtasks /run task
>

Sometimes, the task will not work, even though it works on your development machine. Omit the /ru and /rp flags; if you try again, the task should run in the foreground (and perhaps also run to completion).

If you have VNC server on the remote machine, you might be able to see the running window from the VNC client.

[1] Technically, it’s not the “background.” The task just doesn’t run in your face on the Remote Desktop screen.

Checklist for migrating tasks

Renting out of IT is a lesson in ownership: the hardware is theirs, so not even your scripts are more important than business-driven resource (re-)allocation. Here’s a checklist for debugging your tasks, “when they worked before”:

  • Desktop\ folder in SysWOW64\config\systemprofile
  • If your new home is 64-bit, also Desktop\ folder in System32\config\systemprofile
  • “Run with highest privileges” checked for task in Task Scheduler
  • “Run whether user is logged in or not” selected for task in Task Scheduler
  • Review all tasks multiple times to make sure the above two selections are marked; selecting one may change the other!
  • /ru DOMAIN\xxx domain account, if available; local account, even if the same username, is “different” somehow
  • Add EXCEL.EXE (full path) to anti-virus exclusion list to allow temporary file creation

nslookup IP given hostname

A remote machine acts as a kiosk, but its data is stored locally. Retrieving it is easy enough with a mount and the right credentials, but the IP address can change. I can use a reverse lookup by hostname before attempting a temporary mount:

set host=MY_COMPUTER_3

for /f "tokens=1,2" %%i in ('nslookup %host%') do (
  if "%%i"=="Address:" (
    set ip=%%j
  )
)
if not !errorlevel!==0 (
  echo error: unable to determine IP of remote host >> err.log
  exit /b 1
)
rem follow up with net use
rem ...

To prevent long reservations of drive letters, I disconnect and reconnect only as long as needed. Fortunately, I haven’t run into collisions of scheduled tasks needing the same drive letter.

Morale

For a field that instructs soulless machines, I have a lot of emotions. Is it possible to be too emotional to write programs? IT expunged me from their server to knock a hole in drywall, sledgehammer to a blocked port, a backend piece for service debut. To cut costs!

The migration was simple and left me nothing but to run on dev. Flashing console screens every which minutes, loudspeaker to announce breaks and lunches, a techno-chorus before newsbriefs: is this a prison or training?

I seem to mark my days. The market insists on skills I don’t have, tech I don’t want to learn, and everyone is so happy. Maybe semantics have to be defined by machines sufficiently abstracted, their neurons coldly modeled, that language and emotion become emergent things. Man was clay until breath, and cognition was upon him in an instant.

In-memory lookup is faster

It feels like – since, quantitatively, I have not measured it for rigor other than mindful minutes – VLOOKUP is faster when the source workbook is actually open. Row by row with VBA, putting down a “=VLOOKUP(” string as it blocks to evaluate, takes forever otherwise. And closing the second workbook changes the formula to reflect the absolute path, so recalculation on subsequent open might be slow too. So I do an immediate replacement:

Sub VLOOKUPInPlace()
  Dim wb As String

  wb = ActiveWorkbook.Name

  Workbooks.Open Filename:="C:\src.xlsx", ReadOnly:=True

  Workbooks(wb).Activate
  For Each r In Range("A1").CurrentRegion.Rows
  If r.Row > 1 Then
    Cells(r.Row, 2) = "=VLOOKUP(..."
    Cells(r.Row, 2) = Cells(r.Row, 2) ' <-------
  End If
  Next
  ...
End Sub

Midnight oil

Whether the AutoIt process or batch scripts in general, scheduled tasks aren’t reliable enough to let run for more than a day. I have a task to end long-running tasks after their usefulness extends past the workday, so they can start fresh in the next. In the scheduled task, nothing but

schtasks /end /tn task-1
schtasks /end /tn task-2
schtasks /end /tn task-3

This run daily once, at 00:00:00, midnight, so whatever cogitations occur with infinite requests into the ether do not bubble up to freeze in next morn.

VBA: MATCH() and R1C1

For the life of me, I could not figure why VBA was throwing an “Application Error” for something like this:

Cells(1,2) = "=MATCH(RC[1], ..."

It has worked before in many other places, but I can’t argue with a compiler. The working alternative was

Cells(1,2) = "=MATCH(F" & row_var & "..." ' hardcoded column

Single-file make do

A network transfer of a single page of a PDF, round-trip, with conversion and the whole flow from web visit to remote print, is about the equivalent of a person checking the process every several minutes. And this because I could not figure the whole page of rows to download, and serendipity took the form of the first checkbox always being selected. These factors in sum enabled headless printers, black cubes, to spool to life and print, cylinders on, cylinders off.

Toner and paper travels in an endless cycle from supplies and back. A quizzical clerk wondering at the consumption, though metrics show it is not much faster than a practiced wrist and lots of idle space. Some requests are fulfilled* in less than a minute, which is really nice.

These are all still scripts. No novel data structures. Free software from there and back. Reliability is a layer, not baked in. Failures are transparent. They know I am fallible and mortal. All in a day’s work.

* Fulfillment is a tricky identifier. There are more time-consuming steps after the print, but “as far as I’m concerned,” etc.

Downsizing

More empty cubes than occupied ones, blank desks with a single Ethernet cable and a chair. The natives are going, and I wonder how much of it was due to my work. Which small project awoke the cost-cutting measures? It wouldn’t take much after the first, because the precedent justifies the rest. Maybe the code meant nothing until its momentum made it impossible to stop.

Maybe it wasn’t me at all. It’s hard to focus when someone is crying in the hallway. Someone else decided something a continent away, and even their executors are not me. I come in and help people be more efficient: the computer can do computer things, and that frees folk to do people things. That’s the happy agreement.

I almost decided game programming was better than automation, because at least you aren’t contributing to a person’s change in destiny, sending him skittering into the jobless aether. Software of real world effects belongs to radiation machines, self-driving cars, and airplanes. Nothing I did could touch the tangible. Yet thus.

I wonder when it will be my turn. Will I feel the relief I plan to feel? Will I have to train a replacement? If nothing else, to embed a fertile mind with the meme of piped scripts is something I’d do for free.

Watch a folder for new files in Cygwin

Here is a quick way to observe a folder with Cygwin:

$ while true ; do date && ls -t /cygdrive/m/folder/path | head -n 1 \
  ; sleep 300 ; done

If your filenames have timestamps, translate that timestamp with the output from date to calculate time differences. Use that to build alerting tools.

In my case, finished jobs move files to that location; post-processing can include image region extraction and OCR for further metrics and reports.