问题
Trying to set up c# console program that converts pdf to html using Word as intermediary. Works from command line when logged in, but will not do when run from scheduler. Now I know MS do not officially support this- https://support.microsoft.com/en-us/help/257757/considerations-for-server-side-automation-of-office - but no the less I wish to pursue this avenue. I have seen various posts on workarounds, but have failed to get it to work.
In short program stalls at the point of opening the document.
Can anyone advise on what steps can be taken to workaround this MS implemented restriction.
namespace InterOpTest
{
class Program
{
static void Main(string[] args)
{
Microsoft.Office.Interop.Word.Application oWord = new Microsoft.Office.Interop.Word.Application();
String sFolder = "C:\\temp";
String sInputFile =sFolder+"\\input.pdf";
String sOutputFile = sFolder+"\\test\\output.html";
String sLogFile = sFolder + "\\Interoptest.log";
System.IO.DirectoryInfo d = new DirectoryInfo(sFolder);
// StreamWriter sw= new StreamWriter(sLogFile);
StreamWriter sw = File.AppendText(sLogFile);
try
{
sw.WriteLine("");
sw.WriteLine(DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss") + ", Deleting any pre-existing version of " + sOutputFile);
File.Delete(sOutputFile);
sw.WriteLine(DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss") + ", Opening "+sInputFile);
oWord.Documents.Open(sInputFile);
sw.WriteLine(DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss") + ", saving as " + sOutputFile);
oWord.ActiveDocument.SaveAs2(sOutputFile, FileFormat: 10);
oWord.Quit();
oWord = null;
sw.WriteLine(DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss") + ", Done");
}
catch (Exception e) {
sw.WriteLine(DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss") + ", Error :"+ e.Message);
}
finally
{
sw.Close();
Console.WriteLine("Done");
}
}
}
}
回答1:
Depending wich format you are working with, there are 3 basic cases.
- if you only need the modern Formats (like docx), you can use the OpenXML SDK. Additional Options include any wrapper for it or even the ZipArchive and XMLreader classes - the modern formats are that easy and well known.
- if you also need to support the older formats (like .doc) the main way is the (t)rusty Office COM Interop. That one suffers all the normal limits of COM interop and also needs a Interative Session and Office installed to work.
- For any given format, any given Operation and any given Frontend (WinForms, ASP.Net) there might be a 3rd way to do stuff. But those are far in between and can no be relied on.
My advise is to always use the OpenXML SDK. Try to bury the idea of supporting the old formats and just convert the old files to the new formats.
The Interop is very dated and has a bunch of extra issues. But as we always had it as fallback, .NET never quite got a complete library to read and work the old office formats.
My guess is that you are running into the lack of a Interactive Session. You may be able to force the TaskSheduler to give you a interactive session. After all, there is no Security need like there is for Services. But I still would advise to just start ingoring the old school way and go for the Modern Formats only. The old ones really outlived their time.
回答2:
As far as I understand there are no workarounds.
Office Interop(and other GUI-dependent libraries) will work normally only in the interactive desktop session.
And as
- https://serverfault.com/questions/458848/can-i-schedule-a-windows-task-to-run-in-an-interactive-desktop-session
- A workaround for the fact that a scheduled task in Windows requires a user to be logged in
say there aren't any indirect options to achieve it.
So you should either
- run/schedule the application as the currently logged in user.
- or bite the bullet and switch to OpenXML/another alternative as Christopher's answer proposes.
来源:https://stackoverflow.com/questions/57316086/office-interop-run-via-task-scheduler