C# 服务器上MS Office的远程自动化

C# 服务器上MS Office的远程自动化,c#,wcf,interop,ms-office,.net-remoting,C#,Wcf,Interop,Ms Office,.net Remoting,我警告你,这个问题对很多人来说似乎很奇怪:)但我必须发布它,因为我的项目经理正在告诉我存在一个技术解决方案,即使对我来说它并不存在 我们所拥有的: 一个Windows 7控制台应用程序,没有UI,我们的C#应用程序正在运行,没有Office和互操作 Windows 2012服务器,安装了Ms Office 2010+Interop(当然还有IIS和.NET) 我的首相想要什么(我告诉他这是不可能的): 从我的C#客户端应用程序 自动化服务器上安装的“Ms office” 自动化意味着将文档

我警告你,这个问题对很多人来说似乎很奇怪:)但我必须发布它,因为我的项目经理正在告诉我存在一个技术解决方案,即使对我来说它并不存在

我们所拥有的:

  • 一个Windows 7控制台应用程序,没有UI,我们的C#应用程序正在运行,没有Office和互操作
  • Windows 2012服务器,安装了Ms Office 2010+Interop(当然还有IIS和.NET)
我的首相想要什么(我告诉他这是不可能的):

  • 从我的C#客户端应用程序
  • 自动化服务器上安装的“Ms office”
  • 自动化意味着将文档文件“保存”或“打印”到网络打印机
  • 当然,Ms office进程必须在服务器上运行
这种“远程Ms办公自动化是可能的”的解决方案对我来说似乎是不可能的。但也许我错了,可能是使用DCOM、WCF或其他什么


请任何人确认我是对的;)

正如您已经从评论中了解到的,自动化任何Office应用程序的桌面版本都不好,原因有几个。有关详细信息,请参阅知识库文章KB257757。该条的主要内容是:

Microsoft目前不建议也不支持从任何无人参与、非交互式客户端应用程序或组件(包括ASP、ASP.NET、DCOM和NT服务)自动化Microsoft Office应用程序,因为在该环境中运行Office时,Office可能会表现出不稳定的行为和/或死锁

但是,您仍然坚持认为,下面的例子是一个非常简单、幼稚、不被使用的近乎生产证明的概念,使您能够快速地处理KB文章中提到的所有问题。

在新的解决方案中,创建WCF服务应用程序和控制台应用程序。在WCF应用程序中,添加以下接口:

[ServiceContract]
public interface IPrintService
{
    [OperationContract]
    string Print(Stream wordDoc);
}
并有一个服务来实现这一点。确保添加对Microsoft.Office.Interop.Word的引用,该引用可在“添加引用”对话框的“COM”选项卡中找到

public class PrintService : IPrintService
{
    public string Print(Stream wordDocStream)
    {
        // copy our stream to a local file
        var tempFile = Path.GetTempFileName();
        using(var file = File.Create(tempFile))
        {
            wordDocStream.CopyTo(file);
        }

        // start word
        var wordApp = new Microsoft.Office.Interop.Word.Application();
        // setup printer
        wordApp.ActivePrinter = "Canon LBP3010/LBP3018/LBP3050";
        // open, collect data, print and close
        var doc = wordApp.Documents.Open(tempFile);
        doc.PrintOut();
        var res = doc.Words.Count;
        doc.Close(false);

        // quit word
        wordApp.Quit(false);
        // delete temp file
        File.Delete(tempFile);
        return String.Format("{0} words", res);
    }
}
您可以在这里看到一个基本的解决方案,用于打印作为流发送到服务的文档。该服务将流复制到一个文件中,启动Word,打开文件,打印文档,从文档中获取一些数据,并在完成后进行分解和清理

客户是直截了当的:

using(var client = new PrintService.PrintServiceClient())
{
    using(var file = File.Open(@"small.docx", FileMode.Open))
    {
        var response = client.Print(file);
        Console.WriteLine(response);
    }
}
从技术上讲,这就是从服务打印Word文档所需的全部内容。这在dev服务器上运行时没有太多问题。如果在IIS上运行此操作,您可能必须确保应用池中用作标识的帐户是可以启动Word的“用户”,允许访问打印机等。我已经遇到一个已知问题:我使用了XPS打印驱动程序,导致弹出一个对话框。这是服务器上无法实现的,并且没有真正的方法来防止或检测

请记住,此服务接口仅允许发送流。如果您想添加额外的数据,您必须使用消息约定,如中的msdn中所述。在这种情况下,您的合同必须如下所示:

[MessageContract]
public class UploadStreamMessage
{
   [MessageHeader]
   public string appRef;
   [MessageBodyMember]
   public Stream data;
} 

如果你运行所有这些(压力测试),考虑部署和安装,我确信你会说服任何人,这不是一个好主意。

澄清,他希望你做的是基本上运行在你的应用程序中的远程服务器上安装的Office版本,这样客户端就可以执行所有的功能了吗?或者只是选择要打印的文档并通过安装在远程服务器上的Office打印它们?这当然是可能的,但并不容易。但是,解决方案太复杂,无法在此处作为答案发布。您基本上需要创建一个WCF或Web服务来打印文档,并由您的客户端应用程序调用。@Taegost,我想从客户端应用程序执行操作(打印、保存文档),而不需要在客户端上安装Ms office。互操作的一种远程使用:)@DirkVollmar WS或WCF的解决方案是我向他提出的解决方案,但他告诉我们这太难维护(IIS管理、WS声明……)。但对我来说,这是最可靠的!!“这当然是可能的”。。。这些话对我来说很有趣。。。你有关于它的更多细节吗???@sstassin-它是哪一个?你使用“保存”这个词会使事情变得棘手,因为这意味着除了打印之外还要进行编辑。如果您只需要选择文档和打印,是的,服务器上的服务将是最好的,但是如果他们想在您的应用程序中实现Office,最好设置一些终端服务或Citrix…感谢您提供非常详细的答案。Il将尝试在我们的Intranet Web服务器上实现这一点。我知道微软关于“不在服务器模式下使用微软办公软件”的所有考虑,但现在这是以非常高的精度打印复杂的现有文档的最佳方式。