使用C#的MPXJ库编辑MPP文件时写入空文件并触发空引用异常
问题分析与解决方案
核心问题1:使用了错误的文件写入器
你当前使用MPXWriter来写入MPP文件,但MPXWriter是用于处理MPX格式项目文件的,并非MPP格式。用它写入MPP文件会导致文件结构损坏,生成空文件或无效文件,后续读取自然会触发NullReferenceException。
核心问题2:变量作用域混淆(潜在风险)
在AddTask方法中,你声明了局部变量var project接收OpenReaderProject的返回值,但OpenWriterProject实际操作的是类成员变量project。虽然此时二者指向同一实例,但这种写法容易导致逻辑混淆,若后续修改代码可能引发不一致问题。
其他潜在问题
- 未对
OpenReaderProject返回的project实例做空值判断,若文件读取失败(如路径错误、文件损坏),后续调用project.addTask()会直接报错。 - 写入操作未处理文件占用情况,若原MPP文件被其他程序打开,写入会失败。
修正后的代码示例
1. 替换正确的文件写入器
将MPXWriter改为MPPWriter,匹配MPP文件格式:
ProjectReader reader = new MPPReader(); ProjectWriter writer = new MPPWriter(); // 替换为MPPWriter private ProjectFile project;
2. 优化读写方法与添加任务逻辑
public ProjectFile OpenReaderProject() { string filePath = "Files/Prova file1.mpp"; try { // 直接赋值给成员变量,避免局部变量混淆 project = reader.read(filePath); Console.WriteLine("文件读取成功"); } catch (MPXJException ex) { Console.WriteLine("Errore durante l'apertura del file .mpp: " + ex.Message); project = null; // 读取失败时置空 } return project; } public void OpenWriterProject() { if (project == null) { Console.WriteLine("项目实例为空,无法写入文件"); return; } string filePath = "Files/Prova file1.mpp"; try { writer.write(project, filePath); Console.WriteLine("文件写入成功"); } catch (MPXJException ex) { Console.WriteLine("Errore durante la scrittura del file .mpp: " + ex.Message); } } public void AddTask() { // 直接使用成员变量,无需局部变量 OpenReaderProject(); if (project == null) { Console.WriteLine("无法添加任务:项目文件未成功加载"); return; } var task = project.addTask(); task.setName(java.lang.String.valueOf("Attività di esempio")); var taskDto = _mapper.Map<TaskDto>(task); OpenWriterProject(); }
额外注意事项
- 确保程序运行时的工作目录下存在
Files文件夹,且Prova file1.mpp文件路径正确(可改为绝对路径避免路径问题)。 - 写入文件前,确保原MPP文件未被Microsoft Project或其他程序锁定。
- 建议使用最新版本的MPXJ库,避免旧版本的已知兼容性问题。
内容的提问来源于stack exchange,提问作者AleQuad
相关产品推荐
相关产品推荐

