.NET 导入导出Project(mpp)以及发布后遇到的Com组件问题

news2024/11/24 11:26:52

最近公司项目有一个对Project导入导出的操作,现在市面上能同时对Project进行导入导出的除了微软自带的Microsoft.Office.Interop.MSProject,还有就是Aspose.Tasks for .NET。但因为后者是收费软件且破解版的现阶段只到18.11,只支持.net Framework,而我们的项目是用的netcore,在对Aspose.Tasks破解版进行测试的过程中始终提示“The opreation is not allowed in evaluation model”,未花费过多精力去研究Aspose.Tasks。转战Interop.MSProject,网上还是有相关参考资料,以下是我们的代码,(未进行方法封装优化):

需要用到COM组件:Microsoft.Office.Core以及 Microsoft.Office.Interop.MSProject

导出代码

public static void Export(List<ImportPlanMppModel> result, string fileSavePath)
        {
            Microsoft.Office.Interop.MSProject.ApplicationClass prj = null;
            try
            {
                //创建COM(MSProject)
                prj = new Microsoft.Office.Interop.MSProject.ApplicationClass();
                prj.Visible = true;

                //创建Project
                prj.FileNew(Type.Missing, Type.Missing, Type.Missing, false);

                //prj.SetField("责任人", "", true);
                //prj.SetField("责任人", "", true);
                //prj.CustomFieldValueListAdd(Microsoft.Office.Interop.MSProject.PjCustomField.pjCustomProjectEnterpriseText1, "123", "11", "111", "1232", "456");

                //prj.ShowAddNewColumn(10);
                //prj.AddNewColumn(7);

                Microsoft.Office.Interop.MSProject.Project myProject = prj.ActiveProject;
                Microsoft.Office.Interop.MSProject.PjFileFormat format = Microsoft.Office.Interop.MSProject.PjFileFormat.pjMPP;//format定义
                object missing = System.Reflection.Missing.Value;//missing值 
                                                                 //myProject.AutoTrack = true;

                //.........................................
                //myProject.HoursPerDay = 8;
                //myProject.HoursPerWeek = 56;
                //myProject.DaysPerMonth = 30;
                //Microsoft.Office.Interop.MSProject.WeekDays weedday = myProject.Calendar.WeekDays;
                //weedday[1].set_Working(true);
                //weedday[7].set_Working(true);

                //myProject.ShowCriticalSlack = 0;
                List<Microsoft.Office.Interop.MSProject.Task> taskList = new List<Microsoft.Office.Interop.MSProject.Task>();
                foreach (var item in result)
                {
                    Microsoft.Office.Interop.MSProject.Task task = null;
                    //System.Threading.Thread.Sleep(1000);
                    task = myProject.Tasks.Add(item.TaskName, Type.Missing);//item.Id
                    task.Duration = item.TaskDuration;
                    if (item.TaskPlanStartDate.HasValue)
                    {
                        task.Start = item.TaskPlanStartDate;
                    }
                    if (item.TaskPlanEndDate.HasValue)
                    {
                        task.Finish = item.TaskPlanEndDate;
                    }
                    if (item.TaskActualStartDate.HasValue)
                    {
                        task.ActualStart = item.TaskActualStartDate;
                    }
                    if (item.TaskActualEndDate.HasValue)
                    {
                        task.ActualFinish = item.TaskActualEndDate;
                    }
                    if (item.TaskOutlineLevel > 0)
                    {
                        task.OutlineLevel = Convert.ToInt16(item.TaskOutlineLevel);
                    }
                    //task.Milestone = dr["IsMTask"].ToString() == "1" ? true : false;//是否里程碑:0=否、1=是
                    task.WBS = item.WBS;
                    //负责人
                    task.Text1 = item.ResponsibleUserName;
                    //平米单价
                    if (item.SquareMetrePrice.HasValue)
                    {
                        task.Number1 = Convert.ToDouble(item.SquareMetrePrice);
                    }


                    //标记列
                    task.Notes = item.Id.ToString();
                    //资源名称
                    //task.ResourceNames = "资源名称1,资源名称2";

                    标记列
                    //task.SetField(Microsoft.Office.Interop.MSProject.PjField.pjTaskNotes, "Task1");
                    资源名称
                    //task.SetField(Microsoft.Office.Interop.MSProject.PjField.pjTaskResourceNames, "wenzhixing,wen,zhi");

                    //task.SetField(Microsoft.Office.Interop.MSProject.PjField.pjTaskText1, "负责人");
                    //task.SetField(Microsoft.Office.Interop.MSProject.PjField.pjTaskNumber1, "10.231");

                    //task.Rollup = true;
                    taskList.Add(task);
                }

                for (int i = 0; i < taskList.Count; i++)
                {
                    Microsoft.Office.Interop.MSProject.Task task = taskList[i];
                    var item = result.FirstOrDefault(x=>x.Id.ToString() == task.Notes);

                    ///前置任务
                    if (!string.IsNullOrWhiteSpace(item.TaskPredecessorsIdStr))
                    {
                        for (int j = 0; j < item.TaskPredecessorsIdStr.Split(',').Length; j++)
                        {
                            var dependencTaskId = item.TaskPredecessorsIdStr.Split(',')[j];

                            var dependencTask = taskList.FirstOrDefault(x => x.Notes == dependencTaskId);
                            if (dependencTask != null)
                            {
                                var dependencTaskType = Enum.Parse<Microsoft.Office.Interop.MSProject.PjTaskLinkType>(item.TaskPredecessorsTypeStr.Split(',')[j]);

                                task.TaskDependencies.Add(dependencTask, dependencTaskType, item.TaskPredecessorsDurationStr.Split(',')[j]);
                            }
                        }
                    }
                }
                //保存到指定目录
                prj.FileSaveAs(fileSavePath, format, missing, missing, missing, missing, missing, missing, missing, "MSProject.mpp", missing, missing, missing, missing, missing, missing, missing, missing, missing);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (prj != null)
                {
                    try
                    {
                        //退出COM组件
                        prj.FileClose(Microsoft.Office.Interop.MSProject.PjSaveType.pjDoNotSave);
                        prj.Quit(Microsoft.Office.Interop.MSProject.PjSaveType.pjDoNotSave);
                    }
                    catch
                    {

                    }
                }
            }
        }

导入代码

public static List<ImportPlanMppModel> ImportTasks(string filename)
{
    List<ImportPlanMppModel> result = null;
    if (System.IO.File.Exists(filename) == false)
    {
        throw new FriendlyException("未找到文件信息");
    }
    result = new List<ImportPlanMppModel>();

    ProjectReader reader = ProjectReaderUtility.getProjectReader(filename);
    ProjectFile file = reader.read(filename);
    foreach (net.sf.mpxj.Task task in file.Tasks.ToIEnumerable())
    {
        if (task.ID.toString() == "0") //自动创建的节点,一般为文件名,不需要
        {
            continue;
        }

        ImportPlanMppModel model = new ImportPlanMppModel();
        model.Id = task.ID.intValue();
        model.Guid = Guid.Parse(task.GUID.toString());
        model.UniqueId = task.UniqueID.intValue();
        model.TaskName = task.Name;
        model.TaskDuration = task.Duration.Duration;
        if (task.ParentTask != null && Convert.ToInt32(task.OutlineLevel.toString()) > 1) //是否根节点,mpp文件必须只有一个根节点,否则会报错
        {
            model.ParentId = task.ParentTask.ID.intValue();
            model.ParentGuid = Guid.Parse(task.ParentTask.GUID.toString());
        }

        model.TaskPlanStartDate = task.Start.ToNullableDateTime(); //DateTime.Parse(string.Format("{0:d}", task.Start.ToDateTime())); 
        model.TaskPlanEndDate = task.Finish.ToNullableDateTime();
        model.TaskActualStartDate = task.ActualStart.ToNullableDateTime();
        model.TaskActualEndDate = task.ActualFinish.ToNullableDateTime();
        model.TaskOutlineLevel = task.OutlineLevel.intValue();

        bool isHasChildTask = false;
        if (task.HasChildTasks())
        {
            isHasChildTask = true;
        }
        model.IsHasChildTask = isHasChildTask;
        model.ResponsibleUserName = task.GetText(1);
        model.SquareMetrePrice = task.GetNumber(1).ToNullableDecimal();
        model.WBS = task.WBS;

        string beforeTaskId = string.Empty;
        string beforeTaskGuid = string.Empty;
        string beforeTaskType = string.Empty;
        string beforeTaskDuration = string.Empty;
        if (task.Predecessors != null && task.Predecessors.isEmpty() == false)
        {
            foreach (Relation relation in task.Predecessors.ToIEnumerable())
            {
                beforeTaskId += relation.TargetTask.ID.intValue() + ",";
                beforeTaskGuid += relation.TargetTask.GUID.toString() + ",";
                beforeTaskType += relation.Type.Value + ",";
                beforeTaskDuration += relation.Lag.Duration + ",";
            }
        }
        model.TaskPredecessorsIdStr = beforeTaskId.TrimEnd(',');
        model.TaskPredecessorsGuIdStr = beforeTaskGuid.TrimEnd(',');
        model.TaskPredecessorsTypeStr = beforeTaskType.TrimEnd(',');
        model.TaskPredecessorsDurationStr = beforeTaskDuration.TrimEnd(',');

        result.Add(model);
    }

    return result;
}

发布运行问题

我们的程序版本是使用的32位的project 2016 professional(office也是2016专业增强版的32位),在VS编译调试没有问题,发布到IIS进行测试时,在代码进行到

//创建COM(MSProject)
prj = new Microsoft.Office.Interop.MSProject.ApplicationClass();

会触发异常:"System.Runtime.InteropServices.COMException (0x80010001): Retrieving the COM class factory for component with CLSID {36D27C48-A1E8-11D3-BA55-00C04F72F325} failed due to the following error: 80010001 被呼叫方拒绝接收呼叫。 (0x80010001 (RPC_E_CALL_REJECTED))"。查询了很多相关资料,绝大部分都是说可能是账户权限问题,给除的解决办法也都是去对Com组件进行赋权。

网上大部分解决方案如下:

-在命令行中输入:dcomcnfg,会显示出“组件服务”管理器

-打开“组件服务->计算机->我的电脑->DCOM 配置”,找到“Microsoft Project”,单击右键,选择“属性”

-在“属性”对话框中单击“标识”选项卡,选择“交互式用户””

-然后找到“安全”,把下面所有的权限都选择自定义,然后添加各种用户全部权限。

但对我们项目的代码没有作用,机缘巧合我自己本机是office2010专业增强版64位,project 也是64位的2010专业版,我这边部署到IIS后导出在相同代码提示的是:"Retrieving the COM class factory for component with CLSID {36D27C48-A1E8-11D3-BA55-00C04F72F325} failed due to the following error: 80070005 拒绝访问"。按照如上的网上大部分解决方案配置后依旧有问题,后续对DCOM组件 project basic进行标识配置时,我选择了指定具体的用户

且在IIS进程池的进程模型的标识选择了:LocalSystem,再进行测试时发现可以正常导出,且导出时不会弹出project应用窗口。

在搜索解决方案时,看到过 "HymanLiuTS"的 错误处理(一)—— 被呼叫方拒绝接收呼叫。 (异常来自 HRESULT:0x80010001 (RPC_E_CALL_REJECTED)),在文章里给出了微软的一个解决方案,方案2 引入IOleMessageFilter,从根本上杜绝这种异常情况的出现,

”如何:修复“应用程序正忙”和“被调用者拒绝了调用”错误“,参考官方代码修改了项目里的相应位置的代码,具体修改如下:

MessageFilter.Register();//新增异常处理代码
//创建COM(MSProject)
prj = new Microsoft.Office.Interop.MSProject.ApplicationClass();
if (prj != null)
{
    try
    {
        //退出COM组件
        prj.FileClose(Microsoft.Office.Interop.MSProject.PjSaveType.pjDoNotSave);
        prj.Quit(Microsoft.Office.Interop.MSProject.PjSaveType.pjDoNotSave);
    }
    catch
    {

    }
}
MessageFilter.Revoke();//新增异常处理代码

再将DCOM的标识从指定具体账号更改为交互式用户,iis配置不变也能导出成功,不过在导出文件时会弹出project应用窗口。

注:上述两种处理方式在32位的project 2016上始终未能解决,若您有解决方案,请你留言向您讨教。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/377746.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【博学谷学习记录】超强总结,用心分享丨人工智能 多场景实战 常用英文缩写概念总结

目录PV(Page View)UV(Unique Visitor)CPM(Cost Per Mille)CPC(Cost Per Click)CPA(Cost Per Action)CPI(Cost Per Install)ACU(Average concurrent users)PCU(Peak concurrent users)ARPU(Average Revenue Per User)ARPPU(Average Revenue Per Paying User)LTV(Life Time Value…

Windows系统部署瀚高数据库并在SuperMap iDesktop中使用

目录前言一&#xff1a;Windows系统部署瀚高数据库二&#xff1a;对数据库进行PostGIS扩展三&#xff1a;SuperMap iDesktop中新建HighGoDB数据库型数据源作者&#xff1a;kxj 前言 瀚高数据库是一款对象-关系型数据库&#xff0c;拥有非常丰富的数据库基本功能&#xff0c;涵盖…

【数据结构与算法】图 ( 图的存储形式 | 图的基本概念 | 图的表示方式 | 邻接矩阵 | 邻接表 | 图的创建 | 代码示例 )

文章目录一、图的存储形式二、图的基本概念三、图的表示方式1、邻接矩阵2、邻接表四、图的创建 ( 代码示例 )一、图的存储形式 线性表 中的元素 , 有 一个 直接前驱 和 一个 直接后继 ; 树 中的元素 , 有 一个 直接前驱 和 多个 直接后继 ; 图 中的元素 , 有 多个 直接前驱 和…

常见的视频文件格式有哪些?

常见的视频文件格式有哪些&#xff1f;常见在线流媒体格式&#xff1a;mp4、flv、f4v、webm移动设备格式&#xff1a;m4v、mov、3gp、3g2RealPlayer &#xff1a;rm、rmvb微软格式 &#xff1a;wmv、avi、asfMPEG 视频 &#xff1a;mpg、mpeg、mpe、tsDV格式 &#xff1a;div、…

【学习笔记】构建小型金融知识图谱(github项目)

前言 需要构建农业知识图谱&#xff0c;先来学习一下构建知识图谱的基本流程和套路&#xff0c;熟悉过程方便 科研 后续工作的开展&#xff0c;写下此篇博客作为我的笔记吧~ 参考代码来源&#xff1a;github项目 jm199504/Financial-Knowledge-Graphs 1.知识图谱存储方式 知…

intel的集成显卡(intel(r) uhd graphics) 配置stable diffusion

由于很多商务本没有独立显卡&#xff0c;只有Intel的集成显卡&#xff0c;在配置安装stable diffusion 时候需要特殊对待&#xff0c;参考不少帖子&#xff0c;各取部分现稍加整合。整体思路分两个部分&#xff1a;第一步是先配置环境&#xff0c;主要是安装Anaconda Pytorch&…

Biotin-PEG-SVA,生物素聚乙二醇琥珀酰亚胺戊酸酯,可用于检测或分子标记

Biotin-PEG-SVA 结构式&#xff1a;PEG分子量&#xff1a; 1000&#xff0c;2000&#xff0c;3400&#xff0c;5000&#xff0c;10000中文名称&#xff1a;生物素聚乙二醇琥珀酰亚胺戊酸酯&#xff0c;生物素-PEG-琥珀酰亚胺戊酸酯英文名称&#xff1a;Biotin-PEG-SVA &#xf…

自动化测试项目实战 ——12306火车票网站自动登录工具

还记得前几年春运&#xff0c;12306火车票预订网站经常崩溃无法登录吗。 今天我们就开发一个12306网站自动登录软件。 帮助您轻松订票 通过前两篇博客Fiddler教程和HTTP协议详解&#xff0c;我们了解了Web的原理. Web的原理就是&#xff0c;浏览器发送一个Request给Web服务器…

torchserve安装、模型的部署与测试(基于docker)

问题描述 pytorch 一直很受大家的欢迎&#xff0c;但是作为一个深度模型&#xff0c;与外界复杂的业务需求交互其实是一件比较麻烦的事情&#xff0c;这里 torchserve 提供一个基于 TCP 的交互方法&#xff0c;算法模型部署后&#xff0c;用户可以通过提交 post 请求&#xff…

今天面了个腾讯拿25K出来的软件测试工程师,让我见识到了真正的天花板...

今天上班开早会就是新人见面仪式&#xff0c;听说来了个很厉害的大佬&#xff0c;年纪还不大&#xff0c;是上家公司离职过来的&#xff0c;薪资已经达到中高等水平&#xff0c;很多人都好奇不已&#xff0c;能拿到这个薪资应该人不简单&#xff0c;果然&#xff0c;自我介绍的…

html实现浪漫的爱情日记(附源码)

文章目录1.设计来源1.1 主界面1.2 遇见1.3 相熟1.4 相知1.5 相念2.效果和源码2.1 动态效果2.2 源代码2.3 代码结构源码下载更多爱情表白源码作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/129264757 html实现浪漫的爱情…

Vue3 组合式函数,实现minxins

截至目前&#xff0c;组合式函数应该是在VUE 3应用程序中组织业务逻辑最佳的方法。它让我们可以把一些小块的通用逻辑进行抽离、复用&#xff0c;使我们的代码更易于编写、阅读和维护。 一. 什么是“组合式函数”&#xff1f; 根据官方文档说明&#xff0c;在 Vue 应用的概念中…

你还不会用CAD一键布置停车位?赶紧学起来!

在设计CAD建筑图的过程中&#xff0c;你还在一个一个地画停车位吗&#xff1f;那未免也太低效了吧&#xff01;今天&#xff0c;小编用浩辰CAD建筑软件来教大家一键布置停车位&#xff0c;赶紧学起来吧&#xff01; 浩辰CAD建筑软件是行业应用最广泛的创新型建筑设计专业软件&…

2023软件测试金三银四常见的软件测试面试题-【接口测试】

九、接口测试 9.1 接口测试怎么测 &#xff08;jmeter版本&#xff09; 首先开发会给我们一个接口文档&#xff0c;我们根据开发给的接口文档&#xff0c;进行测试点的分析&#xff0c;主要是考虑正常场景与异常场景&#xff0c;正常场景&#xff0c;条件的组合&#xff0c;…

uni-app实现可滑动日历

效果&#xff1a; uni-calendar.vue <template><view class"uni-calendar"><view v-if"!insert&&show" class"uni-calendar__mask" :class"{uni-calendar--mask-show:aniMaskShow}" click"clean"&…

项目难点——【4】分布式事务

项目难点——【4】分布式事务 1 概述 我们想知道什么是分布式事务首先了解下什么是本地事务。 平常我们在程序中通过spring去控制事务是利用数据库本身的事务特性来实现的&#xff0c;因此叫数据 库事务&#xff0c;由于应用主要靠关系数据库来控制事务&#xff0c;而数据库通…

顺序表(2)

目录 1、线性表 2、顺序表 1、概念及结构 2、接口实现 1、SeqList.h 2、SeqList.c 3、练习 例1、移除元素 例2、删除有序数组中的重复项 例3、合并两个有序数组 1、线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列&#xff…

运行你的第一个 Django APP

Django 版本&#xff1a;4.1.7 Python 版本&#xff1a;3.9.13 目录一、运行 Django二、创建 APP一、运行 Django 1、新建项目&#xff08;Project&#xff09; 项目类型为 Django&#xff0c;选择虚拟环境&#xff0c;点击 Create 后就会自动下载并安装 Django。 如果你是在 …

机器学习——支持向量机学习

支持向量机(Support Vector Machine, SVM)不仅具有坚实的统计学理论基础,还可以很好地应用于高维数据、避免维度灾难问题&#xff0c;已经成为一种倍受关注的机器学习分类技术。为了解释SVM的基本思想,我们首先介绍一下最大边缘超平面(Maximal Margin Hyperplane)给定训练数据集…

C++STL详解(三)——vector的介绍和使用

文章目录vector的介绍vector的使用vector的定义方式vector的空间增长问题reserve和resizevector的迭代器使用begin 和endrbegin和rendinsert 和erasefind函数元素访问vector迭代器失效问题1&#xff1a;inserse插入扩容时空间销毁造成野指针问题2&#xff1a;erase删除或者inse…