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

这篇具有很好参考价值的文章主要介绍了.NET 导入导出Project(mpp)以及发布后遇到的Com组件问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近公司项目有一个对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进行标识配置时,我选择了指定具体的用户

c# 导出mpp,NETCore,.netcore,DCOM,Project,MPP,Powered by 金山文档

且在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上始终未能解决,若您有解决方案,请你留言向您讨教。文章来源地址https://www.toymoban.com/news/detail-686168.html

到了这里,关于.NET 导入导出Project(mpp)以及发布后遇到的Com组件问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • docker导入导出镜像、导入导出容器的命令详解以及使用的场景

    这是一对操作,用于处理 Docker 镜像。这个操作会将所有的镜像层以及元数据打包到一个 tar 文件中。然后,你可以使用 docker load 命令将这个 tar 文件导入到任何 Docker 环境中。例如: 这种方式主要用于分享或迁移整个镜像,包括所有版本、标签和历史。 这也是一对操作,用

    2024年02月16日
    浏览(47)
  • 基于.Net开发的数据库导入导出的开源项目

    在项目开发过程中,我们经常碰到从数据库导入导出的需求,虽然这样的功能不是很复杂,但是往往我们都会碰到一些问题。 比如导入的Excel格式问题、Excetl中图片导入问题,导出的需求为了方便客户查看,会面临更多个性化的需求,为了满足这些需求,开发还是比较繁琐的

    2024年02月02日
    浏览(58)
  • .NET Core6.0使用NPOI导入导出Excel

    一、使用NPOI导出Excel //引入NPOI包 HTML JS C# 二、使用NPOI导入Excel HTML JS C# 控制器代码 添加ExcelHelper类 添加Extensions类 添加实体类UserEntity,要跟Excel的列名一致 Excel模板 实现效果

    2024年02月12日
    浏览(44)
  • springboot项目利用easypoi导入导出(包括一对多导出的动态列选择,以及普通导入)

    因为项目只涉及到一对多的导出,以及普通的导入,所以,本文只会涉及这方面的使用 导入的时候,有校验,如果有错误数据,就会返回错误数据的所在行,以及错误信息(如果需要返回错误信息的所在的那几行数据以及错误信息的excel文件的话,可以看看第三个参考文章,

    2023年04月21日
    浏览(39)
  • 数据导入导出(POI以及easyExcel)

            将一些数据库信息导出为Excel表格         将Excel表格数据导入数据库         大量数据的导入导出操作 常⽤的解决⽅案为: Apache POI 与阿⾥巴巴 easyExcel Apache POI 是基于 Office Open XML 标准( OOXML )和 Microsoft 的 OLE 2 复合⽂档 格式( OLE2 )处理各种⽂件格式的

    2024年02月13日
    浏览(38)
  • easypoi模板导出excel以及遇到的合并问题

    背景是甲方要导出周报,但是导出的周报的样式比较复杂,只能选用模板导出,但是第一次使用模板导出遇到了一些问题的记录 下图是来自官方文档的指令图片,附带官网链接,可以直接去官网看 easypoi官网链接 下图就是我的模板,在测试的时候我感觉NULL和NULL没有太大的区

    2024年02月11日
    浏览(44)
  • 如何使用drawio画流程图以及导入导出

    你可以在线使用drawio, 或者drawon创建很多不同类型的图表。 如何使用编辑器,让我们以一个最基本的流程图开始。 流程图,就是让你可视化的描述一个过程或者系统。 图形和很少部分的文字表达就可以让读者很快的理解他们需要什么。 为了便于大家更直观的理解,我们在

    2024年02月07日
    浏览(47)
  • Android系统源码如何导入android studio中使用以及导入过程中遇到的问题

    一、在源码根目录中编译出android.ipr和android.iml android.ipr:整个系统源码的工程项目,android studio上直接打开即可查看源码 android.iml:工程中的具体配置信息 二、安装android studio,打开工程项目android.ipr 三、配置sdk 废话不多说,直接开始 进入源码根目录 之后选择要编译的项目

    2024年02月12日
    浏览(46)
  • JS实现Excel导入以及table导出为Excel

    在开发项目的过程中遇到了一个需求,将excel文件导入并且解析渲染到页面上。用户可以对表格内的部分内容做修改后再上传到服务端。 导入Excel 1.使用html支持上传标签从本地获取文件,例如type为file的input,el-upload等 2.实例化FileReader,并且通过readAsBinaryString将文件读取为二

    2024年02月09日
    浏览(44)
  • <VB.net>下CSV文件的导入(读取到DataGridView)和导出(DataGirdView保存到csv)

    VB.net项目主要使用微软旗下的Visual Studio 2022编辑器来进行,打开VS2022.新建一个VB.net窗体项目,保存。 然后在窗体上添加以下控件: DataGridView(数据表格控件)、Label(标签控件)、ContextMenuStrip(右键关联菜单控件)等 然后,设置DataGridView控件的contextmenustrip属性(关联到添

    2024年02月05日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包