您的位置:首页 > 编程语言 > C#

C# 实现刻录光盘功能

2014-05-18 15:53 363 查看
最近公司提出一个需求,要把公司系统的图像刻录成光盘(公司系统是医院放射科系统,很多放射科的图像)

查看了很多资料发现有两个比较可靠

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/QiW6hcu9QwLfe 访问密码 4fad

没有找到博客园上传文件地方,就用网盘了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: