Start implementing task scheduler
This commit is contained in:
parent
591d431226
commit
a68952653c
@ -397,7 +397,7 @@ public class MainSettingsController {
|
||||
|
||||
@FXML
|
||||
private void handleTestConnectionButtonPress() {
|
||||
// TODO
|
||||
WindowsScheduler.registerSchedule(settings);
|
||||
}
|
||||
|
||||
public StringProperty stationAddressProperty() {
|
||||
|
@ -0,0 +1,238 @@
|
||||
package name.nathanmcrae.numbersstation;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class WindowsScheduler {
|
||||
private static final Logger logger = Logger.getLogger(Main.class.getName());
|
||||
|
||||
public static Document generateScheduleDocument(String authorName, String userId) throws ParserConfigurationException {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||
|
||||
// Root element
|
||||
Document doc = docBuilder.newDocument();
|
||||
Element rootElement = doc.createElement("Task");
|
||||
rootElement.setAttribute("version", "1.2");
|
||||
rootElement.setAttribute("xmlns", "http://schemas.microsoft.com/windows/2004/02/mit/task");
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
// RegistrationInfo element
|
||||
Element registrationInfo = doc.createElement("RegistrationInfo");
|
||||
rootElement.appendChild(registrationInfo);
|
||||
|
||||
Element date = doc.createElement("Date");
|
||||
date.appendChild(doc.createTextNode("2025-01-22T22:09:01.6765321"));
|
||||
registrationInfo.appendChild(date);
|
||||
|
||||
Element author = doc.createElement("Author");
|
||||
author.appendChild(doc.createTextNode(authorName));
|
||||
registrationInfo.appendChild(author);
|
||||
|
||||
Element uri = doc.createElement("URI");
|
||||
uri.appendChild(doc.createTextNode("\\test task"));
|
||||
registrationInfo.appendChild(uri);
|
||||
|
||||
// Triggers element
|
||||
Element triggers = doc.createElement("Triggers");
|
||||
rootElement.appendChild(triggers);
|
||||
|
||||
Element calendarTrigger = doc.createElement("CalendarTrigger");
|
||||
triggers.appendChild(calendarTrigger);
|
||||
|
||||
Element startBoundary = doc.createElement("StartBoundary");
|
||||
startBoundary.appendChild(doc.createTextNode("2025-01-22T22:08:06"));
|
||||
calendarTrigger.appendChild(startBoundary);
|
||||
|
||||
Element enabled = doc.createElement("Enabled");
|
||||
enabled.appendChild(doc.createTextNode("true"));
|
||||
calendarTrigger.appendChild(enabled);
|
||||
|
||||
Element randomDelay = doc.createElement("RandomDelay");
|
||||
randomDelay.appendChild(doc.createTextNode("PT1H"));
|
||||
calendarTrigger.appendChild(randomDelay);
|
||||
|
||||
Element scheduleByDay = doc.createElement("ScheduleByDay");
|
||||
calendarTrigger.appendChild(scheduleByDay);
|
||||
|
||||
Element daysInterval = doc.createElement("DaysInterval");
|
||||
daysInterval.appendChild(doc.createTextNode("1"));
|
||||
scheduleByDay.appendChild(daysInterval);
|
||||
|
||||
// Principals element
|
||||
Element principals = doc.createElement("Principals");
|
||||
rootElement.appendChild(principals);
|
||||
|
||||
Element principal = doc.createElement("Principal");
|
||||
principal.setAttribute("id", "Author");
|
||||
principals.appendChild(principal);
|
||||
|
||||
Element userIdElement = doc.createElement("UserId");
|
||||
userIdElement.appendChild(doc.createTextNode(userId));
|
||||
principal.appendChild(userIdElement);
|
||||
|
||||
Element logonType = doc.createElement("LogonType");
|
||||
logonType.appendChild(doc.createTextNode("InteractiveToken"));
|
||||
principal.appendChild(logonType);
|
||||
|
||||
Element runLevel = doc.createElement("RunLevel");
|
||||
runLevel.appendChild(doc.createTextNode("LeastPrivilege"));
|
||||
principal.appendChild(runLevel);
|
||||
|
||||
// Settings element
|
||||
Element settings = doc.createElement("Settings");
|
||||
rootElement.appendChild(settings);
|
||||
|
||||
Element multipleInstancesPolicy = doc.createElement("MultipleInstancesPolicy");
|
||||
multipleInstancesPolicy.appendChild(doc.createTextNode("IgnoreNew"));
|
||||
settings.appendChild(multipleInstancesPolicy);
|
||||
|
||||
Element disallowStartIfOnBatteries = doc.createElement("DisallowStartIfOnBatteries");
|
||||
disallowStartIfOnBatteries.appendChild(doc.createTextNode("true"));
|
||||
settings.appendChild(disallowStartIfOnBatteries);
|
||||
|
||||
Element stopIfGoingOnBatteries = doc.createElement("StopIfGoingOnBatteries");
|
||||
stopIfGoingOnBatteries.appendChild(doc.createTextNode("true"));
|
||||
settings.appendChild(stopIfGoingOnBatteries);
|
||||
|
||||
Element allowHardTerminate = doc.createElement("AllowHardTerminate");
|
||||
allowHardTerminate.appendChild(doc.createTextNode("true"));
|
||||
settings.appendChild(allowHardTerminate);
|
||||
|
||||
Element startWhenAvailable = doc.createElement("StartWhenAvailable");
|
||||
startWhenAvailable.appendChild(doc.createTextNode("false"));
|
||||
settings.appendChild(startWhenAvailable);
|
||||
|
||||
Element runOnlyIfNetworkAvailable = doc.createElement("RunOnlyIfNetworkAvailable");
|
||||
runOnlyIfNetworkAvailable.appendChild(doc.createTextNode("false"));
|
||||
settings.appendChild(runOnlyIfNetworkAvailable);
|
||||
|
||||
Element idleSettings = doc.createElement("IdleSettings");
|
||||
settings.appendChild(idleSettings);
|
||||
|
||||
Element stopOnIdleEnd = doc.createElement("StopOnIdleEnd");
|
||||
stopOnIdleEnd.appendChild(doc.createTextNode("true"));
|
||||
idleSettings.appendChild(stopOnIdleEnd);
|
||||
|
||||
Element restartOnIdle = doc.createElement("RestartOnIdle");
|
||||
restartOnIdle.appendChild(doc.createTextNode("false"));
|
||||
idleSettings.appendChild(restartOnIdle);
|
||||
|
||||
Element allowStartOnDemand = doc.createElement("AllowStartOnDemand");
|
||||
allowStartOnDemand.appendChild(doc.createTextNode("true"));
|
||||
settings.appendChild(allowStartOnDemand);
|
||||
|
||||
Element enabledSetting = doc.createElement("Enabled");
|
||||
enabledSetting.appendChild(doc.createTextNode("true"));
|
||||
settings.appendChild(enabledSetting);
|
||||
|
||||
Element hidden = doc.createElement("Hidden");
|
||||
hidden.appendChild(doc.createTextNode("false"));
|
||||
settings.appendChild(hidden);
|
||||
|
||||
Element runOnlyIfIdle = doc.createElement("RunOnlyIfIdle");
|
||||
runOnlyIfIdle.appendChild(doc.createTextNode("false"));
|
||||
settings.appendChild(runOnlyIfIdle);
|
||||
|
||||
Element wakeToRun = doc.createElement("WakeToRun");
|
||||
wakeToRun.appendChild(doc.createTextNode("false"));
|
||||
settings.appendChild(wakeToRun);
|
||||
|
||||
Element executionTimeLimit = doc.createElement("ExecutionTimeLimit");
|
||||
executionTimeLimit.appendChild(doc.createTextNode("PT72H"));
|
||||
settings.appendChild(executionTimeLimit);
|
||||
|
||||
Element priority = doc.createElement("Priority");
|
||||
priority.appendChild(doc.createTextNode("7"));
|
||||
settings.appendChild(priority);
|
||||
|
||||
// Actions element
|
||||
Element actions = doc.createElement("Actions");
|
||||
actions.setAttribute("Context", "Author");
|
||||
rootElement.appendChild(actions);
|
||||
|
||||
Element exec = doc.createElement("Exec");
|
||||
actions.appendChild(exec);
|
||||
|
||||
Element command = doc.createElement("Command");
|
||||
command.appendChild(doc.createTextNode("notepad.exe"));
|
||||
exec.appendChild(command);
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
public static String getUserId() throws IOException, InterruptedException {
|
||||
Process process = new ProcessBuilder("whoami", "/user").start();
|
||||
process.waitFor();
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.contains("S-")) {
|
||||
return line.split("\\s+")[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void registerSchedule(StationSettings settings) {
|
||||
Path tempFile = null;
|
||||
try {
|
||||
String taskName = "numbers-station-main_" + settings.getName();
|
||||
|
||||
Document doc = generateScheduleDocument(System.getProperty("user.name"), getUserId());
|
||||
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
DOMSource source = new DOMSource(doc);
|
||||
|
||||
tempFile = Files.createTempFile("task", ".xml");
|
||||
StreamResult result = new StreamResult(tempFile.toFile());
|
||||
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(tempFile)) {
|
||||
writer.write("<?xml version=\"1.0\"?>\n");
|
||||
transformer.transform(source, new StreamResult(writer));
|
||||
}
|
||||
|
||||
Process process = new ProcessBuilder("schtasks.exe", "/create", "/tn", taskName, "/xml", tempFile.toString()).start();
|
||||
int exitCode = process.waitFor();
|
||||
|
||||
if (exitCode == 0) {
|
||||
logger.info(taskName + " task registered successfully.");
|
||||
} else {
|
||||
logger.info("Failed to register " + taskName + " task. Exit code: " + exitCode);
|
||||
}
|
||||
} catch (ParserConfigurationException | TransformerException | IOException | InterruptedException e) {
|
||||
logger.log(Level.SEVERE, "Exception while registering schedule", e);
|
||||
} finally {
|
||||
if (tempFile != null) {
|
||||
try {
|
||||
Files.delete(tempFile);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, "Failed to delete temporary file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user