一.背景介绍
最近公司一个老项目需要添加导出数据到光盘的功能.开始对这功能添加有点抵触的.光盘?都啥年代了.
光盘一种即将淘汰的存储媒介.就像当年的随身听,Mp3,Mp4一样,即将退出历史舞台.领导让加,发牢骚归发牢骚,活还是得干哈.
从网上找了一些资料,都是特别古老的文档了.很多方法用起来并不是特别的方便.
1.CodePlex Archive https://archive.codeplex.com/?p=csimapi2samples 其中的例子功能不全,参数都使用dynamic类型,刚开始不了解那些基础概念时,理解起来比较难.可以参考学习.
2.博客:https://blog.csdn.net/huanghunjiuba/article/details/12967463 中的例子BurnCdDemo.
里面的BurnCdDemo对ImApi2做了封装.其实例子里面的封装做的挺不错的.注释也特别全.
在做测试的时候发现刻录功能在本机运行的非常好.在公司的测试机上却获取不到光盘大小,取到的大小是负数.对着Demo的源代码检查了半天,没找到原因.╮( ̄▽ ̄")╭,脑袋好大的.后来找到原因了,在下面的过程中会描述下.
PS:个人不喜欢啥都做抽象.抽象,意味着要多写代码,查找问题也不方便.抽象,依赖注入,控制反转是个好东西,就是要多写许多代码.
个人觉得,很多技术还是要看实际项目情况而使用,没有必要去为了追求使用而滥用.看起来高大上,实际多写了代码维护也不方便.
So,自己搞个简单点的.因为就那么几个功能:获取光驱设备列表,获取光盘信息,添加媒体文件,刻录,进度通知.
二.工欲善其事必先利其器
因工作电脑没有光驱,测试非常不方便.那我们就安装一个虚拟光驱.
推荐一个比较好用的虚拟光驱软件PhantomBurner,带注册码.下载地址:https://download.csdn.net/download/zjhaag/10909339
安装过程就不说了.选下安装路径,一路Next.安装完成后提示重启.其实不重启也可以用.
安装完成后界面如下.在About中输入注册码激活.点击Create,选择Dvd+RW创建Virtual Disc Image.在资源管理器中就可以看到我们创建的虚拟光驱了.
三.开工
1.设备列表获取
(1)首先添加一个RecorderHelper.在RecorderHelper类中添加一个静态方法GetRecorderList用于获取光驱设备列表.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 /// <summary> 2 /// 获取光驱设备列表 3 /// </summary> 4 /// <returns></returns> 5 public static List<Recorder> GetRecorderList() 6 { 7 List<Recorder> recordList = new List<Recorder>(); 8 9 // Create a DiscMaster2 object to connect to optical drives. 10 MsftDiscMaster2 discMaster = new MsftDiscMaster2(); 11 for (int i = 0; i < discMaster.Count; i++) 12 { 13 if (discMaster[i] != null) 14 { 15 Recorder recorder = new Recorder(discMaster[i]); 16 recordList.Add(recorder); 17 } 18 } 19 return recordList; 20 }
此时,需要Recorder光驱对象主要属性如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 MsftDiscRecorder2 msRecorder = null; //Recorder 2 3 /// <summary> 4 /// 当前磁盘标签 5 /// </summary> 6 public string RecorderName { get; private set; } 7 8 /// <summary> 9 /// 是否支持当前刻录机 10 /// </summary> 11 public bool IsRecorderSupported { get; private set; } 12 13 /// <summary> 14 /// 是否支持当前磁盘媒体 15 /// </summary> 16 public bool IsCurrentMediaSupported { get; private set; } 17 18 /// <summary> 19 /// 当前磁盘可用大小 20 /// </summary> 21 public long FreeDiskSize { get; private set; } 22 23 /// <summary> 24 /// 当前磁盘总大小 25 /// </summary> 26 public long TotalDiskSize { get; private set; } 27 28 /// <summary> 29 /// 当前媒体状态 30 /// </summary> 31 public IMAPI_FORMAT2_DATA_MEDIA_STATE CurMediaState { get; private set; } 32 33 /// <summary> 34 /// 当前媒体状态 35 /// </summary> 36 public string CurMediaStateName { get; private set; } 37 38 /// <summary> 39 /// 当前媒体类型 40 /// </summary> 41 public IMAPI_MEDIA_PHYSICAL_TYPE CurMediaType { get; private set; } 42 43 /// <summary> 44 /// 当前媒体类型 45 /// </summary> 46 public string CurMediaTypeName { get; private set; } 47 48 /// <summary> 49 /// 是否可以刻录 50 /// </summary> 51 public bool CanBurn { get;private set;}
(2)对Recorder各属性进行初始化,赋值.主要方法如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 /// <summary> 2 /// Recorder Ctor 3 /// </summary> 4 /// <param name="uniqueId">标识Id</param> 5 public Recorder(string uniqueId) 6 { 7 this.uniqueId = uniqueId; 8 msRecorder = new MsftDiscRecorder2(); 9 msRecorder.InitializeDiscRecorder(uniqueId); 10 InitRecorder(); 11 12 this.BurnMediaList = new List<BurnMedia>(); 13 this.BurnMediaFileSize = 0; 14 } 15 16 /// <summary> 17 /// 初始化Recorder 18 /// 更新Recorder信息,更新光盘后可重试. 19 /// </summary> 20 public void InitRecorder() 21 { 22 try 23 { 24 if (msRecorder.VolumePathNames != null && msRecorder.VolumePathNames.Length > 0) 25 { 26 foreach (object mountPoint in msRecorder.VolumePathNames) 27 { //挂载点 取其中一个 28 RecorderName = mountPoint.ToString(); 29 break; 30 } 31 } 32 // Define the new disc format and set the recorder 33 MsftDiscFormat2Data dataWriter = new MsftDiscFormat2Data(); 34 dataWriter.Recorder = msRecorder; 35 36 if (!dataWriter.IsRecorderSupported(msRecorder)) 37 { 38 return; 39 } 40 if (!dataWriter.IsCurrentMediaSupported(msRecorder)) 41 { 42 return; 43 } 44 if (dataWriter.FreeSectorsOnMedia >=