C# 实现刻录光盘功能
最近公司提出一个需求,要把公司系统的图像刻录成光盘(公司系统是医院放射科系统,很多放射科的图像)
查看了很多资料发现有两个比较可靠
1:使用IMAPI2,进行文件的光盘刻录,具体实例可以参照以下链接:
C#实现方式:
Burning and Erasing CD/DVD Media with C# and IMAPI2
地址:http://www.codeproject.com/Articles/24544/Burning-and-Erasing-CD-DVD-Blu-ray-Media-with-C-an
C++实现方式:
Burning CD/DVD Media with the Image Mastering API Version 2.0 (IMAPI2)
地址:http://www.codeproject.com/Articles/22538/Burning-CD-DVD-Media-with-the-Image-Mastering-API
我用的C#的版本,经过测试 在WIN7下好用,xp 下不好用, 虽然很多人说xp sp3补丁可以,但是我还是失败了,公司的系统要求Xp可以使用
而且有个奇怪的问题,我自定义的项目就没有进度条的事件,下载老外的源码就有,好奇怪
郁闷呀..
2:C#调用Nero SDK进行
参考资料:1.http://blog.sina.com.cn/s/blog_962aaf5d01012vow.html
2.http://blog.csdn.net/laibeikele/article/details/2500185
这两位写的都很完全,我只是把它收集补充了一下
首先是
SDK的版本: 采用NeroSDK-1.08版本,
Nero版本: 你的电脑需要安装Nero, 应该是必须要Nero7, 我安装了8不好用,只有安装7才好用
开发注意:.net版本应该是1.0到3.5之间.4.0,4.5编译不了,而且项目的目标平台必须是x86 其他的会报错
基于Nero SDK有我自己的一个简单的封装,帖出来给大家分享一下
项目结构
系统定义部分委托:
/// <summary> /// 显示时间进度 /// </summary> /// <param name="time"></param> public delegate void ShowTimeProcessDelegate(string time); /// <summary> /// 显示进度 /// </summary> /// <param name="percentProgress"></param> public delegate void ShowBrushLogLineDelegate(string value); /// <summary> /// 显示进度 /// </summary> /// <param name="percentProgress"></param> public delegate void ShowBrushProcessDelegate(ProcessEntity percentEvent); /// <summary> /// 刻录错误 /// </summary> /// <param name="error"></param> public delegate void BurshErrorDelegate(Exception ex); /// <summary> /// 刻录成功 /// </summary> /// <param name="value"></param> public delegate void BrushSuccessDelegate(string value); /// <summary> /// 显示光盘信息 /// </summary> /// <returns></returns> public delegate void ShowDiscInfoDelegate(DiscInfoEntity disc); /// <summary> /// 获取所以刻录信息 /// </summary> /// <param name="collection"></param> public delegate void GetSpeedEntityCollectionDelegate(SpeedEntityCollection collection);
获取光盘信息方法
/// <summary> /// 光盘信息帮助类 /// </summary> class DiscHelper { private Nero m_nero; private NeroDrive m_drive; internal event ShowDiscInfoDelegate ShowDisc; public DiscHelper(Nero nero, NeroDrive drive) { this.m_nero = nero; this.m_drive = drive; } /// <summary> /// 获取光盘容量 /// </summary> /// <param name="driveInfo">驱动器信息</param> /// <returns></returns> public void GetDriveInfoSize() { if (m_drive != null) { m_drive.OnDoneCDInfo += drive_OnDoneCDInfo; } RefreshDiscInfo(); } private void RefreshDiscInfo() { if (m_drive != null) { m_drive.CDInfo(NERO_CDINFO_FLAGS.NERO_READ_CD_TEXT); } } /// <summary> /// 异步触发信息类 /// </summary> /// <param name="pCDInfo"></param> private void drive_OnDoneCDInfo(INeroCDInfo pCDInfo) { m_drive.OnDoneCDInfo -= drive_OnDoneCDInfo; DisplayDiscInfo((NeroCDInfo)pCDInfo); } /// <summary> /// 格式化光盘信息实体类 /// </summary> /// <param name="cdinfo"></param> private void DisplayDiscInfo(NeroCDInfo cdinfo) { DiscInfoEntity info = null; if (cdinfo != null) { info = new DiscInfoEntity(); long l2048 = 2048;//2048转换成long类型 info.MediaType = m_nero.get_TypeNameOfMedia(cdinfo.MediaType); info.StrFreeCapacity = BlockToByte(cdinfo.FreeCapacityInBlocks); info.StrUnused = BlockToByte((uint)cdinfo.UnusedBlocks); info.StrTotalCapacity = BlockToByte(cdinfo.TotalCapacity); info.TotalCapacity = cdinfo.FreeCapacityInBlocks * l2048; info.Unused = ((uint)cdinfo.UnusedBlocks) * l2048; info.TotalCapacity = cdinfo.TotalCapacity * l2048; info.Cdinfo = cdinfo; } //委托返回信息 if (ShowDisc != null) { ShowDisc(info); } } #region 格式化函数 private string BlockToByte(int block) { string Value = string.Empty; int temp = FromByteM(block); if (temp < 1024) { Value = string.Format("{0}MB", temp); } else { Value = string.Format("{0:N}GB", FromByteG(block)); } return Value; } private string BlockToByte(uint block) { string Value = string.Empty; int temp = FromByteM(block); if (temp < 1024) { Value = string.Format("{0}MB", temp); } else { Value = string.Format("{0:N}GB", FromByteG(block)); } return Value; } /// <summary> /// Block转换MB /// </summary> /// <param name="block"></param> /// <returns></returns> private int FromByteM(int block) { int temp = block * 2 / 1024; return temp; } /// <summary> /// Block转换MB /// </summary> /// <param name="block"></param> /// <returns></returns> private int FromByteM(uint block) { uint ut1 = 2; uint ut2 = 1024; int temp = (int)(block * ut1 / ut2); return temp; } /// <summary> /// Block转换GB /// </summary> /// <param name="block"></param> /// <returns></returns> private double FromByteG(int block) { double d1 = (double)block; double temp = d1 * 2 / 1024 / 1024; return temp; } /// <summary> /// Block转换GB /// </summary> /// <param name="block"></param> /// <returns></returns> private double FromByteG(uint block) { uint ut1 = 2; uint ut2 = 1024; double d1 = (double)block; double temp = (double)(d1 * ut1 / ut2 / ut2); return temp; } #endregion }
有一部分是block转换使用的.SDK获取到的并不在我们常用的单位
光盘信息定义的实体类
/// <summary> /// 光盘信息实体类 /// </summary> public class DiscInfoEntity { /// <summary> /// 剩余容量(带单位) /// </summary> public string StrFreeCapacity { get; set; } /// <summary> /// 不可用容量(带单位) /// </summary> public string StrUnused { get; set; } /// <summary> /// 全部容量(带单位) /// </summary> public string StrTotalCapacity { get; set; } /// <summary> /// 剩余容量Byte /// </summary> public long FreeCapacity { get; set; } /// <summary> /// 已用容量Byte /// </summary> public long Unused { get; set; } /// <summary> /// 全部容量 /// </summary> public long TotalCapacity { get; set; } /// <summary> /// 光盘类型 /// </summary> public string MediaType { get; set; } /// <summary> /// /// </summary> public NeroCDInfo Cdinfo { get; set; } }
2:获取刻录机的读写速度
/// <summary> /// 刻录速度帮助类 /// </summary> class SpeedHelper { public NeroDrive m_drive; private bool m_bWriteSpeeds; private _INeroDriveEvents_OnDoneCDInfoEventHandler m_evOnDoneCDInfo; internal event GetSpeedEntityCollectionDelegate GetSpeedCollect; public SpeedHelper(NeroDrive drive, bool writeSpeed) { m_drive = drive; m_bWriteSpeeds = writeSpeed; m_evOnDoneCDInfo = new _INeroDriveEvents_OnDoneCDInfoEventHandler(m_drive_OnDoneCDInfo); m_drive.OnDoneCDInfo += m_evOnDoneCDInfo; } /// <summary> ///异步获取速度 /// </summary> public void GetSpeed() { m_drive.CDInfo(0); } /// <summary> /// 触发异步事件 /// </summary> /// <param name="pCDInfo"></param> private void m_drive_OnDoneCDInfo(INeroCDInfo pCDInfo) { // Unsubscribe from event, get the speeds and populate the // speeds combobox with it m_drive.OnDoneCDInfo -= m_evOnDoneCDInfo; SpeedEntityCollection collection = GetSpeedCollection(pCDInfo, m_bWriteSpeeds); if (GetSpeedCollect != null) { GetSpeedCollect(collection); } } /// <summary> /// 获取读取速度 /// </summary> /// <param name="pCDInfo">光盘信息</param> /// <returns></returns> public SpeedEntityCollection GetReadSpeedCollection(INeroCDInfo pCDInfo) { SpeedEntityCollection collection = GetSpeedCollection(pCDInfo, false); return collection; } /// <summary> /// 获取写入速度 /// </summary> /// <param name="pCDInfo">光盘信息</param> /// <returns></returns> public SpeedEntityCollection GetWriteSpeedCollection(INeroCDInfo pCDInfo) { SpeedEntityCollection collection = GetSpeedCollection(pCDInfo, true); return collection; } /// <summary> /// 获取读写速度 /// </summary> /// <param name="pCDInfo">光盘信息</param> /// <param name="WriteSpeeds">是否读写</param> /// <returns></returns> private SpeedEntityCollection GetSpeedCollection(INeroCDInfo pCDInfo, bool WriteSpeeds) { NERO_MEDIA_TYPE nmt = (pCDInfo != null ? pCDInfo.MediaType : NERO_MEDIA_TYPE.NERO_MEDIA_NONE); NeroSpeeds speeds = m_drive.get_AvailableSpeeds(WriteSpeeds ? NERO_ACCESSTYPE.NERO_ACCESSTYPE_WRITE : NERO_ACCESSTYPE.NERO_ACCESSTYPE_READ, nmt); SpeedEntityCollection collection = GetSpeedEntityCollection(speeds, WriteSpeeds); return collection; } /// <summary> /// 生成速度集合 /// </summary> /// <param name="speeds"></param> /// <param name="WriteSpeeds"></param> /// <returns></returns> private SpeedEntityCollection GetSpeedEntityCollection(NeroSpeeds speeds, bool WriteSpeeds) { SpeedEntityCollection collection = new SpeedEntityCollection(); // If we should add "Maximum", do it here and now. // if (WriteSpeeds) { collection.SpeedEntity.Add(new SpeedEntity("Maximum", 0)); } else { // If we should not add "Maximum", see if there is at // least one speed. If not, add "<none>". // if (speeds.Count == 0) { collection.SpeedEntity.Add(new SpeedEntity("<none>", 0)); } } // Now, add each speed from the NeroSpeeds collection. // foreach (int iSpeed in speeds) { float fSpeed = iSpeed / (float)speeds.BaseSpeedKBs; collection.SpeedEntity.Add(new SpeedEntity(fSpeed.ToString() + "x (" + iSpeed.ToString() + " kb/s)", iSpeed)); } return collection; }
读写速度的实体类
/// <summary> /// 速度集合类 /// </summary> public class SpeedEntityCollection { public IList<SpeedEntity> SpeedEntity { get; set; } public SpeedEntityCollection() { this.SpeedEntity = new List<SpeedEntity>(); } } /// <summary> /// 速度实体类 /// </summary> public class SpeedEntity { public string m_sItem; public int m_iSpeed; public SpeedEntity(string sItem, int iSpeed) { m_sItem = sItem; m_iSpeed = iSpeed; } public override string ToString() { return m_sItem; } }
刻录类
class BrushHelper { private NeroDrive m_drive; private Nero m_nero; private _INeroDriveEvents_OnDoneBurnEventHandler m_evOnDoneBurn; private _INeroDriveEvents_OnProgressEventHandler m_evOnProgress; private _INeroDriveEvents_OnSubTaskProgressEventHandler m_evOnSubTaskProgress; private _INeroDriveEvents_OnAbortedEventHandler m_evOnAborted; private _INeroDriveEvents_OnAddLogLineEventHandler m_evOnAddLogLine; private _INeroDriveEvents_OnSetPhaseEventHandler m_evOnSetPhase; private _INeroDriveEvents_OnDisableAbortEventHandler m_evOnDisableAbort; private _INeroEvents_OnFileSelImageEventHandler m_evOnFileSelImage; private _INeroEvents_OnWaitCDEventHandler m_evOnWaitCD; private _INeroEvents_OnWaitCDDoneEventHandler m_evOnWaitCDDone; private _INeroEvents_OnWaitCDMediaInfoEventHandler m_evOnWaitCDMediaInfo; private _INeroEvents_OnNonEmptyCDRWEventHandler m_evOnNonEmptyCDRW; private bool m_bAborted; private DateTime m_timeStart; private System.Timers.Timer m_timer; private WaitCD m_frmWaitCD = null; public bool IsCancle { get; set; } /// <summary> /// 使用时间 /// </summary> internal event ShowTimeProcessDelegate ShowTimeProcess; /// <summary> /// 显示进度 /// </summary> internal event ShowBrushProcessDelegate ShowBurshProcess; /// <summary> /// 显示子进度 /// </summary> internal event ShowBrushProcessDelegate SubShowBurshProcess; /// <summary> /// 显示进度 /// </summary> internal event ShowBrushLogLineDelegate ShowLogLine; /// <summary> /// 刻录成功委托 /// </summary> internal event BrushSuccessDelegate BrushSuccess; /// <summary> /// 刻录失败委托 /// </summary> internal event BurshErrorDelegate BrushError; public BrushHelper(Nero nero, NeroDrive drive) { IsCancle = true; this.m_nero = nero; this.m_drive = drive; this.m_frmWaitCD = new WaitCD(); this.m_frmWaitCD.OnCancel += m_frmWaitCD_OnCancel; } void m_frmWaitCD_OnCancel(object sender, EventArgs e) { this.Cancle(); } /// <summary> /// 刻录光盘 /// </summary> /// <param name="isoTrack"></param> /// <param name="audioTracks"></param> /// <param name="cdStamp"></param> /// <param name="BurnFlags"></param> /// <param name="m_iSpeed"></param> /// <param name="MediaType"></param> public void Brush(NeroISOTrack isoTrack, NeroAudioTracks audioTracks, NeroCDStamp cdStamp, NERO_BURN_FLAGS BurnFlags, int m_iSpeed, NERO_MEDIA_TYPE MediaType ) { BurnIsoAudio(string.Empty, string.Empty, isoTrack, audioTracks, cdStamp, BurnFlags, m_iSpeed, MediaType); } /// <summary> /// 刻录光盘 /// </summary> /// <param name="sArtist"></param> /// <param name="sTitle"></param> /// <param name="isoTrack">光盘类</param> /// <param name="audioTracks">音频类</param> /// <param name="cdStamp"></param> /// <param name="BurnFlags">刻录标记</param> /// <param name="m_iSpeed">速度</param> /// <param name="MediaType">光盘类型</param> public void Brush(string sArtist, string sTitle, NeroISOTrack isoTrack, NeroAudioTracks audioTracks, NeroCDStamp cdStamp, NERO_BURN_FLAGS BurnFlags, int m_iSpeed, NERO_MEDIA_TYPE MediaType ) { BurnIsoAudio(sArtist, sTitle, isoTrack, audioTracks, cdStamp, BurnFlags, m_iSpeed, MediaType); } /// <summary> /// 停止刻录 /// </summary> public void Cancle() { if (!IsCancle) { return; } m_bAborted = true; m_nero.Abort(); } private void BurnIsoAudio(string sArtist, string sTitle, NeroISOTrack isoTrack, NeroAudioTracks audioTracks, NeroCDStamp cdStamp, NERO_BURN_FLAGS nbf, int iSpeedInKBS, NERO_MEDIA_TYPE mediaType) { try { // First subscribe to all events of interest. // SubscribeToEvents(true); // If the iso track passed in has neither files nor folders, // don't use it. // if (isoTrack.RootFolder.Files.Count == 0 && isoTrack.RootFolder.Folders.Count == 0) { isoTrack = null; } // Just pass on all the gathered parameters. // m_drive.BurnIsoAudioCD(sArtist, sTitle, false, isoTrack, audioTracks, cdStamp, (NERO_BURN_FLAGS)((uint)nbf | (uint)NERO_BURN_FLAGS.NERO_BURN_FLAG_SPEED_IN_KBS), iSpeedInKBS, mediaType); } catch (COMException ex) { SubscribeToEvents(false); XLogManager.LogError(ex); //MessageBox.Show(this, ex.Message); } catch (Exception exx) { XLogManager.LogError(exx); // MessageBox.Show(this, exx.Message); } } private void SubscribeToEvents(bool bSubscribe) { if (bSubscribe) { // Subscribe to NeroDrive events. // m_evOnDoneBurn = new _INeroDriveEvents_OnDoneBurnEventHandler(m_drive_OnDoneBurn); m_drive.OnDoneBurn += m_evOnDoneBurn; m_evOnProgress = new _INeroDriveEvents_OnProgressEventHandler(m_drive_OnProgress); m_drive.OnProgress += m_evOnProgress; m_evOnSubTaskProgress = new _INeroDriveEvents_OnSubTaskProgressEventHandler(m_drive_OnSubTaskProgress); m_drive.OnSubTaskProgress += m_evOnSubTaskProgress; m_evOnAborted = new _INeroDriveEvents_OnAbortedEventHandler(m_drive_OnAborted); m_drive.OnAborted += m_evOnAborted; m_evOnAddLogLine = new _INeroDriveEvents_OnAddLogLineEventHandler(m_drive_OnAddLogLine); m_drive.OnAddLogLine += m_evOnAddLogLine; m_evOnSetPhase = new _INeroDriveEvents_OnSetPhaseEventHandler(m_drive_OnSetPhase); m_drive.OnSetPhase += m_evOnSetPhase; m_evOnDisableAbort = new _INeroDriveEvents_OnDisableAbortEventHandler(m_drive_OnDisableAbort); m_drive.OnDisableAbort += m_evOnDisableAbort; // Subscribe to Nero events. // m_evOnFileSelImage = new _INeroEvents_OnFileSelImageEventHandler(m_nero_OnFileSelImage); m_nero.OnFileSelImage += m_evOnFileSelImage; m_evOnWaitCD = new _INeroEvents_OnWaitCDEventHandler(m_nero_OnWaitCD); m_nero.OnWaitCD += m_evOnWaitCD; m_evOnWaitCDDone = new _INeroEvents_OnWaitCDDoneEventHandler(m_nero_OnWaitCDDone); m_nero.OnWaitCDDone += m_evOnWaitCDDone; m_evOnWaitCDMediaInfo = new _INeroEvents_OnWaitCDMediaInfoEventHandler(m_nero_OnWaitCDMediaInfo); m_nero.OnWaitCDMediaInfo += m_evOnWaitCDMediaInfo; m_evOnNonEmptyCDRW = new _INeroEvents_OnNonEmptyCDRWEventHandler(m_nero_OnNonEmptyCDRW); m_nero.OnNonEmptyCDRW += m_evOnNonEmptyCDRW; //// Start the timer that is responsible for displaying //// the elapsed time during burning. //// m_timeStart = DateTime.Now; m_timer = new System.Timers.Timer(500); m_timer.Elapsed += new System.Timers.ElapsedEventHandler(m_timer_Elapsed); m_timer.Start(); } else { //// Stop the elapsed time timer. //// m_timer.Stop(); // Unsubscribe from NeroDrive events. // m_drive.OnDoneBurn -= m_evOnDoneBurn; m_drive.OnProgress -= m_evOnProgress; m_drive.OnSubTaskProgress -= m_evOnSubTaskProgress; m_drive.OnAborted -= m_evOnAborted; m_drive.OnAddLogLine -= m_evOnAddLogLine; m_drive.OnSetPhase -= m_evOnSetPhase; m_drive.OnDisableAbort -= m_evOnDisableAbort; // Unsubscribe from Nero events. // m_nero.OnFileSelImage -= m_evOnFileSelImage; m_nero.OnWaitCD -= m_evOnWaitCD; m_nero.OnWaitCDDone -= m_evOnWaitCDDone; m_nero.OnWaitCDMediaInfo -= m_evOnWaitCDMediaInfo; m_nero.OnNonEmptyCDRW -= m_evOnNonEmptyCDRW; } } /// <summary> /// 光盘信息 /// </summary> /// <param name="LastDetectedMedia"></param> /// <param name="LastDetectedMediaName"></param> /// <param name="RequestedMedia"></param> /// <param name="RequestedMediaName"></param> private void m_nero_OnWaitCDMediaInfo(ref NERO_MEDIA_TYPE LastDetectedMedia, ref string LastDetectedMediaName, ref NERO_MEDIA_TYPE RequestedMedia, ref string RequestedMediaName) { // When this event is fired, we need to update the // information on the WaitCD form. Also, sometimes // this event can come before the actual OnWaitCD so // make sure that either of them is prepared to // show the WaitCD form. // m_frmWaitCD.c_LastDetectedMedia.Text = LastDetectedMediaName; m_frmWaitCD.c_RequestedMedia.Text = RequestedMediaName; m_frmWaitCD.Show(); } /// <summary> /// 光盘不为空时,是否格式化 /// </summary> /// <param name="Response"></param> private void m_nero_OnNonEmptyCDRW(ref NERO_RESPONSE Response) { //// This event will be fired only if the proper conditions //// are met AND if NERO_BURN_FLAGS.NERO_BURN_FLAG_DETECT_NON_EMPTY_CDRW //// was specified to the burn fucntion. Ask if we should erase //// the rewritable. //// if (DialogResult.Yes != MessageBox.Show("当前光盘不是空的.需要被删除才能继续,你想删除光盘吗?", "擦除?", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { // If the answer was NO, ask for a new disc. // Response = NERO_RESPONSE.NERO_RETURN_RESTART; } else { // If YES, then do erase the disc and continue burning // afterwards. // EraseProgressForm frm = new EraseProgressForm(m_drive, true, false); frm.ShowDialog(); Response = NERO_RESPONSE.NERO_RETURN_CONTINUE; } } /// <summary> /// 光盘完成 /// </summary> private void m_nero_OnWaitCDDone() { // When waiting on a disc is done, make sure to // enable us and hide the WaitCD form. // m_frmWaitCD.Hide(); } /// <summary> /// 等待光盘 /// </summary> /// <param name="WaitCD"></param> /// <param name="WaitCDLocalizedText"></param> private void m_nero_OnWaitCD(ref NERO_WAITCD_TYPE WaitCD, ref string WaitCDLocalizedText) { // Ok, so now we need to wait on a disc. Let's pass // the WaitCD form the text and show it (if not already // shown). Make sure to disable the parent (this window) // so that a modal behavior is simulated. // string value = WaitCDLocalizedText; if (WaitCDLocalizedText.Contains("Please insert the disc to write to...")) { value = "请插入可写光盘..."; } m_frmWaitCD.c_WaitCDText.Text = value; m_frmWaitCD.Show(); } /// <summary> /// 设置文件信息时 /// </summary> /// <param name="Filename"></param> private void m_nero_OnFileSelImage(ref string Filename) { //// This events asks us to supply the image filename to //// save to if the chose recorder is "Image Recorder". //// //SaveFileDialog dlg = new SaveFileDialog(); //dlg.DefaultExt = ".nrg"; //dlg.Filter = "NRG files (*.nrg)|*.nrg|All files (*.*)|*.*"; //// To cancel, assign empty string. //// //if (DialogResult.OK == dlg.ShowDialog(this)) //{ // Filename = dlg.FileName; //} //else //{ // Filename = ""; //} } /// <summary> /// 禁用中止 /// </summary> /// <param name="EnableAbort"></param> private void m_drive_OnDisableAbort(ref bool EnableAbort) { // This event will be fired at appropriate moments // only if NERO_BURN_FLAGS.NERO_BURN_FLAG_DISABLE_ABORT // was specified to the burning function. Make sure to // update the state of the Cancel button accordingly. // //c_Cancel.Enabled = EnableAbort; IsCancle = EnableAbort; } /// <summary> /// 添加进度说明 /// </summary> /// <param name="TextType"></param> /// <param name="Text"></param> private void m_drive_OnAddLogLine(ref NERO_TEXT_TYPE TextType, ref string Text) { // This one informs us of the important events during // the burn process. We simply add a line to the list // view with the current time beside it. // DateTime time = DateTime.Now; //ListViewItem lvi = c_Events.Items.Add(time.ToLongTimeString()); //lvi.SubItems.Add(Text); if (ShowLogLine != null) { ShowLogLine(Text); } } private void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // When the timer ticks, we should update the elapsed // time. // try { TimeSpan ts = System.DateTime.Now - m_timeStart; if (ShowTimeProcess != null) { this.ShowTimeProcess(ts.Hours.ToString("00") + ":" + ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00")); } } catch (Exception ex) { XLogManager.LogError(ex); Console.WriteLine(ex.Message); } } /// <summary> /// 设置阶段 /// </summary> /// <param name="Text"></param> private void m_drive_OnSetPhase(ref string Text) { // When a new phase comes in, display it. // //c_Phase.Text = Text; if (this.ShowBurshProcess != null) { ShowLogLine(Text); } } /// <summary> /// 终止刻录 /// </summary> /// <param name="Abort"></param> private void m_drive_OnAborted(ref bool Abort) { // This is a general aborted event that is called // more frequently than other events that might // also give us a chance to abort. // Abort = m_bAborted; } /// <summary> /// 刻录结束 /// </summary> /// <param name="StatusCode"></param> private void m_drive_OnDoneBurn(ref NERO_BURN_ERROR StatusCode) { // When burning is over, make sure to unsubscribe from all // events. // SubscribeToEvents(false); // Show the appropriate message for success and failure. // if (StatusCode == NERO_BURN_ERROR.NERO_BURN_OK) { //MessageBox.Show(this, "Burn process completed successfully!"); BrushSuccess("刻录完成"); } else { //MessageBox.Show(this, "Burn process failed!\n" + StatusCode.ToString()); XLogManager.LogError(StatusCode.ToString()); BrushError(new Exception("刻录失败!\n" + StatusCode.ToString())); } this.IsCancle = false; } /// <summary> /// 任务进度 /// </summary> /// <param name="ProgressInPercent"></param> /// <param name="Abort"></param> private void m_drive_OnProgress(ref int ProgressInPercent, ref bool Abort) { // This events gives us an opportunity to show progress // as well as abort if needed. // Abort = m_bAborted; if (ProgressInPercent <= 0) return; if (this.ShowBurshProcess != null) { ShowBurshProcess(new ProcessEntity(ProgressInPercent, string.Empty)); } //c_Task.Value = ProgressInPercent; //c_TaskPercent.Text = ProgressInPercent.ToString() + "%"; } /// <summary> /// 子任务进度 /// </summary> /// <param name="ProgressInPercent"></param> /// <param name="Abort"></param> private void m_drive_OnSubTaskProgress(ref int ProgressInPercent, ref bool Abort) { // This event gives us the other task's progress. // Abort = m_bAborted; if (this.SubShowBurshProcess != null) { SubShowBurshProcess(new ProcessEntity(ProgressInPercent, string.Empty)); } //c_SubTask.Value = ProgressInPercent; //c_SubTaskPercent.Text = ProgressInPercent.ToString() + "%"; } }
刻录管理类
/// <summary> /// 刻录管理类 /// </summary> public class BrushManagerHelper { private Nero m_nero; private NeroDrives m_devices; /// <summary> /// 刻录进程 /// </summary> private Thread BrushThread; /// <summary> /// 调用窗口 /// </summary> private Form ParentFrm; /// <summary> /// 文件列表 /// </summary> private IList<FileFolers> fileFolersList = null; /// <summary> /// 文件大小 /// </summary> private long FileSize = 0; /// <summary> /// 刻录成功委托 /// </summary> public event BrushSuccessDelegate BrushSuccess; /// <summary> /// 刻录失败委托 /// </summary> public event BurshErrorDelegate BrushError; /// <summary> /// 显示进度委托 /// </summary> public event ShowBrushProcessDelegate ShowBurshProcess; /// <summary> /// 委托返回光盘信息 /// </summary> public event ShowDiscInfoDelegate ShowDisc; /// <summary> /// 显示进度 /// </summary> public event ShowBrushLogLineDelegate ShowLogLine; /// <summary> /// 显示子进度 /// </summary> public event ShowBrushProcessDelegate SubShowBurshProcess; /// <summary> /// 使用时间 /// </summary> public event ShowTimeProcessDelegate ShowTimeProcess; /// <summary> /// 获取刻录速度 /// </summary> public event GetSpeedEntityCollectionDelegate ShowSpeedCollect; public BrushManagerHelper(Form frm) { m_nero = new NeroClass(); ParentFrm = frm; fileFolersList = new List<FileFolers>(); } /// <summary> /// 获取所有刻录机信息
/// </summary> /// <returns></returns> public IList<CDDriveInfo> GetAllDriveInfo() { m_devices = m_nero.GetDrives(NERO_MEDIA_TYPE.NERO_MEDIA_CD); IList<CDDriveInfo> list = new List<CDDriveInfo>(); for (int i = 0; i < m_devices.Count; i++) { NeroDrive drive = (NeroDrive)m_devices.Item(i); string sDriveLetter = (drive.DriveLetter == "") ? "?" : drive.DriveLetter.ToUpper(); list.Add(new CDDriveInfo() { VolumeName = sDriveLetter + ": " + drive.DeviceName, NeroDrive = drive }); } return list; } /// <summary> /// 获取光盘信息 /// </summary> /// <param name="driverInfo"></param> public void GetDriveInfoSize(CDDriveInfo driverInfo) { if (driverInfo == null) { return; } DiscHelper disHelper = new DiscHelper(this.m_nero, driverInfo.NeroDrive); disHelper.ShowDisc += disHelper_ShowDisc; disHelper.GetDriveInfoSize(); } #region 读写速度 /// <summary> /// 获取光盘信息 /// </summary> /// <param name="driverInfo"></param> /// <param name="writed"></param> public void GetSpeedCollect(CDDriveInfo driverInfo, bool writed) { if (driverInfo == null) return; SpeedHelper speedHelper = new SpeedHelper(driverInfo.NeroDrive, writed); speedHelper.GetSpeedCollect += speedHelper_GetSpeedCollect; speedHelper.GetSpeed(); } /// <summary> /// 获取读取速度 /// </summary> /// <param name="driverInfo"></param> /// <param name="pCDInfo"></param> /// <returns></returns> public SpeedEntityCollection GetReadSpeedCollection(CDDriveInfo driverInfo, INeroCDInfo pCDInfo) { if (driverInfo == null) return null; SpeedHelper speedHelper = new SpeedHelper(driverInfo.NeroDrive, true); return speedHelper.GetReadSpeedCollection(pCDInfo); } /// <summary> /// 获取写入速度 /// </summary> /// <returns></returns> public SpeedEntityCollection GetWriteSpeedCollection(CDDriveInfo driverInfo, INeroCDInfo pCDInfo) { if (driverInfo == null) return null; SpeedHelper speedHelper = new SpeedHelper(driverInfo.NeroDrive, true); return speedHelper.GetWriteSpeedCollection(pCDInfo); } #endregion /// <summary> /// 刻录 /// </summary> public void Brush(CDDriveInfo driverInfo, DiscInfoEntity DiscInfo) { StopThread(); BrushThread = new Thread(new ParameterizedThreadStart(BurshStart)); BrushThread.Start(new object[] { driverInfo, DiscInfo }); } /// <summary> /// 获取文件夹大小 /// </summary> /// <param name="folderPath"></param> /// <param name="size"></param> private void GetFiloderSize(string folderPath, ref long size) { if (Directory.Exists(folderPath)) { DirectoryInfo info = new DirectoryInfo(folderPath); DirectoryInfo[] direArray = info.GetDirectories(); if (direArray != null) { foreach (DirectoryInfo item in direArray) { GetFiloderSize(item.FullName, ref size); } } FileInfo[] fileArray = info.GetFiles(); if (fileArray != null) { foreach (FileInfo item in fileArray) { size += item.Length; } } } } /// <summary> /// 多线程刻录 /// </summary> /// <param name="Array"></param> private void BurshStart(object Array) { try { if (Array.GetType().Name == "Object[]") { object[] obj = Array as object[]; CDDriveInfo CDDriveInfo = obj[0] as CDDriveInfo; DiscInfoEntity DiscInfo = obj[1] as DiscInfoEntity; if (CDDriveInfo == null) { throw new Exception("请选择刻录机"); } if (DiscInfo == null) { throw new Exception("没有找到光盘信息"); } NeroISOTrack isoTrack = CreateISOTrack(); isoTrack.BurnOptions = GetNeroBurnOptions(); AddFileFolerToISO(ref isoTrack); if (isoTrack.RootFolder.Files.Count == 0 && isoTrack.RootFolder.Folders.Count == 0) { isoTrack = null; return; } BrushHelper helper = new BrushHelper(this.m_nero, CDDriveInfo.NeroDrive); helper.ShowTimeProcess += helper_ShowTimeProcess; helper.ShowBurshProcess += helper_ShowBurshProcess; helper.ShowLogLine += helper_ShowLogLine; helper.SubShowBurshProcess += helper_SubShowBurshProcess; helper.BrushSuccess += helper_BrushSuccess; helper.BrushError += helper_BrushError; helper.Brush(isoTrack, null, null , GetNeroFlages() , GetWriteSpeedCollection(CDDriveInfo, DiscInfo.Cdinfo).SpeedEntity[0].m_iSpeed , DiscInfo.Cdinfo.MediaType); } } catch (Exception ex) { XInvoke(BrushError, ex); StopThread(); } } /// <summary> /// 停止线程 /// </summary> private void StopThread() { if (BrushThread != null && (BrushThread.ThreadState == ThreadState.Running || BrushThread.ThreadState == ThreadState.WaitSleepJoin)) { try { BrushThread.Abort(); } catch (Exception ex) { XLogManager.LogError(ex); } } } /// <summary> /// 获取文件大小 /// </summary> /// <returns></returns> public long GetFileSize() { FileSize = 0; if (this.fileFolersList != null) { foreach (FileFolers item in this.fileFolersList) { if (item.FileType == FileType.Folder) { long temp = 0; GetFiloderSize(item.FullPath, ref temp); FileSize += temp; } if (item.FileType == FileType.File) { FileInfo fileInfo = new FileInfo(item.FullPath); FileSize += fileInfo.Length; } } } return FileSize; } /// <summary> /// 获取刻录 /// </summary> /// <returns></returns> private NERO_BURN_OPTIONS GetNeroBurnOptions() { NERO_BURN_OPTIONS options = (NERO_BURN_OPTIONS)((uint)NERO_BURN_OPTIONS.NERO_BURN_OPTION_CREATE_ISO_FS + (uint)NERO_BURN_OPTIONS.NERO_BURN_OPTION_USE_JOLIET); return options; } /// <summary> /// 刻录形式 /// </summary> /// <returns></returns> private NERO_BURN_FLAGS GetNeroFlages() { NERO_BURN_FLAGS flags = new NERO_BURN_FLAGS(); flags = flags | NERO_BURN_FLAGS.NERO_BURN_FLAG_WRITE; flags = flags | NERO_BURN_FLAGS.NERO_BURN_FLAG_CLOSE_SESSION; flags = flags | NERO_BURN_FLAGS.NERO_BURN_FLAG_BUF_UNDERRUN_PROT; flags = flags | NERO_BURN_FLAGS.NERO_BURN_FLAG_DISABLE_ABORT; flags = flags | NERO_BURN_FLAGS.NERO_BURN_FLAG_DAO; flags = flags | NERO_BURN_FLAGS.NERO_BURN_FLAG_CD_TEXT; flags = flags | NERO_BURN_FLAGS.NERO_BURN_FLAG_DETECT_NON_EMPTY_CDRW; flags = flags | NERO_BURN_FLAGS.NERO_BURN_FLAG_SPEED_IN_KBS; return flags; } #region ISO部分 /// <summary> /// 添加文件到光盘 /// </summary> /// <param name="sFile"></param> /// <param name="isoTrack"></param> private void AddFileToISO(string sFile, ref NeroISOTrack isoTrack) { // This is a file. Create a new NeroFile // change its properties. // NeroFile file = new NeroFileClass(); file.SourceFilePath = sFile; file.Name = Path.GetFileName(sFile); file.EntryTime = Directory.GetLastWriteTime(sFile); // In this implementation, specified files are added // to the root of the disc only. // XInvoke(ShowBurshProcess, new ProcessEntity(0, string.Format("添加文件{0}到关盘", sFile))); isoTrack.RootFolder.Files.Add(file); } /// <summary> /// 添加文件到目录 /// </summary> private void AddFileFolerToISO(ref NeroISOTrack isoTrack) { if (this.fileFolersList != null) { foreach (FileFolers item in this.fileFolersList) { if (item.FileType == FileType.Folder) { NeroFolder folder = isoTrack.RootFolder; AddFolderRecursively(ref folder, item.FullPath); } if (item.FileType == FileType.File) { AddFileToISO(item.FullPath, ref isoTrack); } } } } /// <summary> /// 创建一个光盘 /// </summary> /// <returns></returns> private NeroISOTrack CreateISOTrack() { NeroISOTrack isoTrack = new NeroISOTrackClass(); return isoTrack; } #endregion #region 文件文件夹 /// <summary> /// 添加目录 /// </summary> /// <param name="directioryPath"></param> public void AddDirectory(string directioryPath) { if (!Directory.Exists(directioryPath)) { return; } fileFolersList.Add(new FileFolers() { FileType = FileType.Folder, FullPath = directioryPath }); } /// <summary> /// 添加一个目录 /// </summary> /// <param name="filePath"></param> public void AddFile(string filePath) { if (!File.Exists(filePath)) { return; } fileFolersList.Add(new FileFolers() { FullPath = filePath, FileType = FileType.File }); } /// <summary> /// 这个函数是用于递归路径添加到提供的父NeroFolder /// </summary> /// <param name="folderParent"></param> /// <param name="sPath"></param> private void AddFolderRecursively(ref NeroFolder folderParent, string sPath) { NeroFolder folder = new NeroFolderClass(); folderParent.Folders.Add(folder); string[] sSplits = sPath.Split(new char[] { '\\' }, sPath.Length); if (sSplits.GetLength(0) >= 2) { string sFolderName = sSplits[sSplits.GetLength(0) - 2]; folder.Name = sFolderName; string[] sDirectories = Directory.GetDirectories(sPath); foreach (string sSubDirPath in sDirectories) { AddFolderToFolder(sSubDirPath + "\\", ref folder); } } string[] sFiles = Directory.GetFiles(sPath); foreach (string sFile in sFiles) { AddFileToFolder(sFile, ref folder); } } /// <summary> /// 添加文件夹到关盘 /// </summary> private void AddFolderToFolder(string sPath, ref NeroFolder folderParent) { XInvoke(ShowBurshProcess, new ProcessEntity(0, string.Format("添加文件假{0}到关盘", sPath))); AddFolderRecursively(ref folderParent, sPath); } /// <summary> /// 添加文件到目录 /// </summary> /// <param name="sFile"></param> /// <param name="folder"></param> private void AddFileToFolder(string sFile, ref NeroFolder folder) { NeroFile file = new NeroFileClass(); file.SourceFilePath = sFile; file.Name = Path.GetFileName(sFile); file.EntryTime = Directory.GetLastWriteTime(sFile); XInvoke(ShowBurshProcess, new ProcessEntity(0, string.Format("添加文件{0}到关盘", sFile))); folder.Files.Add(file); } #endregion #region 事件 /// <summary> /// 刻录出错 /// </summary> /// <param name="ex"></param> void helper_BrushError(Exception ex) { XInvoke(BrushError, ex); } /// <summary> /// 刻录成功后 /// </summary> /// <param name="value"></param> void helper_BrushSuccess(string value) { XInvoke(BrushSuccess, value); } /// <summary> /// 子进度 /// </summary> /// <param name="percentEvent"></param> void helper_SubShowBurshProcess(ProcessEntity percentEvent) { XInvoke(SubShowBurshProcess, percentEvent); } /// <summary> /// 显示日志记录 /// </summary> /// <param name="value"></param> void helper_ShowLogLine(string value) { XInvoke(ShowLogLine, value); } /// <summary> /// 显示百分比进度 /// </summary> /// <param name="percentEvent"></param> void helper_ShowBurshProcess(ProcessEntity percentEvent) { XInvoke(ShowBurshProcess, percentEvent); } /// <summary> /// 显示时间进度 /// </summary> /// <param name="time"></param> void helper_ShowTimeProcess(string time) { XInvoke(ShowTimeProcess, time); } /// <summary> /// 显示可以刻录的速度 /// </summary> /// <param name="collection"></param> void speedHelper_GetSpeedCollect(SpeedEntityCollection collection) { XInvoke(this.ShowSpeedCollect, collection); } /// <summary> /// 显示光盘信息 /// </summary> /// <param name="disc"></param> void disHelper_ShowDisc(DiscInfoEntity disc) { XInvoke(this.ShowDisc, disc); } /// <summary> /// 调用事件 /// </summary> /// <param name="delegateValue"></param> /// <param name="args"></param> private void XInvoke(Delegate delegateValue, params object[] args) { if (this.ParentFrm == null) { StopThread(); return; } if (this.ParentFrm != null && this.ParentFrm.IsDisposed) { StopThread(); return; } if (delegateValue != null) { this.ParentFrm.BeginInvoke(delegateValue, args); Thread.Sleep(10); } } #endregion }
本机刻录前需要获取光盘信息,系统刻录是需要光盘的容量,大小类型等信息,采用多线程刻录,防止因为刻录卡死界面线程
下面的测试功能:
最后把我的代码分享出来:http://yunpan.cn/QTeiwZifcurhr (提取码:a7d8)
没有找到博客园上传文件地方,就用网盘了.