Task Scheduler WorkItem Not Running - windows

I have a very specific problem that I need fixing. The major issue is that I don't exactly know how to properly search the remnants of my problem on google. Therefore I am coming to StackOverflow for advice in hopes that someone will assist me.
Summary
So I am writing an application which is to be PCI-compliant for the company which I am starting. The application involves IPC (Inter-process communication) and two "watch-dog" apps which monitor the status of the main application. One of these "watch-dog" applications is an updater (sends an HTTP Request to the server looking for updates of the application).
So! This method which I am using to check the server if the application is up-to-date is using the WinInet library and InternetOpen() to send the request. Then read the response of the page and use GetCookie() to store the response in a buffer. It shall then parse the response accordingly.
If the response says that the current version of my application is less than the version located on the server. It will then tell the customer (user) that their application is out of date, and ask them whether or not they want to update the software. If they choose to update the software, it will perform a Download And Execute from the internet and launch the update-installer on the user's PC.
The Problem
Unfortunately, windows is very "secure" when it comes to having an "unauthorized" application send an HTTP Request to an outgoing url, let alone download something from the server then execute it on the users PC.
My conclusion to this issue was to add the watch-dog programs to the Task Scheduler. That way after the main application is run, it will spawn the watch-dog programs and check if they are running with NTAUTHORITY privileges (which are granted by the Task Scheduler).
After implementing the code to create the task and point it to the location of the watch-dog programs, naming it, writing a description and everything. I executed the program. It ran without errors though here the REAL PROBLEM:
1) Programs executes
2) Spawns watch-dog programs
3) Watchdog program checks for new version
4) Version is found
5) Installer is downloaded, execute ... but
6) The installer does not appear on the screen!
When I run my 'Process Hacker' application to monitor all process actions. I can see that the new installer is download & executed. It is running as NTAUTHORITY/SYSTEM just like the watch-dog programs but it doesn't appear on the system.
I made sure that in my code the status of the window is set to SW_SHOWNORMAL not SW_HIDE. I also made sure that all flags are set accordingly. Though it doesn't appear on the screen!
When I run the application without adding it to the Task Scheduler as my user without NTAUTHORITY/SYSTEM status and just regular user status. It executes (obviously since I am already running as administrator) -- everything works fine. But after adding it to Task Scheduler and having it run with SYSTEM level privileges. The window doesn't appear on the screen visually. Why's that?
I would greatly appreciate anyone that is able to assist me with this problem. Thank-you!
edit 1
Can anyone help me understand how this user applied his fix in the registry? By reading the problem I can somewhat interpret that he had the same issue as me.
App is invisible if started from Task Scheduler without any user logged in
In any case, I am trying to use the advice that Gisley gave me to run the application in Interactive Mode. Possibly going to try to give that a try. Still looking for more answers but I am going to be working no this none-the-less in the meantime.
edit 2
I tried setting the INTERACTIVE FLAG and it had no effect unfortunately.
Allow me to just emphasize my problem:
For example I write a program which has message boxes and put it in a loop.
for
message box
get current pid
make process in the task scheduler
spawn new process as the task scheduler proc with NTAUTHORITY/SYSTEM
kill last proc pid
end for
Then when I execute it:
I get the message box. Then after new process opens with NTAUTHORITY/SYSTEM the message box does not appear anymore.
Same for if I open a calculator for example.
System("cmd.exe start /c calc.exe")
Program runs... opens calculator
Program gets NTAUTHORITY/SYSTEM status
ON the next loop it executes the calc.exe
I see it in my task manager but it doesnt appear on the screen
I hope the above helped emphasize the core of my issue. I dont see the processes opened by the task scheduler process id with NTAUTHORITY/SYSTEM rights... I dont see the procs executed by it on my screen, though I see them in the task manager | process hacker and they are running with NTAUTHORITY/SYSTEM privileges too.

A shot in the dark - try running the task in interactive mode, but you'll need to have a user logged on.
https://superuser.com/questions/616206/run-interactive-task-even-if-user-is-not-logged-on-windows
Alternatively, or additionally, pass parameters to the installer so that it installs silently.
Silent installation of a MSI package

Related

Make a PowerShell script run on startup in the OOBE Sysprep environment

Thanks for stopping by, I've searched the corners of the internet but haven't gotten anywhere.
To provision devices for my organization, we must manually run PowerShell commands using SHIFT + F10 in the Windows 11 OOBE as we have multiple methods, one of which being legacy. I'm sure there are better methods but I'm unfortunately working within these limitations. So far, to automate the imaging process, I've created an autounattend.xml which makes WinPE completely silent and some pages of the OOBE also.
Recently, I combined all the PowerShell commands we had been running prior into a script that, after running repeated checks for a network connection, prompts users with a GUI and effectively automates everything we had been doing manually before:
Message box with radio buttons
I need to make this run when the OOBE Sysprep starts, but I really need some help.
The script contains GUI, so it cannot run silently and the user needs to interact with it.
The script must start with the OOBE Windows Welcome Screen, (i.e. select region screen). This is a limitation of the modules used and I therefore can't include it as a synchronous command in FirstLogonCommands or include it in SetupComplete.cmd, as those both execute after the OOBE is completed.
I've tried configuring the answer file to boot into audit mode and have the script run there, but the script requires several reboots and I get an installation failed message after any reboot (despite later making the script enable the Administrator account and call "sysprep /audit /reboot"). Additionally, the Audit Administrator account takes ~15 minutes to log in so it defeats the whole purpose of time saving.
I've tried using Task Scheduler, running both on System Start Up and User Log On, as defaultuser0, BUILTIN\Administrators and SYSTEM. Task scheduler seems to either queue tasks or not call them at all in the OOBE
I've tried placing the script, and then a shortcut of the script, in the common start up folder but that didn't work either.
To reiterate, I need a way to automatically run a script when the OOBE Sysprep starts. Furthermore, I need it to run every time the OOBE is launched as sometimes, we have to manually reboot if something glitches or goes wrong so the script will need to run again when the OOBE is resumed.
I know this is a tough one due to the limitations, but this will make the device rollout significantly easier.
Thanks,
Jake

How to clear Windows event logs without showing any error messages?

I'm creating a Windows event log-clearing software.
Whenever you clear logs from the command-line, there are always a few logs that can't be cleared, because either newer versions of Windows don't use the services those logs were meant for anymore, or they are important system logs that are almost always being written to.
However, when the Windows event utility tool finds out it can't clear those logs, it relays an error message to the user. And because I'm trying to make this Batch file into an actual software, I would rather not have a bunch of messy error messages on the screen, for the sake of the user experience.
The obvious answer to this problem would be to have the batch file start a separate background batch script to clear the logs, where the user wouldn't see any error messages, but modern-day anti-virus really don't like batch scripts, and flag them almost every time, so I can't do that.
I tried to instead create a powershell script (Much more trusted by anti-virus.) to clear the logs. But because of the nature of powershell, even if it runs completely in the background, without a console, it still relays error messages in the form of VBS XMessages.
If it's any useful, here's the two lines of code in the powershell script:
wevtutil el | Foreach-Object {wevtutil cl "$_"}
exit
And for those who are wondering, yes, I am clearing logs with administrative privileges.
I need one of the following:
Another way to clear Windows event logs, that doesn't show error messages, that I can integrate into the software I'm creating.
A way to forcefully clear those Windows event logs that normally can't be cleared.
A way to have a batch script run without anti-virus having a stroke.
A way to make the powershell script run completely in the background, without event displaying error messages.
To any who happened to stumble upon this question, the answer is in the comments section, as credit goes to #vonPryz, who mentioned that Clear–EventLog would work better than wevtutil, and it does.

Detect if MSI requires a reboot before installation

If I launch an installer with MSIExec in quiet mode I can detect if a reboot is required to complete installation by checking if the exit code is 3010. But what I'd like to be able to do in a programmable form is test whether or not the installation of an MSI will require a reboot to complete before I launch the actual installer.
I've looked around at the MSI APIs:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa369426(v=vs.85).aspx
I did think I could:
Call MsiOpenPackage to get the installer ready to run
Call MsiDoAction with the following: CostInitialize, FileCost, CostFinalize, InstallValidate
Read records from the FilesInUse table (the following documentation on MSDN suggests this table is created after running CostFinalize/InstallValidate:
http://msdn.microsoft.com/en-us/library/aa369546(VS.85).aspx
However that table doesn't actually appear to exist when I query for it during the installation process. Are there any other ways to check if a reboot will be required?
Gareth, theoretically you don't need to perform the actual install, you should execute just the actions until InstallValidate (included) because then the Files In Use messages appear. However, when the installation is performed with an an external UI handler the Windows Installer may behave a little different so that should be tested.
The decision gets eventually made only during installation itself. As you know, it depends on circumstances like DLLs locked by a concurrently runnning application and therefore it is quite volatile.
There is no way that would guarantee you that you will not receive exit code 3010 after the real installation has completed.
That said, the exit code is not that closely bound to files in use. It may also indicate an inability to stop a service or perhaps some other transient or permanent condition. You can not learn whether a service could be stopped until you try.
Jirka is right about the volatility of is a restart required - all kinds of things could happen during the installation process.
However, I think I've got close to what I'd like to be able to do with a different method:
Register an external UI handler for INSTALLLOGMODE_RMFILESINUSE
Capture INSTALLMESSAGE_RMFILESINUSE messages
If I capture any INSTALLMESSAGE_RMFILESINUSE messages, return -1 and exit installation before any file copying proceeds
In this way I can attempt a silent background installation of software but if for any reason it looks like I won't be able to complete the install I can hold back. I think I might be able to do a rollback using the MsiBeginTransaction and MsiEndTransaction functions as well if I do end up in a state of the user has locked a file after starting to copy.

How to restart program automatically if it crashes in Windows?

How can I start my program automatically if it crashes on windows 2003 server? Sometimes my program just crashes, is there a way in windows or settings that I can set?
There are several ways to create a process supervisor/guardian process on Windows.
First, is to leverage windows command line capabilities. Create a bat file:
#echo off
:start
start /w "your app to watch.exe"
goto start
start /w will wait for the process to exit. When the process crashes and exits, the bat script will relaunch it.
Another option is to use free supervisor tool https://github.com/chebum/Supervisor. It allows to restart the crashed app, plus it allows to monitor two or more apps at once and it will automatically close these apps when supervisor's window is closed.
The usual approach is to run what is known as a guardian process. This is a separate process, often a service, that monitors the state of the main process. When the guardian detects that the main service has died, it re-spawns it.
To the very best of my knowledge, there is not built in Windows functionality to do this for you.
Notice: running self-looping bat files can be useful, but unless you know what you're doing, they can wreak all kinds of havoc. This goes especially if you run them on startup. You have been warned.
Anyway. I just remembered something from my 286 days, when I played around a lot with BAT files. If you write the file
yourprogram.exe
some other event
the BAT file will run yourprogram, and then pause and wait around in the background until the program exits. After that it will run "some other event". This used to be kind of annoying if you wanted to run multiple things at once, but here it's actually useful. Using this, it's possible to make it run a loop that restarts the program (and reruns the bat file) as soon as it exits. Combine this with https://superuser.com/questions/62525/run-a-completly-hidden-batch-file, and you'll never even see it happening.
The final BAT file ("restart.bat" in this example) will look something like:
c:\[location]\yourprogram.exe
wscript "C:\[location]\invisible.vbs" "C:\[location]\restart.bat"
That's about it. Start the program (on startup via task or even just startup folder) with line 2, and this ought to solve your problem :)
Oh, if you want to stop the loop, just rename the bat file or put "// " in front of the two lines, save it, and exit the program.
If the program you are running requires admin rights, the solution I found was using psexec (http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx) to run both the program and the bat with elevated privileges. In that case the BAT will look like:
c:\[location]\psexec -h c:\[location]\yourprogram.exe
c:\[location]\psexec -h wscript "C:\[location]\invisible.vbs" "C:\[location]\restart.bat"
Then you run the bat as administrator, or run the second line (without the psexec part) from task scheduler with elevated privileges. BEWARE: running it as a normal user and clicking "no" on the UAC prompt gave me a BSOD, probably because it looped "can't run program because of lacking privileges" a couple of billion times or something :)
You can use RegisterApplicationRestart.
"If you register for restart and the application encounters an
unhandled exception or is not responsive, the user is offered the
opportunity to restart the application; the application is not
automatically restarted without the user's consent. "
For automatic restart without user intervention, there is also RestartOnCrash. Works with all Windows versions.
I was looking for something similar. There are two options to handle this - either you can write a small script by yourself or use something that is already existing.
After some googling I came across this nice list. The blogger has compiled about 8 tools to automatically restart a crashed or closed application.
Unfortunately there are no settings in Windows to automatically restart a regular program when it crashes.
Do you need to actively interact with your application's GUI? Some of the Service Wrappers (designed to run any application as a Windows Service) will monitor your application and restart it when it fails, but be sure investigate Session 0 Isolation to ensure that it won't get in the way.
You may use some special app like BDV SystemEvents or any other. It allows you to specify application which will be started if some another application is closed. Specify the same application as a Condition and as an Action and you will get expected results.

Printing PDFs in WinServer 2008 from a non-interactive process (Windows service, scheduled task, etc.)

I am trying to write a non-interactive process that prints PDFs, and I need advice on how to build this on Windows Server 2008 (and Vista/7).
Previously, we have had a scheduled task (set to run whether the user account was logged on or not) that would print all PDFs inside of a directory. (A seperate process would move the PDFs into the directory.) At runtime, this would spin up another process (either Adobe Reader or Foxit Reader) to print the PDF. Both Adobe Reader and Foxit Reader feature silent printing, so everything would be sent to the default printer for the user that the scheduled task ran as. No UI was ever generated, and all files would be printed without a hitch. This worked on Server 2003.
The process no longer works on Server 2008. I'm not entirely sure, but I believe this has to do with Session 0 Isolation. I cannot prove this. However, I can say that the process works as a scheduled task when set as "Run only when the user is logged in". Now, while this works, it forces a user to log in to the machine, and thus does not fulfill my requirements. (My first clue was in this previous question.)
I cannot determine how I can move forward on this. Is there any way to fulfill my requirements?
A few notes :
Every solution I've seen seems to be using the credentials of a logged-in user. See the question I linked above - the solution listed appears to be grabbing the token of a logged-in user and using it to run the program. (Look at the GetCurrentUserToken() procedure - the returned value is later used in the API call CreateProcessAsUser().)
My current process generates, as near as I can tell, no UI. I've verified, using ProcMon, that the reader process (Adobe or Foxit) appears to print correctly and the print driver itself appears to have a problem. This is backed up by an attempt to use a print-to-file driver - the print-to-file driver runs in three visible steps and clearly finishes the first for all files without starting the second. So how does Session 0 Isolation affect the printer driver? This is unclear to me. (The best documentation I can find on the subject only mentions that printer drivers may be affected, even though the print spooler runs in Session 0.)
Printing as a Windows service never works, even when the process has 'Allow service to interact with desktop' checked.
Bold text added to counter the blear-inducing wall-of-text effect.
Try using Foxit Reader instead of Acrobat-Reader.
Foxit Reader supports GUI-less / commandline execution properly, also in Windows 2008 and above!
Printing is also possible, but you will have to add (or check) the printer in session0 every time you run the printjob.
If you need any more help on that, just ask again. I already built a powershell script which runs in task scheduler to print pdf-files with help of Foxit Reader.

Resources