为什么schtasks无法识别XML语法?

红衣主教-恢复莫妮卡

我试图通过从Java执行schtasks将计划的任务XML导入Windows Task Scheduler。在我的程序运行schtasks命令之前,它将在<Command>元素中插入一个文件路径任务计划程序命令我编辑XML之前有效,但之后则无效。它一直给我同样的错误:

ERROR: The task XML is malformed.

(1,2)::ERROR: incorrect document syntax

有趣的是,taskschd.msc毫不费力地导入了我的任务。仅仅是schtasks给我带来麻烦。如果我使用taskchd.msc手动输入文件路径,然后将其导出,则它与我的程序输出的XML完全匹配,但是schtasks接受它。这使我相信它与文件编码有关。话虽这么说,我使用taskchd.msc生成的UTF-16格式编码文件,所以我也怀疑它可能与javax.xml库处理文档的方式有关我在互联网上四处寻找答案,但是我只能找到有缺陷的Powershell脚本和实际上格式错误的XML文档的结果。那么到底是什么引起了这个问题,我该如何解决呢?

这是我的程序编辑XML文档和执行schtasks的方式:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(f2); // f2 is the XML file
Node n = document.getElementsByTagName("Command").item(0);
// f is the target executable that this task will execute
n.setTextContent("\"" + f.getAbsolutePath() + "\"");

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-16");
Result output = new StreamResult(f2);
Source input = new DOMSource(document);

transformer.transform(input, output);

ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "schtasks", "/Create", "/TN", taskName, "/XML",
        "\"" + f2.getAbsolutePath() + "\"");
Process p = builder.start();

这是传递给schtasks的最终XML文件:

<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<Task xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task" version="1.2">
  <RegistrationInfo>
    <Date>2020-09-11T16:33:30</Date>
    <Author>CardinalSystem</Author>
    <URI>\LOTHStartupScheduler</URI>
  </RegistrationInfo>
  <Triggers>
    <LogonTrigger>
      <StartBoundary>2020-09-11T16:33:00</StartBoundary>
      <Enabled>true</Enabled>
    </LogonTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <GroupId>S-1-5-32-545</GroupId>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>"C:\Users\Cardinal System\Desktop\TaskScheduler.exe"</Command>
      <Arguments>-startup 1</Arguments>
    </Exec>
  </Actions>
</Task>
坎帕内罗

我认为该MSDN页面可以提供有价值的信息来解决您的问题。

就像您还指出的那样,该帖子暗示该问题与XML文件的编码有关(请参阅最新答案):

即使任务计划程序将任务文件导出为UTF-16编码,它也会拒绝读取它,除非它是UTF-8。使用文本编辑器(如TextPad或Notepad ++)将XML保存为UTF-8编码的文件,任务计划程序将正确导入它(即使主XML标签显示encoding =“ UTF-16”)。

在您的代码中,您将其指示UTF-16为所需的输出编码。在我的机器上,如果使用macOS,则使用该配置Transformer会在UTF-16 Big Endian中生成一个文件。

如上述文章所述,此编码似乎不受支持:

是的,这些编码与schtasks导入xml文件一起工作(将编码Notepad命名为它们):Unicode Ansi,而不能:Unicode big endian,UTF-8

不幸的是,最后一个答案并没有提供太多帮助。看到这篇文章。

不过,您可以尝试将程序修改为output UTF-8

为此,显然,您只需要在代码中更改此行:

transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

再次不幸的是,这也可能很棘手

如果是这种情况,可以尝试如下操作:

String taskName = "taskname";
File f = new File("C:\\Users\\Cardinal System\\Desktop\\TaskScheduler.exe");
File f2 = new File("C:\\Users\\Cardinal System\\Desktop\\input.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(f2); // f2 is the XML file
Node n = document.getElementsByTagName("Command").item(0);
// f is the target executable that this task will execute
n.setTextContent("\"" + f.getAbsolutePath() + "\"");

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

File fout = new File("/Users/jccampanero/Desktop/output.xml");
Writer out = null;

try {
  out = new OutputStreamWriter(new FileOutputStream(fout), Charset.forName("UTF-8"));

  out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");

  Source input = new DOMSource(document);
  Result output = new StreamResult(out);

  transformer.transform(input, output);

  out.flush();
} finally {
  if (out != null) {
    try {
      out.close();
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }
  }
}

ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "schtasks", "/Create", "/TN", taskName, "/XML",
    "\"" + fout.getAbsolutePath() + "\"");
Process p = builder.start();

如果仍然不起作用,则可以尝试使用其他编码方式,例如计算机上的默认编码方式,或者尝试使用其他序列化方法document

Writer writer = new FileWriter("C:\\Users\\Cardinal System\\Desktop\\output.xml");
XMLSerializer xml = new XMLSerializer(writer, null);
xml.serialize(document);

请注意,该代码段FileWriter幕后使用了依次将默认字符编码应用于XML的代码。请参阅此堆栈溢出问题以获取更多信息。

因此,我最好的客人是,可能以一种或另一种方式应用计算机的默认编码将达到目的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么 .NET 无法识别 Lambda 语法?

来自分类Dev

为什么无法识别“ \ xff”?

来自分类Dev

为什么无法识别路线?

来自分类Dev

为什么antrl4无法将标记识别为语法规则的一部分?

来自分类Dev

为什么此Javascript无法识别鼠标?

来自分类Dev

为什么流无法识别我的类型?

来自分类Dev

为什么concat在Teradata中无法识别?

来自分类Dev

为什么无法识别FORMAT功能?

来自分类Dev

为什么unicodedata无法识别某些字符?

来自分类Dev

为什么在WebForms中无法识别ruleSet?

来自分类Dev

为什么Glassfish无法识别罐子?

来自分类Dev

为什么Pillow无法识别JPEG格式?

来自分类Dev

为什么ptrace无法识别该功能?

来自分类Dev

为什么gcc无法识别-rdynamic选项?

来自分类Dev

为什么实例变量无法识别

来自分类Dev

为什么Rails无法识别路线

来自分类Dev

为什么无法识别多个条件?

来自分类Dev

为什么Min函数无法被ksql识别

来自分类Dev

为什么Docker无法识别其网络?

来自分类Dev

为什么无法识别我的PATH更改?

来自分类Dev

为什么在scala中无法识别proc?

来自分类Dev

为什么gcc无法识别-rdynamic选项?

来自分类Dev

为什么Make无法识别我的变量?

来自分类Dev

为什么Oracle Linux无法识别virtio?

来自分类Dev

为什么“自我”无法识别?

来自分类Dev

为什么无法识别Seq.chunkBySize

来自分类Dev

为什么对元素的这种引用无法识别?

来自分类Dev

为什么在语音识别 C# 中需要语法

来自分类Dev

Python语法-无法看到为什么接收语法错误