C#光盘刻录
一.背景介绍
最近公司一个老项目需要添加导出数据到光盘的功能.开始对这功能添加有点抵触的.光盘?都啥年代了.
光盘一种即将淘汰的存储媒介.就像当年的随身听,Mp3,Mp4一样,即将退出历史舞台.领导让加,发牢骚归发牢骚,活还是得干哈.
从网上找了一些资料,都是特别古老的文档了.很多方法用起来并不是特别的方便.
1.CodePlex Archive https://archive.codeplex.com/?p=csimapi2samples 其中的例子功能不全,参数都使用dynamic类型,刚开始不了解那些基础概念时,理解起来比较难.可以参考学习.
2.博客:https://blog.csdn.net/huanghunjiuba/article/details/12967463 中的例子BurnCdDemo.
里面的BurnCdDemo对ImApi2做了封装.其实例子里面的封装做的挺不错的.注释也特别全.
在做测试的时候发现刻录功能在本机运行的非常好.在公司的测试机上却获取不到光盘大小,取到的大小是负数.对着Demo的源代码检查了半天,没找到原因.╮( ̄▽ ̄")╭,脑袋好大的.后来找到原因了,在下面的过程中会描述下.
PS:个人不喜欢啥都做抽象.抽象,意味着要多写代码,查找问题也不方便.抽象,依赖注入,控制反转是个好东西,就是要多写许多代码.
个人觉得,很多技术还是要看实际项目情况而使用,没有必要去为了追求使用而滥用.看起来高大上,实际多写了代码维护也不方便.
So,自己搞个简单点的.因为就那么几个功能:获取光驱设备列表,获取光盘信息,添加媒体文件,刻录,进度通知.
二.工欲善其事必先利其器
因工作电脑没有光驱,测试非常不方便.那我们就安装一个虚拟光驱.
推荐一个比较好用的虚拟光驱软件PhantomBurner,带注册码.下载地址:https://download.csdn.net/download/zjhaag/10909339
安装过程就不说了.选下安装路径,一路Next.安装完成后提示重启.其实不重启也可以用.
安装完成后界面如下.在About中输入注册码激活.点击Create,选择Dvd+RW创建Virtual Disc Image.在资源管理器中就可以看到我们创建的虚拟光驱了.
三.开工
1.设备列表获取
(1)首先添加一个RecorderHelper.在RecorderHelper类中添加一个静态方法GetRecorderList用于获取光驱设备列表.
/// <summary>
/// 获取光驱设备列表
/// </summary>
/// <returns></returns>
public static List<Recorder> GetRecorderList()
{
List<Recorder> recordList = new List<Recorder>(); // Create a DiscMaster2 object to connect to optical drives.
MsftDiscMaster2 discMaster = new MsftDiscMaster2();
for (int i = ; i < discMaster.Count; i++)
{
if (discMaster[i] != null)
{
Recorder recorder = new Recorder(discMaster[i]);
recordList.Add(recorder);
}
}
return recordList;
}
此时,需要Recorder光驱对象主要属性如下
MsftDiscRecorder2 msRecorder = null; //Recorder /// <summary>
/// 当前磁盘标签
/// </summary>
public string RecorderName { get; private set; } /// <summary>
/// 是否支持当前刻录机
/// </summary>
public bool IsRecorderSupported { get; private set; } /// <summary>
/// 是否支持当前磁盘媒体
/// </summary>
public bool IsCurrentMediaSupported { get; private set; } /// <summary>
/// 当前磁盘可用大小
/// </summary>
public long FreeDiskSize { get; private set; } /// <summary>
/// 当前磁盘总大小
/// </summary>
public long TotalDiskSize { get; private set; } /// <summary>
/// 当前媒体状态
/// </summary>
public IMAPI_FORMAT2_DATA_MEDIA_STATE CurMediaState { get; private set; } /// <summary>
/// 当前媒体状态
/// </summary>
public string CurMediaStateName { get; private set; } /// <summary>
/// 当前媒体类型
/// </summary>
public IMAPI_MEDIA_PHYSICAL_TYPE CurMediaType { get; private set; } /// <summary>
/// 当前媒体类型
/// </summary>
public string CurMediaTypeName { get; private set; } /// <summary>
/// 是否可以刻录
/// </summary>
public bool CanBurn {get;private set;}
(2)对Recorder各属性进行初始化,赋值.主要方法如下
/// <summary>
/// Recorder Ctor
/// </summary>
/// <param name="uniqueId">标识Id</param>
public Recorder(string uniqueId)
{
this.uniqueId = uniqueId;
msRecorder = new MsftDiscRecorder2();
msRecorder.InitializeDiscRecorder(uniqueId);
InitRecorder(); this.BurnMediaList = new List<BurnMedia>();
this.BurnMediaFileSize = ;
} /// <summary>
/// 初始化Recorder
/// 更新Recorder信息,更新光盘后可重试.
/// </summary>
public void InitRecorder()
{
try
{
if (msRecorder.VolumePathNames != null && msRecorder.VolumePathNames.Length > )
{
foreach (object mountPoint in msRecorder.VolumePathNames)
{ //挂载点 取其中一个
RecorderName = mountPoint.ToString();
break;
}
}
// Define the new disc format and set the recorder
MsftDiscFormat2Data dataWriter = new MsftDiscFormat2Data();
dataWriter.Recorder = msRecorder; if (!dataWriter.IsRecorderSupported(msRecorder))
{
return;
}
if (!dataWriter.IsCurrentMediaSupported(msRecorder))
{
return;
}
if (dataWriter.FreeSectorsOnMedia >= )
{ //可用大小
FreeDiskSize = dataWriter.FreeSectorsOnMedia * 2048L;
} if (dataWriter.TotalSectorsOnMedia >= )
{ //总大小
TotalDiskSize = dataWriter.TotalSectorsOnMedia * 2048L;
}
CurMediaState = dataWriter.CurrentMediaStatus; //媒体状态
CurMediaStateName = RecorderHelper.GetMediaStateName(CurMediaState);
CurMediaType = dataWriter.CurrentPhysicalMediaType; //媒介类型
CurMediaTypeName = RecorderHelper.GetMediaTypeName(CurMediaType);
CanBurn = RecorderHelper.GetMediaBurnAble(CurMediaState); //判断是否可刻录
}
catch (COMException ex)
{
string errMsg = ex.Message.Replace("\r\n", ""); //去掉异常信息里的\r\n
this.CurMediaStateName = $"COM Exception:{errMsg}";
}
catch (Exception ex)
{
this.CurMediaStateName = $"{ex.Message}";
}
}
(3)测试代码如下
#region 查找光驱设备
Console.Clear();
Console.WriteLine("正在查找光驱设备..");
List<Recorder> recorderList = RecorderHelper.GetRecorderList();
if (recorderList.Count <= )
{
Console.WriteLine("没有可以使用的光驱,请检查.");
Console.WriteLine("请连接光驱后,按任意键重试...");
Console.ReadKey();
continue;
}
for (int i = ; i < recorderList.Count; i++)
{
Recorder tempRecorder = recorderList[i];
Console.WriteLine($"发现光驱设备:[{i+1}] {tempRecorder.RecorderName}");
Console.WriteLine($"媒体类型:{tempRecorder.CurMediaTypeName}");
Console.WriteLine($"媒体状态:{tempRecorder.CurMediaStateName}");
Console.WriteLine("支持刻录:" + (tempRecorder.CanBurn ? "√" : "×"));
Console.WriteLine($"可用大小:{FormatFileSize(tempRecorder.FreeDiskSize)}");
Console.WriteLine($"总大小:{FormatFileSize(tempRecorder.TotalDiskSize)}");
}
if (!recorderList.Any(r=>r.CanBurn))
{
Console.WriteLine("没有可以用于刻录的光驱设备,请检查后,按任意键重试.");
Console.ReadKey();
continue;
}
#endregion
测试结果:
至此,我们完成了对于光驱设备列表的获取及Recorder对象各属性的初始化工作.
说明下,对光驱设备操作需要有管理员权限,没有管理员权限会导致获取失败.对于C#应用程序设置以管理员身份启动请参照https://www.cnblogs.com/babycool/p/3569183.html
2.添加刻录文件
(1)我们为Recorder对象添加待刻录媒体对象列表和待刻录媒体文件大小两个属性
/// <summary>
/// 待刻录媒体对象List
/// </summary>
public List<BurnMedia> BurnMediaList {get;set;} /// <summary>
/// 待刻录媒体文件大小
/// </summary>
public long BurnMediaFileSize { get; set; }
待刻录媒体对象定义如下
/// <summary>
/// 刻录媒体
/// </summary>
public class BurnMedia
{
/// <summary>
/// 路径
/// </summary>
public string MediaPath { get; set; } /// <summary>
/// 名称
/// </summary>
public string MediaName { get; set; } /// <summary>
/// 是否是文件夹
/// </summary>
public bool IsDirectory { get; set; } /// <summary>
/// 大小
/// </summary>
public long Size { get; set; }
}
(2)为Recorder对象添加AddBurnMedia方法
/// <summary>
/// 添加刻录媒体对象
/// </summary>
public BurnMedia AddBurnMedia(string path)
{
BurnMedia media = null;
if(string.IsNullOrEmpty(path))
{
throw new Exception("文件路径不能为空.");
}
if(!CanBurn)
{
throw new Exception("当前磁盘状态不支持刻录.");
}
media = new BurnMedia();
long fileSize = ;
if (Directory.Exists(path))
{
DirectoryInfo dirInfo = new DirectoryInfo(path);
fileSize = GetDirectorySize(path);
media.MediaName = dirInfo.Name;
media.MediaPath = dirInfo.FullName;
media.Size = fileSize;
media.IsDirectory = true;
}
else if (File.Exists(path))
{
FileInfo fileInfo = new FileInfo(path);
fileSize = fileInfo.Length;
media.MediaName = fileInfo.Name;
media.MediaPath = fileInfo.FullName;
media.Size = fileSize;
media.IsDirectory = false;
}
else
{
throw new Exception("文件不存在");
}
if (BurnMediaFileSize + fileSize >= FreeDiskSize)
{
throw new Exception("剩余空间不足");
}
if (BurnMediaList.Any(m => m.MediaName.ToLower() == media.MediaName.ToLower()))
{
throw new Exception($"已存在媒体名称为{media.MediaName}的对象");
}
BurnMediaList.Add(media);
BurnMediaFileSize += fileSize;
return media;
}
(3)测试代码如下
while (true)
{
Console.WriteLine("添加文件:请输入待刻录文件或文件夹路径. 0完成 1查看已添加文件");
string filePath = Console.ReadLine();
if (string.IsNullOrEmpty(filePath))
{
continue;
}
else if (filePath == "")
{
break;
}
else if (filePath == "")
{
ShowBurnMediaListInfo(recorder);
}
else
{
try
{
BurnMedia media = recorder.AddBurnMedia(filePath);
Console.WriteLine($"添加成功:{filePath}");
Console.WriteLine("文件大小:" + FormatFileSize(media.Size));
Console.WriteLine("已添加文件总大小:" + FormatFileSize(recorder.BurnMediaFileSize));
}
catch (Exception ex)
{
Console.WriteLine($"添加失败:{ex.Message}");
}
}
}
运行结果:
3.刻录及刻录进度通知
为Recorder对象添加Burn方法.同时,添加刻录进度通知.
(1)添加BurnProgressChanged委托用于通知刻录进度
/// <summary>
/// 刻录进度delegate
/// </summary>
public delegate void BurnProgressChanged(BurnProgress burnProgress);
刻录进度通知对象定义如下(其属性为根据需求添加):
/// <summary>
/// 刻录进度对象
/// </summary>
public class BurnProgress
{
/// <summary>
/// 当前操作
/// 对应IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION枚举
/// 4 正在写入数据 5完成数据写入 6 刻录完成
/// </summary>
public int CurrentAction { get; set; } /// <summary>
/// 当前操作Name
/// </summary>
public string CurrentActionName { get; set; } /// <summary>
/// 已用时间单位S
/// </summary>
public int ElapsedTime { get; set; } /// <summary>
/// 预计总时间单位S
/// </summary>
public int TotalTime { get; set; } /// <summary>
/// 数据写入进度
/// </summary>
public decimal Percent { get; set; } /// <summary>
/// 数据写入进度%
/// </summary>
public string PercentStr { get { return Percent.ToString("0.00%"); } }
}
(2)为Recorder对象添加委托属性
/// <summary>
/// 刻录进度变化通知
/// </summary>
public BurnProgressChanged OnBurnProgressChanged { get; set; }
(3)为Recorder添加Burn方法
/// <summary>
/// 刻录
/// </summary>
public void Burn(string diskName = "SinoUnion")
{
if(!CanBurn)
{
throw new Exception("当前磁盘状态不支持刻录");
}
if (string.IsNullOrEmpty(diskName))
{
throw new Exception("DiskName不能为空");
}
if (BurnMediaList.Count <= )
{
throw new Exception("待刻录文件列表不能为空");
}
if(BurnMediaFileSize<=)
{
throw new Exception("待刻录文件大小为0");
} try
{ //说明
//1.fsi.ChooseImageDefaults用的是IMAPI2FS的,我们定义的msRecorder是IMAPI2的.所以必须用动态类型
//2.dataWriter也要使用动态类型,要不然Update事件会出异常.
// Create an image stream for a specified directory.
dynamic fsi = new IMAPI2FS.MsftFileSystemImage(); // Disc file system
IMAPI2FS.IFsiDirectoryItem dir = fsi.Root; // Root directory of the disc file system
dynamic dataWriter = new MsftDiscFormat2Data(); //Create the new disc format and set the recorder dataWriter.Recorder = msRecorder;
dataWriter.ClientName = "SinoGram";
//不知道这方法不用行不行.用的参数是IMAPI2FS的.
//所以学官网的例子,把fsi改成了动态的.使用msRecorder作为参数
fsi.ChooseImageDefaults(msRecorder); //设置相关信息
fsi.VolumeName = diskName; //刻录磁盘名称
for (int i = ; i < BurnMediaList.Count; i++)
{
dir.AddTree(BurnMediaList[i].MediaPath, true);
}
// Create an image from the file system
IStream stream = fsi.CreateResultImage().ImageStream;
try
{
dataWriter.Update += new DDiscFormat2DataEvents_UpdateEventHandler(BurnProgressChanged);
dataWriter.Write(stream);// Write stream to disc
}
catch (System.Exception ex)
{
throw ex;
}
finally
{
if (stream != null)
{
Marshal.FinalReleaseComObject(stream);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"刻录失败:{ex.Message}");
}
} /// <summary>
/// 刻录进度通知
/// </summary>
/// <param name="object"></param>
/// <param name="progress"></param>
void BurnProgressChanged(dynamic @object, dynamic progress)
{
BurnProgress burnProgress = new BurnProgress();
try
{
burnProgress.ElapsedTime = progress.ElapsedTime;
burnProgress.TotalTime = progress.TotalTime;
burnProgress.CurrentAction = progress.CurrentAction;
if (burnProgress.ElapsedTime > burnProgress.TotalTime)
{ //如果已用时间已超过预估总时间.则将预估总时间设置为已用时间
burnProgress.TotalTime = burnProgress.ElapsedTime;
}
string strTimeStatus;
strTimeStatus = "Time: " + progress.ElapsedTime + " / " + progress.TotalTime;
int currentAction = progress.CurrentAction;
switch (currentAction)
{
case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_CALIBRATING_POWER:
burnProgress.CurrentActionName = "Calibrating Power (OPC)";
break;
case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_COMPLETED:
burnProgress.CurrentActionName = "Completed the burn";
burnProgress.Percent = ;
burnProgress.TotalTime = burnProgress.ElapsedTime; //刻录完成,将预估用时,修正为已用时间
break;
case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_FINALIZATION:
burnProgress.CurrentActionName = "Finishing the writing";
burnProgress.Percent = ;
burnProgress.TotalTime = burnProgress.ElapsedTime; //写入完成,将预估用时,修正为已用时间
break;
case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_FORMATTING_MEDIA:
burnProgress.CurrentActionName = "Formatting media";
break;
case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_INITIALIZING_HARDWARE:
burnProgress.CurrentActionName = "Initializing Hardware";
break;
case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_VALIDATING_MEDIA:
burnProgress.CurrentActionName = "Validating media";
break;
case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_VERIFYING:
burnProgress.CurrentActionName = "Verifying the data";
break;
case (int)IMAPI2.IMAPI_FORMAT2_DATA_WRITE_ACTION.IMAPI_FORMAT2_DATA_WRITE_ACTION_WRITING_DATA:
dynamic totalSectors;
dynamic writtenSectors;
dynamic startLba;
dynamic lastWrittenLba;
totalSectors = progress.SectorCount;
startLba = progress.StartLba;
lastWrittenLba = progress.LastWrittenLba;
writtenSectors = lastWrittenLba - startLba;
burnProgress.CurrentActionName = "Writing data";
burnProgress.Percent = Convert.ToDecimal(writtenSectors)/ Convert.ToDecimal(totalSectors);
break;
default:
burnProgress.CurrentActionName = "Unknown action";
break;
}
}
catch (Exception ex)
{
burnProgress.CurrentActionName = ex.Message;
}
if (OnBurnProgressChanged != null)
{
OnBurnProgressChanged(burnProgress);
}
}
(4)测试代码如下
if (recorder.BurnMediaList.Count <= )
{
Console.WriteLine($"未添加任何刻录文件.已退出刻录过程.");
}
else
{
#region 刻录前确认
bool confirmBurn = false;
Console.Clear();
ShowBurnMediaListInfo(recorder);
while (true)
{
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.DarkGreen;//设置颜色.
Console.WriteLine($"刻录过程一旦开始,终止可能会造成磁盘损坏.确认要开始刻录(y/n)?");
Console.ForegroundColor = colorFore;//还原颜色.
string confirmStr = Console.ReadLine();
if (confirmStr.ToLower() == "n")
{
break;
}
else if (confirmStr.ToLower() == "y")
{
confirmBurn = true;
break;
}
}
if (!confirmBurn)
{
Console.WriteLine($"本次刻录过程已退出");
continue;
}
#endregion
Console.CursorVisible = false; //隐藏光标
ShowBurnProgressChanged(recorder);
recorder.Burn(); //刻录
Console.WriteLine();
}
(5)输出刻录进度变化,添加ShowBurnProgressChanged方法
在查找如何输出进度数据的时候,看到了控制台输出进度条的功能.带颜色的还挺漂亮的,看到好的功能就想加到我们的项目里.
/// <summary>
/// 输出刻录进度通知
/// </summary>
/// <param name="recorder"></param>
static void ShowBurnProgressChanged(Recorder recorder)
{
Console.Clear(); #region 搭建输出显示框架
Console.WriteLine();
Console.WriteLine($"**********************刻录中,请稍候**********************");
Console.WriteLine();
Console.WriteLine(" 当前操作:"); //第4行当前操作
Console.WriteLine(); // 第6行绘制进度条背景
Console.Write(" ");
Console.BackgroundColor = ConsoleColor.DarkCyan;
for (int i = ; i <= ; i++)
{ //设置50*1的为总进度
Console.Write(" ");
} Console.WriteLine();
Console.BackgroundColor = colorBack; Console.WriteLine(); //第7行输出空行
Console.WriteLine(); //第8行输出进度
Console.WriteLine($"*********************************************************"); //第9行
Console.WriteLine(); //第10行输出空行
#endregion //进度变化通知时,更新相关行数据即可.
recorder.OnBurnProgressChanged += (burnProgress) => {
if (burnProgress.CurrentAction == )
{ //刻录完成
Console.SetCursorPosition(, );
Console.WriteLine($"*************************刻录完成************************");
}
//第4行 当前操作
Console.SetCursorPosition(, );
Console.Write($" 当前操作:{burnProgress.CurrentActionName}");
Console.Write(" "); //填充空白区域
Console.ForegroundColor = colorFore; // 第6行 绘制进度条进度(进度条前预留2空格)
Console.BackgroundColor = ConsoleColor.Yellow; // 设置进度条颜色
Console.SetCursorPosition(, ); // 设置光标位置,参数为第几列和第几行
for (int i = ; i <burnProgress.Percent*; i++)
{ //每个整数写入1个空格
Console.Write(" "); // 移动进度条
}
Console.BackgroundColor = colorBack; // 恢复输出颜色 //第8行 已用时间,总时间
Console.ForegroundColor = ConsoleColor.Green;// 更新进度百分比,原理同上.
Console.SetCursorPosition(, );
Console.Write($" 进度:{burnProgress.PercentStr} " +
$"已用时间:{FormatTime(0, 0, burnProgress.ElapsedTime)} " +
$"剩余时间:{FormatTime(0, 0, burnProgress.TotalTime - burnProgress.ElapsedTime)}");
Console.Write(" "); //填充空白区域
Console.ForegroundColor = colorFore; Console.SetCursorPosition(, ); //光标 定位到第10行
};
}
运行结果如下,剩余时间为IMAPI2提供.并不一定准确.
四.BurnCdDemo获取磁盘大小为负数bug
在开始的时候,我们说了使用BurnCdDemo获取光盘大小为负数.在实际开发的过程中,也碰到了.因为我们买的光盘太大了?达到8G,实际模拟刻录时,没那么大.所以没啥问题.
我们看BurnCdDemo里Recorder对象的代码:
private long m_nDiskSize = ;
private long m_nUseableSize = ; //可用的
m_nUseableSize = msFormat.FreeSectorsOnMedia * ;
//总大小
m_nDiskSize = msFormat.TotalSectorsOnMedia * ;
msFormat.FreeSectorsOnMedia和msFormat.TotalSectorsOnMedia类型为int.大家想到原因了吧.int溢出了.所以把后面的2048改为2048L就可以了.看似正常的代码,以后在碰到类型转换时要多注意些.
五.总结
总结写点啥呢.当然是最重要的哈.上源码:https://github.com/279328316/RecorderHelper
如有问题,欢迎留言.
C#光盘刻录的更多相关文章
- 光盘刻录 CD刻录软件 Ashampoo Burning Studio特别版 刻录CD就这么简单
著名的刻录软件Nero,其近上百M体积实在太大,而且安装之后的文件体积也有上G多.这么大的体积安装使用都不方便,好在现在很多都做得很不错,比如阿香婆的光盘刻录软件Ashampoo® Burning S ...
- Ubuntu16.04 U盘安装Ubuntu16.04制作 光盘刻录 安装与简介
从今天开始,我会把我遇到过的技术问题一一记录下来,从而分享给有需要的朋友,尽量希望你们少走弯路! 一.首先从官网上下载Ubuntu16.04镜像,下载最好从官网上下载(http://www.ubunt ...
- Windows 系统光盘刻录教程-光盘怎样刻录?刻录数据光盘用"轨道一次写入"还是"光盘一次写入"?
刻录光盘需要 DVD-RW 的光驱,并且光盘需要 DVD-R 的光盘用于刻录.刻录工具可以使用https://cn.ultraiso.net/ 来进行刻录.选择软件目录 中 工具 ,选择 刻录光盘映像 ...
- Nero8刻录引导系统光盘镜像图文教程
刻录可引导的Windows系统光盘一直是电脑使用者较为需要的,今天,倡萌抽空写了这篇图文教程,希望对于菜鸟级的朋友有所帮助,大虾请飘过.本教程以最为强大的刻录软件Nero 8做为工具(其他版本的Ner ...
- iso系统镜像刻录到光盘和U盘
使用UltraISO刻录 刻录U盘,点击文件,打开,选择镜像 启动,写入硬盘镜像选择U盘即可 刻录光盘 工具,刻录光盘映像,选择镜像,需要先插入光盘刻录机(有些电脑可能自带光驱盘,且有刻录功能,那么我 ...
- 教你用软碟通(UltraISO)刻录系统光盘
用光盘装系统有几个好处:1.便携,显而易见,这是最大的优点2.大容量,比之维护光盘,可以集成N多维护工具,甚至还可以放下几个ghost镜像3.维护功能强大,因为容量大,可以放更多工具.还可以设置多重启 ...
- NERO8.0刻录系统光盘
正常启动NREO,点击NERO 8.0左下角图标(启动NERO应用程序和工具),选NERO Express Essentials,在左边的几个选项中选择“映像.项目.复制”,右边选“光盘映像或保存的项 ...
- 使用U盘代替光盘来刻录ISO镜像文件的方法
原文链接: http://jingyan.baidu.com/article/d3b74d64aa4a6a1f77e60932.html 1.以管理员身份运行UltraISO,点击“文件”菜单下的“打 ...
- 20160805_Win7x64刻录CentOS6.4x64启动光盘
使用的软件为:UltraISO.v.9.6.2.3059.exe Win7 x64 刻录 CentOS6.4 x64 启动盘,有提示错误信息. 网上查了一下,是 AHCI 的驱动没有安装.来到 联想t ...
随机推荐
- (疯狂java)第一课
(本文章只是为了好玩,没有别的意思,有理解错误之处,恳请提醒,谢谢) 环境变量的安装 记得很久之前大学学习java的时候还需要配置环境变量.系统变量,今天看了一下居然还是需要配置,想想啊,mac下面已 ...
- Java学习笔记(16)
需求:使用LinkedList存储一副扑克牌,然后实现洗牌功能 package cn.itcast.list; import java.util.LinkedList; import java.uti ...
- Generator函数(二)
for...of循环 1.for...of循环可以自动遍历Generator函数,不需要再调用next方法 function* helloWorldGenerator(){ yield 'hello' ...
- ucenter创始人密码忘记了,修改方法
简单的:1.在UCenter/data/下找到config.inc.php,打开找到下面2行代码: define('UC_FOUNDERPW', '3858cdf66b0794bfd435af8c0c ...
- jvm分析内存泄露
首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源 - 导航条 - 首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源 ...
- iOS开发利器-CocoaPods安装和使用教程
新博客http://www.liuchendi.com 开发iOS项目时肯定会用到许多第三方项目,比如说:ASIHttprequest,JSONKit等等,一些类库可能又关联着其他类库,如果超过一定的 ...
- Oracle的sqlnet.ora文件配置
DBA对这个文件一定不会陌生,大家了解最多的也一定是sqlnet.ora用来决定oracle怎么解析一个连接中出现的字符串,例如: sqlplus sys/oracle@orcl 那么这个orcl怎么 ...
- 万里长征第二步——django个人博客(第一步 ——创建主页)
运行命令行工具,输入:pip install virtualenv --安装virtualenv库. virtualenv blog_project_venv ——使用virtualenv创建一个虚 ...
- 为什么深度神经网络难以训练Why are deep neural networks hard to train?
Imagine you're an engineer who has been asked to design a computer from scratch. One day you're work ...
- linux gcc升级备忘录
1. 拉包 sudo wget http://mirrors.opencas.org/gnu/gcc/gcc-6.3.0/gcc-6.3.0.tar.bz2 #如果以上给出的镜像不可用,也可以是使用h ...