zoukankan      html  css  js  c++  java
  • C#多进程打开PPT的方法

    1、背景

    PPT文件打开和操作是在一个进程中进行的,如果对多个PPT进行操作,PowerPoint进程默认会以阻塞的方式依次进行,如果打开的PPT特别大(比如超过1GB)很容易造成PPT无响应,这样几乎所有的PPT操作都无法进行。

    解决PPT无响应的一种方式是定时检测PPT进程(POWERPNT.exe)是否无响应,如果无响应就将POWERPNT.exe进程Kill掉,重新打开PPT。这种方式并不能解决需要多个PPT操作的问题,如果多个PPT文件都很大,操作多个PPT会频繁出现PPT无响应的情况。

    解决PPT无响应的另一种方式是使用多进程方式打开PPT。PPT默认是无法使用多个进程打开的,在使用不同用户打开PPT的情况下,可以打开不同的PPT进程,其原因见参考文档。

    2、具体方法

    使用多用户打开PPT的方法,首先需要内置不同的用户,这可以通过代码实现(需要管理员权限),也能通过Windows用户设置添加指定的用户。使用代码操作用户稍后会有参考代码。

    其次是使用指定用户(及密码)启动封装好PPT操作的进程,然后通过进程间通信的方式(管道、COPYDATA 消息、MQTT,推荐管道或者COPYDATA消息,不用依赖第三方库)进行PPT控制(打开、翻页、跳转、媒体控制等)。

    3、参考代码

    (1)使用指定用户打开进程的代码片段(args参数可以传递管道名称或者自定义消息)

    public void StartProcess(string fileName, string userName, string password, string args)
    {
        var pwd = new SecureString();
        if (!string.IsNullOrEmpty(password))
        {
            password.ToCharArray().ToList().ForEach(c => pwd.AppendChar(c));
        }
    
        try
        {
            var process = new Process
            {
                StartInfo =
                {
                    UseShellExecute = false,
                    LoadUserProfile = true,
                    UserName = userName,
                    Password = pwd,
                    Domain = ".",
                    FileName = $""{fileName}"",
                    Arguments = args
                }
            };
            process.Start();
        }
        finally
        {
            pwd.Dispose();
        }
    }

    (2)PPT操作片段

    private void OpenPpt()
    {
        var app = new Microsoft.Office.Interop.PowerPoint.Application();
    }
    
    private void ClosePpt(ref Application app)
    {
        try
        {
            app?.Quit();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    
        app = null;
        GC.Collect();
    }
    
    public void Open(object app, string filePath)
    {
        var ppt = app as Microsoft.Office.Interop.PowerPoint.Application;
        if (ppt == null)
        {
            return;
        }
    
        //正斜杠替换为反斜杠
        filePath = filePath.Replace('/', '\');
    
        try
        {
            //以只读方式打开,方便操作结束后保存
            //使用一个不可能为密码的值(AssemblyGuid)作为密码打开PPT,保证有密码时打开失败
            var presentation = ppt.Presentations.Open(
                $"{filePath}::{Password}",
                MsoTriState.msoTrue, //ReadOnly: true
                MsoTriState.msoTrue, //Untitled: true
                MsoTriState.msoFalse); //WithWindow: false
    
            //获取真实宽高
            var officeWidth = presentation.PageSetup.SlideWidth;
            var officeHeight = presentation.PageSetup.SlideHeight;
    
            //获取页数
            var pageNumber = presentation.Slides.Count;
    
            var slideShowSettings = presentation?.SlideShowSettings;
            if (slideShowSettings == null)
            {
                return;
            }
    
            var window = slideShowSettings.Run();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
    
    public void Close(SlideShowWindow window)
    {
        try
        {
            window?.View.Exit();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
    
    public void GotoSlide(SlideShowWindow window, int index)
    {
        try
        {
            window?.View.GotoSlide(index);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
    
    public void Next(SlideShowWindow window)
    {
        try
        {
            window?.View.Next();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
    
    public void Previous(SlideShowWindow window)
    {
        try
        {
            window?.View.Previous();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

    4、参考文档

    (1)我是如何让PowerPoint能够多进程同时导出的

  • 相关阅读:
    vs 2015 "加载该页时出错。" 解决方案
    Web API使用HttpResponseMessage与HttpResponseException的差异 HttpResponseMessage 返回类型
    a标签使用href=”javascript:void(0); 在火狐浏览器跟chrome 不兼容
    SQL语句 转
    Fiddler抓包 截包伪造提交包
    图片懒加载
    dropzone 上传插件
    MVC5+EF6 完整教程 转
    用Aspose.Cell控件导入Excel非强类型的数据
    利用Aspose.Word控件实现Word文档的操作
  • 原文地址:https://www.cnblogs.com/xhubobo/p/13427198.html
Copyright © 2011-2022 走看看