osx - What's the best way to "pause" a 3rd-party macOS app during launch in Swift? - macos

I've been playing around with NSRunningApplication in Swift 3, and I've come up with a few questions.
What's the best way to "pause" an application while it's launching. Don't quit it, but don't let it launch completely either. Just keep the icon bouncing in the dock (i.e. "freeze" the launch) for some arbitrary time. After that time, if I decide I want to quit the app after all, I can do NSRunningApplication(withBundleIdentifier: "xyz").terminate() or .forceTerminate(), and I can confirm with .isTerminated(). Otherwise, I can just "unfreeze" the app and let it finish launching.
What's the least power-hungry way of checking constantly for an app launch? I could just schedule a Timer to check every half-second or so, but I believe that hogs a fair amount of memory. Can I set a listener or notification to check for a 3rd-party app launch? (i.e. to run a function every time the Notes app changes isTerminated state).
Thanks!

You can't reliably target another process and control it from Swift (or any other User-mode program), as you really need to do that in the kernel, with a kernel extension (Kext).
Apple's official framework for this is the Kernel Authorization framework (KAuth). Using the File Operation Scope (described in the documentation), a kernel extension will be notified of various operations, including a program's execution and can allow or deny its access.
A working example of its usage can be seen in the open source code of Google Santa, which they use to manage their own employees' computers. As its documentation states:
It consists of a kernel extension that monitors for executions, a userland daemon that makes execution decisions based on the contents of a SQLite database, a GUI agent that notifies the user in case of a block decision and a command-line utility for managing the system and synchronizing the database with a server.

Related

Which frameworks am I allowed to link to from a macOS launch daemon?

I'm writing a macOS launch daemon (in C++). It works for the most part, except that I am noticing some random crashes via SIGABRT (in the log.)
I've asked earlier about the use of the Core Graphics framework, which it turns out was not allowed in a launch daemon. I removed it, but I still get very rare crashes.
Thus I'm wondering which of the following frameworks am I allowed to use from a launch daemon?
There's no technical restriction on specific frameworks you're allowed or not allowed to link. Merely linking a library will not cause crashes. Some APIs need to be called from specific contexts, such as much of Core Graphics only making sense if a process is part of a windowing session, as you've found out. But even there, some of the off-screen drawing APIs which don't interface with the windowing system directly ought to work from a Launch Daemon context.
If you're seeing crashes calling specific APIs, you'll need to investigate those one by one. If you're seeing "random" crashes, I suspect you have a bug (memory overwrite? multithreading error?) in your code. Note that Apple's toolchain provides a bunch of different diagnostic options which you can use even when not running in the debugger, such as ASan, UBSan, and Thread Sanitizer. These may help you track down issues.
As you've specifically tagged this question with the IOKit tag and it's shown in your screenshot, I'll add that using IOKit from a launch daemon is very common. It's even possible to use IOKit matching events as a launch trigger for the daemon using XPC events/xpc_set_event_stream_handler - this way, your daemon can be started on-demand when a specific (type of) device is connected, for example. (As opposed to starting up at every system boot and consuming system resources even if it's not needed or doing anything.)

How to activate / enable the process notification feature in API Monitor?

API Monitor has a feature to automatically watch for a new process starting and ask if you want to monitor it. However I have not been able to get this to actually work. The only option in the program I can find which seems to be related is the File menu "Pause Process Notifications" option. However, this is disabled which gives me the impressions that it can't be turned off but also that it is supposed to work automatically "out of the box". But whenever I start a new process, nothing happens.
Specifically I'm referring to the feature described here:
Process Notification
API Monitor intercepts process creation and allows you to select the
process for monitoring. Each time a process is created by the system,
a notification window is displayed with options to monitor, skip or
terminate the process. This is especially useful for monitoring
processes with a short lifespan or processes that are automatically
launched in the background. Process Notification can also be used to
monitor applications such as consent.exe (UAC prompt), which run on a
different desktop.
The following screenshot shows an example of the Process Notification
window that is displayed when launching an application that requires
elevation
I've tried both the 32-bit and 64-bit versions of API Monitor (Version 2.0 Alpha-r13) running both as regular user and as admin; makes no difference.
How can this feature be activated?
The specific reason I'd like to use this feature is that I have process A which starts process B, and it is B I need to monitor. A and B each run for only a few seconds so I can't manually get it to monitor fast enough.
Finally after reading through API Monitor forums I found some information. Unfortunately (for now at least) it seems the answer is that this feature no longer works (since Windows 8.1).
As posted on http://www.rohitab.com/discuss/topic/40418-process-notification-on-81/?p=10093378
rohitabPosted 11 October 2013 - 03:38 AM
Due to security related changes in Windows 8.1, the Process
Notifications feature of API Monitor does not work. I will try to
resolve this issue as soon as possible and post a hotfix.
But a later update in 2014 indicated that it hadn't been fixed yet, and seems not to have been since then either.
It was implied that running in a Windows 7 (or 8.0?) virtual machine might be a workaround, or obviously finding another tool which has this capability.

Is there a way to redirect (render) a window to a "memory display"?

I want to make a windows application whose GUI will be streamed to another device (allowing remote control). The point is that I'm not willing to rely on creating Windows Sessions to isolate the GUI I/O's (1)
To achieve this, I started observing some existing solutions that are able to enable remote access using this premise to see if I could get a clue about where to start.
One of these solution is Winflector (BTW: it is free up to 2 connections).
I got interested in this solution because it seems (I'm guessing) it detects only the repainted regions. What I took from my observations are that:
While the streamed application is "invisibly" running locally in the same session I'm logged in (it shows the application process in my task manager), the application window seems not to be created anyhow - at least Inspect can't get any window information/handle of the application process - It looks like sort of a "GUI StdOut Redirection".
Apparently, no additional Desktop is created;
Also apparently, no Mirror Driver is installed;
Using Process Explorer, I found out Winflector adds some thread's to the original application process. I suspect it is about the GUI redirection (by the thread's names);
The application is started by the Winflector server - that is, it has control about the CreateProcess arguments.
What is the most likely technique to be used in this case?
Windows Hook?
Windows Messages interception?
Special Display Driver?
Sort of Memory Device Context?
Where should I start researching to get a similar approach? Any open source project regarding this subject would also be very welcomed.
PS: By my programming experience, this is sort of a whole "new world" - sorry if my questions are redundant/obvious/non-sense.
(1) That is, this application could be spawned, streamed and interact
with the remote client using the same session which a local user is
already logged in, without conflicting the IO (like a regular VNC
would do, for example). PS: At this moment, I'm focusing only at the
output.

Autoupdating a windows application without using a separate program

I am looking for ways to enable silent auto updates for my windows application. The update process should be such that only the changed files are downloaded and replaced. So, I have planned to integrate it with my application. Considering the fact that renaming/moving a running executable (or its folder) is possible, Is it alright to use the application to update itself?. Is renaming/moving a running executable dangerous?. What are all the advantages of using a separate updater program over using the application itself to update it?
Thanks!.
I think the main disadvantage with allowing the application to update itself is that it makes it harder to be sure that all activity has stopped, for example that all asynchronous I/O has completed, all user interface elements closed, and all data flushed to disk. Typically, with a separate updater, the application process will exit before the update begins so that you can be certain nothing is happening that will interfere with (or be interfered with by) the update process.
If you're just trying to avoid having a separate build, you could design the application so that after downloading the new content it makes a copy of itself (or, if the updater component has itself been updated, extracts a copy of the new version of itself) in a temporary location and launches this copy in update mode. An application that decides at launch-time whether it is being an updater instance or a regular instance is easy to design and doesn't have the problem mentioned above.
The windows operating system will not let you overwrite an application which is running. You need another application to do that. One process I have is that I have my downloader application download files but if they are in use they are given the extension .update.
My application then when it starts looks for any files with that extension in the folder and sub-folders. If it finds one it will launch a patcher application and terminate itself. The patcher waits for the program files to become free and then moved the .update files over the top of the application files and restarts the application.
It takes a split second extra to launch when there are updates but the user doesn't notice.
In addition:
The advantage of a separate updater program is about modularity and cleanliness. You could reuse the updater software and its code is probably not core to what your application is doing. Plus unless you make it multi-threaded its going to impact the interactivity of your application whilst it working.
I've seen a lot of programmers go for the monolithic approach to deployment (with static builds), however modularity still has major benefits if you ask me.

Why are my auto-run applications acting weird on Vista?

The product we are working on allows the user to easily set it up to run automatically whenever the computer is started. This is helpful because the product is part of the basic work environment of most of our users.
This feature was implemented not so long ago and for a while all was well, but when we started testing this feature on Vista the product started behaving really weird on startup. Specifically, our product makes use of another product (lets call it X) that it launches whenever it needs its services. The actual problem is that whenever X is launched immediately after log-on, it crashes or reports critical errors related to disk access (this happens even when X is launched directly - not through our product).
This happens whenever we run our product by registering it in the "Run" key in the registry or place a shortcut to it in the "Startup" folder inside the "Start Menu", even when we put a delay of ~20 seconds before actually starting to run. When we changed the delay to 70 seconds, all is well.
We tried to reproduce the problem by launching our product manually immediately after logon (by double-clicking on a shortcut placed on the desktop) but to no avail.
Now how is it possible that applications that run normally a minute after logon report such hard errors when starting immediately after logon?
This is the effect of a new feature in Vista called "Boxing":
Windows has several mechanisms that allow the user/admin to set up applications to automatically run when windows starts. This feature is mostly used for one of these purposes:
1. Programs that are part of the basic work environment of the user, such that the first action the user would usually take when starting the computer is to start them.
2. All sorts of background "agents" - skype, messenger, winamp etc.
When too many (or too heavy) programs are registered to run on startup the end result is that the user can't actually do anything for the first few seconds/minutes after login, which can be really annoying. In comes Vista's "Boxing" feature:
Briefly, Vista forces all programs invoked through the Run key to operate at low priority for the first 60 seconds after login. This affects both I/O priority (which is set to Very Low) and CPU priority. Very Low priority I/O requests do not pass through the file cache, but go directly to disk. Thus, they are much slower than regular I/O.
The length of the boxing period is set by the registry value:
"HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\DelayedApps\Delay_Sec".
For a more detailed explanation see here and here
The program probably needs some more info put into its properties. It needs to "Run As", instead of just running.
Maybe this application should be developed as a service, instead of a program to be launched, or you could have service that launches the program when its determined the best window of opportunity.

Resources