最近公司提出一个需求,要把公司系统的图像刻录成光盘(公司系统是医院放射科系统,很多放射科的图像)

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

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)

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

C# 实现刻录光盘功能的更多相关文章

  1. Win7自带功能,刻录光盘遇到的问题

    Win7系统的可以使用系统自带有光盘刻录功能来刻录光盘. 把一张空白光盘放入刻录机,打开“计算机”窗口,双击刻录机图标,弹出“刻录光盘”对话框,选择刻录类型.这里有两个选项:一个是“类似于USB闪存驱 ...

  2. 【转】linux下mkisofs制作光盘映像cdrecord刻录光盘

    1.制作光盘映像文件 $mkisofs -R -o /var/tmp/oracle.iso /home/oracle $mkisofs -o myiso.iso /home/oracle/data 补 ...

  3. 【203】利用UltraISO制作和刻录光盘映像的方法

    参考:利用UltraISO制作和刻录光盘映像的方法 软件:UltraISO注册版(制作镜像).rar 目录: 1.利用UltraISO制作光盘映像2.利用UltraISO刻录光盘映像文件 1.利用Ul ...

  4. 制作类似ThinkPHP框架中的PATHINFO模式功能

    一.PATHINFO功能简述 搞PHP的都知道ThinkPHP是一个免费开源的轻量级PHP框架,虽说轻量但它的功能却很强大.这也是我接触学习的第一个框架.TP框架中的URL默认模式即是PathInfo ...

  5. PHP搭建大文件切割分块上传功能

    背景 在网站开发中,文件上传是很常见的一个功能.相信很多人都会遇到这种情况,想传一个文件上去,然后网页提示"该文件过大".因为一般情况下,我们都需要对上传的文件大小做限制,防止出现 ...

  6. SQL Server2014 SP2新增的数据库克隆功能

    SQL Server2014 SP2新增的数据库克隆功能 创建测试库 --创建测试数据库 create database testtest use testtest go --创建表 )) --插入数 ...

  7. SQL Server 数据加密功能解析

    SQL Server 数据加密功能解析 转载自: 腾云阁 https://www.qcloud.com/community/article/194 数据加密是数据库被破解.物理介质被盗.备份被窃取的最 ...

  8. Taurus.MVC 2.2 开源发布:WebAPI 功能增强(请求跨域及Json转换)

    背景: 1:有用户反馈了关于跨域请求的问题. 2:有用户反馈了参数获取的问题. 3:JsonHelper的增强. 在综合上面的条件下,有了2.2版本的更新,也因此写了此文. 开源地址: https:/ ...

  9. TinyWeb v1.0 正式完成第一个Release版本(功能基于 libuv 跨平台库)

    使用方法很简单,很容易融入现有项目,使现有项目拥有Web网站功能和WebSocket,以及Socket直连! 并且包含了一个跨平台(windows/linux)工具集合; 嗯,也挺棒的^,^ 在项目中 ...

随机推荐

  1. 洛谷 P2984 [USACO10FEB]给巧克力Chocolate Giving

    题目描述 Farmer John is distributing chocolates at the barn for Valentine's day, and B (1 <= B <= ...

  2. HDOJ 4509 湫湫系列故事——减肥记II(2013腾讯编程马拉松) 并查集合并区间

    发现这种合并区间的题目还可以这么玩 给你n段时间 然后问没被占用的时间是多少 题目所给的区间是右开的导致我wa 好多人5e5*1440的暴力跑出来的时间居然只是我的两倍 不懂.... 所以并查集并没有 ...

  3. 【Python】使用cmd模块构造一个带有后台线程的交互命令行界面

    最近写一些测试工具,实在懒得搞GUI,然后意识到python有一个自带模块叫cmd,用了用发现简直是救星. 1. 基本用法 cmd模块很容易学到,基本的用法比较简单,继承模块下的Cmd类,添加需要的功 ...

  4. PJSIP-iOS源码编译

    官方文档https://trac.pjsip.org/repos/wiki/Getting-Started/iPhone 功能 在iPhone上可以实现的功能: 包含基于CoreAudio的音频设备, ...

  5. Bootstrap历练实例:验证状态

    验证状态 Bootstrap 包含了错误.警告和成功消息的验证样式.只需要对父元素简单地添加适当的 class(.has-warning. .has-error 或 .has-success)即可使用 ...

  6. CentOS7写汇编并编译运行汇编代码

    1.下载nasm编译器 下载地址是https://www.nasm.us/pub/nasm/releasebuilds/ wget https://www.nasm.us/pub/nasm/relea ...

  7. 【OS_Linux】三大文本处理工具之grep命令

    grep(global search regular expression(RE) and print out the line,整行搜索并打印匹配成功的行 语法:grep  [选项]   搜索词  ...

  8. (5)zabbix配置详解

    zabbix配置介绍 zabbix配置内容比较多,我们要分为9大块来讲解.分别如下:1.主机与组不用多数,顾名思义,他是添加主机配置与组配置. 2.监控项需要监控的项目,例如服务器负载可以使一个监控项 ...

  9. 五分钟入门 Dingo API

    基于 https://laravel-china.org/doc... 文档更简洁的描述Dingo,直戳重点,注重实践 Django-Book 概述 Dingo API帮助您轻松快速地构建自己的API ...

  10. 递归函数&二分查找

    一.递归函数 1)定义 在函数中调用函数本身,就是递归 在python中递归的深度最大为1000,但实际达不到1000 def func(): print("-----func-----&q ...