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!
" + StatusCode.ToString());
                XLogManager.LogError(StatusCode.ToString());
                BrushError(new Exception("刻录失败!
" + 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)

没有找到博客园上传文件地方,就用网盘了.

原文地址:https://www.cnblogs.com/xqaizx/p/3735270.html