如何从 Windows 命令行构建 CD ISO 映像文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/223316/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 05:35:32  来源:igfitidea点击:

How to build a CD ISO image file from the windows command line?

windowsbuild-processbuild-automationiso

提问by Peter

In an effort to satisfy "The Joel Test" question #2 "Can you make a build in one step?", I'm trying to complete a release candidate build script with the creation of a CD iso from the collection of files gathered and generated by the installer creator.

为了满足“乔尔测试”问题 #2“你能一步构建吗?”,我试图通过从收集的文件集合中创建 CD iso 来完成一个发布候选构建脚本,并且由安装程序创建者生成。

There seem to be many good tools (many free) out there that will create ISOs, but I need to find one that can be run at the windows command line so I can integrate it into the NAnt build script that's fired off by Cruise Control.

似乎有很多很好的工具(很多免费)可以创建 ISO,但我需要找到一个可以在 Windows 命令行上运行的工具,以便我可以将它集成到由 Cruise Control 触发的 NAnt 构建脚本中。

Build environment is:

构建环境为:

  • Windows Server 2003
  • .NET 1.1 - 3.5 (application we're creating is built on 2.0)
  • NullSoft installer (NSIS)
  • CruiseControl.net
  • NAnt
  • 视窗服务器 2003
  • .NET 1.1 - 3.5(我们正在创建的应用程序是基于 2.0 构建的)
  • NullSoft 安装程序 (NSIS)
  • 巡航控制网
  • 南特

I've been googling around, but no luck yet.

我一直在谷歌搜索,但还没有运气。

Anyone have a recommendation?

有人有推荐吗?

回答by Andrew

Try mkisofs. It's part of the cdrecordproject.

试试 mkisofs。它是cdrecord项目的一部分。

回答by festive_ken

Blatant plug, but I've just released an alpha version of an OpenSource C# library that can create ISO files. Doesn't directly integrate with Nant, but you could wrap up the library to achieve that. Theres a sample app (ISOCreate) that creates ISOs from a directory structure, but this sample could also get you started:

明目张胆的插件,但我刚刚发布了一个可以创建 ISO 文件的开源 C# 库的 alpha 版本。不直接与 Nant 集成,但您可以封装库来实现这一点。有一个从目录结构创建 ISO 的示例应用程序 (ISOCreate),但此示例也可以帮助您入门:

CDBuilder builder = new CDBuilder();
builder.UseJoliet = true;
builder.VolumeIdentifier = "A_SAMPLE_DISK";
builder.AddFile(@"Folder\Hello.txt", Encoding.ASCII.GetBytes("Hello World!"));
builder.Build(@"C:\temp\sample.iso");

.NET DiscUtils(on GitHub)

.NET DiscUtils(在 GitHub 上)

回答by kibibu

Creating a simple CD ISO

创建一个简单的 CD ISO

I've found a significantlyeasier approach, and it doesn't require Cygwin: CDBurnerXP

我发现一个显著更简单的方法,它不需要Cygwin的:在CDBurnerXP

It's not really advertised on the site, but it includes a command-line edition, as cdbxpcmd.exe. There is also some documentation about the command-line options.

它并没有在网站上真正做广告,但它包含一个命令行版本,如cdbxpcmd.exe. 还有一些关于命令行选项的文档

Of particular interest are the -isoand -formatoptions; used something like:

特别感兴趣的是-iso-format选项;使用了类似的东西:

cdbxpcmd --burn-data -folder:input -iso:output.iso -format:iso -changefiledates

to generate an ISO called output.isofrom the files in the inputfolder

生成output.iso从文件input夹中的文件调用的 ISO



Creating a Bootable ISO

创建可引导 ISO

The command line tool doesn't appear to let you make a bootable CD directly. However, if you know your list of files isn't going to change (ie only the content of those files), you could try the following (untested):

命令行工具似乎不允许您直接制作可引导 CD。但是,如果您知道您的文件列表不会改变(即只有这些文件的内容),您可以尝试以下操作(未经测试):

  • Load up the CDBurnerXP GUI version
  • Add the files interactively
  • Select Disc->Burn Options...
  • Set up your boot image
  • Select File->Save to create a DXP file (which is CDBurnerXP's compilation format)
  • 加载 CDBurnerXP GUI 版本
  • 以交互方式添加文件
  • 选择光盘->刻录选项...
  • 设置启动映像
  • 选择File->Save,创建一个DXP文件(CDBurnerXP的编译格式)

Then, you can use the following command

然后,您可以使用以下命令

cdbxpcmd --burn-data -layout:mycompilation.dxp -iso:output.iso -format:iso

回答by Gerhard

Get mkisofshere- it is part of cdrtools. Available for most platforms.

获取mkisofs这里-这是中cdrtools的一部分。适用于大多数平台。

USAGE examples:

用法示例:

mkisofs -v -dvd-video -V "VOLUME_NAME" -o "c:\my movies\iso\movie.iso" "c:\my movies\dvd"
mkisofs -r -R -J -l -L -o image-file.iso c:\project\install

回答by Tamir

If you want to be Microsoft addictive (not install additional software). You can use IMAPI, build into Windows to burn images. Additional information regarding scripting IMAPI can be found in MSDN

如果您想对 Microsoft 上瘾(而不是安装其他软件)。您可以使用内置于 Windows 中的 IMAPI 来刻录图像。可以在 MSDN 中找到有关脚本 IMAPI 的其他信息

回答by monkut

I've used magiciso, but haven't tested it extensivly. (I may try some of the others mentioned here after some testing) I first make an installer (single file) then just make this an iso.

我使用过magiciso,但还没有对其进行广泛的测试。(经过一些测试,我可能会尝试这里提到的其他一些)我首先制作一个安装程序(单个文件),然后将其制作成一个iso。

http://www.magiciso.com/

http://www.magiciso.com/

Here's the result of my struggle to get this working in python:

这是我努力在 python 中工作的结果:

add_option = '-a'
add_option_value = installer_fullpath
response_option = '-py' # answer yes to all options 


# Get the tempfile name -- to resolve long name issue
# --> My file names were initially too long for MagicIso and it would choke
f_handle = tempfile.TemporaryFile(suffix='.iso', prefix='mi_', dir='.')
temp_filename = f_handle.name
f_handle.close() # File automatically deleted on close                                

args = (magiciso_exe_fullpath,temp_filename,response_option,add_option,add_option_value)

# log output to file
magiciso_con_f = open(MAGICISO_CON_LOG,'w')

magiciso_process = subprocess.Popen(args,stdout=magiciso_con_f,stderr=magiciso_con_f)
magiciso_process.wait()

回答by KERR

Powershell can create an ISO. The below example includes a GUI. Credit to http://blog.apps.id.au/?p=5321

Powershell 可以创建 ISO。下面的示例包括一个 GUI。归功于http://blog.apps.id.au/?p=5321

# Author: Hrisan Dzhankardashliyski
# Date: 20/05/2015

# Inspiration from
#
#   http://blogs.msdn.com/b/opticalstorage/archive/2010/08/13/writing-optical-discs-using-imapi-2-in-powershell.aspx</a>
#
# and
#
#   http://tools.start-automating.com/Install-ExportISOCommand/</a>
#
# with help from
#
#   http://stackoverflow.com/a/9802807/223837</a>

$InputFolder = ""

function WriteIStreamToFile([__ComObject] $istream, [string] $fileName)
{
# NOTE: We cannot use [System.Runtime.InteropServices.ComTypes.IStream],
# since PowerShell apparently cannot convert an IStream COM object to this
# Powershell type.  (See <a href="http://stackoverflow.com/a/9037299/223837">http://stackoverflow.com/a/9037299/223837</a> for
# details.)
#
# It turns out that .NET/CLR _can_ do this conversion.
#
# That is the reason why method FileUtil.WriteIStreamToFile(), below,
# takes an object, and casts it to an IStream, instead of directly
# taking an IStream inputStream argument.

$cp = New-Object CodeDom.Compiler.CompilerParameters
$cp.CompilerOptions = "/unsafe"
$cp.WarningLevel = 4
$cp.TreatWarningsAsErrors = $true

Add-Type -CompilerParameters $cp -TypeDefinition @"
using System;
using System.IO;
using System.Runtime.InteropServices.ComTypes;

namespace My
{

public static class FileUtil {
public static void WriteIStreamToFile(object i, string fileName) {
IStream inputStream = i as IStream;
FileStream outputFileStream = File.OpenWrite(fileName);
int bytesRead = 0;
int offset = 0;
byte[] data;
do {
data = Read(inputStream, 2048, out bytesRead);
outputFileStream.Write(data, 0, bytesRead);
offset += bytesRead;
} while (bytesRead == 2048);
outputFileStream.Flush();
outputFileStream.Close();
}

unsafe static private byte[] Read(IStream stream, int toRead, out int read) {
byte[] buffer = new byte[toRead];
int bytesRead = 0;
int* ptr = &bytesRead;
stream.Read(buffer, toRead, (IntPtr)ptr);
read = bytesRead;
return buffer;
}
}

}
"@

[My.FileUtil]::WriteIStreamToFile($istream, $fileName)
}

# The Function defines the ISO parameturs and writes it to file
function createISO([string]$VolName,[string]$Folder,[bool]$IncludeRoot,[string]$ISOFile){

# Constants from <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364840.aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/aa364840.aspx</a>
$FsiFileSystemISO9660   = 1
$FsiFileSystemJoliet    = 2
$FsiFileSystemUDF      = 4

$fsi = New-Object -ComObject IMAPI2FS.MsftFileSystemImage

#$fsi.FileSystemsToCreate = $FsiFileSystemISO9660 + $FsiFileSystemJoliet

$fsi.FileSystemsToCreate = $FsiFileSystemUDF
#When FreeMediaBlocks is set to 0 it allows the ISO file to be with unlimited size
$fsi.FreeMediaBlocks = 0
$fsi.VolumeName = $VolName

$fsi.Root.AddTree($Folder, $IncludeRoot)

WriteIStreamToFile $fsi.CreateResultImage().ImageStream $ISOFile
}

Function Get-Folder($initialDirectory)

{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")

$foldername = New-Object System.Windows.Forms.FolderBrowserDialog
$foldername.rootfolder = "MyComputer"

if($foldername.ShowDialog() -eq "OK")
{
$folder += [string]$foldername.SelectedPath
}
return $folder
}

# Show an Open Folder Dialog and return the directory selected by the user.
function Read-FolderBrowserDialog([string]$Message, [string]$InitialDirectory, [switch]$NoNewFolderButton)
{
$browseForFolderOptions = 0
if ($NoNewFolderButton) { $browseForFolderOptions += 512 }
$app = New-Object -ComObject Shell.Application
$folder = $app.BrowseForFolder(0, $Message, $browseForFolderOptions, $InitialDirectory)
if ($folder) { $selectedDirectory = $folder.Self.Path }
else { $selectedDirectory = '' }
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($app) > $null
return $selectedDirectory
}

#Prompts the user to save the ISO file, if the files does not exists it will create it otherwise overwrite without prompt
Function Get-SaveFile($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
Out-Null

$SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
$SaveFileDialog.CreatePrompt = $false
$SaveFileDialog.OverwritePrompt = $false
$SaveFileDialog.initialDirectory = $initialDirectory
$SaveFileDialog.filter = "ISO files (*.iso)| *.iso"
$SaveFileDialog.ShowHelp = $true
$SaveFileDialog.ShowDialog() | Out-Null
$SaveFileDialog.filename
}

# Show message box popup and return the button clicked by the user.
function Read-MessageBoxDialog([string]$Message, [string]$WindowTitle, [System.Windows.Forms.MessageBoxButtons]$Buttons = [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]$Icon = [System.Windows.Forms.MessageBoxIcon]::None)
{
Add-Type -AssemblyName System.Windows.Forms
return [System.Windows.Forms.MessageBox]::Show($Message, $WindowTitle, $Buttons, $Icon)
}

# GUI interface for the PowerShell script
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")  #loading the necessary .net libraries (using void to suppress output)

$Form = New-Object System.Windows.Forms.Form    #creating the form (this will be the "primary" window)
$Form.Text = "ISO Creator Tool:"
$Form.Size = New-Object System.Drawing.Size(600,300)  #the size in px of the window length, height
$Form.FormBorderStyle = 'FixedDialog'
$Form.MaximizeBox = $false
$Form.MinimizeBox = $false

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(20,20)
$objLabel.Size = New-Object System.Drawing.Size(120,20)
$objLabel.Text = "Please select a Folder:"
$Form.Controls.Add($objLabel)

$InputBox = New-Object System.Windows.Forms.TextBox
$InputBox.Location = New-Object System.Drawing.Size(150,20)
$InputBox.Size = New-Object System.Drawing.Size(300,20)
$InputBox.Enabled = $false
$Form.Controls.Add($InputBox)

$objLabel2 = New-Object System.Windows.Forms.Label
$objLabel2.Location = New-Object System.Drawing.Size(20,80)
$objLabel2.Size = New-Object System.Drawing.Size(120,20)
$objLabel2.Text = "ISO File Name:"
$Form.Controls.Add($objLabel2)

$InputBox2 = New-Object System.Windows.Forms.TextBox
$InputBox2.Location = New-Object System.Drawing.Size(150,80)
$InputBox2.Size = New-Object System.Drawing.Size(300,20)
$InputBox2.Enabled = $false
$Form.Controls.Add($InputBox2)

$objLabel3 = New-Object System.Windows.Forms.Label
$objLabel3.Location = New-Object System.Drawing.Size(20,50)
$objLabel3.Size = New-Object System.Drawing.Size(120,20)
$objLabel3.Text = "ISO Volume Name:"
$Form.Controls.Add($objLabel3)

$InputBox3 = New-Object System.Windows.Forms.TextBox
$InputBox3.Location = New-Object System.Drawing.Size(150,50)
$InputBox3.Size = New-Object System.Drawing.Size(150,20)
$Form.Controls.Add($InputBox3)

$objLabel4 = New-Object System.Windows.Forms.Label
$objLabel4.Location = New-Object System.Drawing.Size(20,120)
$objLabel4.Size = New-Object System.Drawing.Size(120,20)
$objLabel4.Text = "Status Msg:"
$Form.Controls.Add($objLabel4)

$InputBox4 = New-Object System.Windows.Forms.TextBox
$InputBox4.Location = New-Object System.Drawing.Size(150,120)
$InputBox4.Size = New-Object System.Drawing.Size(200,20)
$InputBox4.Enabled = $false
$InputBox4.Text = "Set ISO Parameters..."
$InputBox4.BackColor = "LimeGreen"
$Form.Controls.Add($InputBox4)

$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(470,20)
$Button.Size = New-Object System.Drawing.Size(80,20)
$Button.Text = "Browse"
$Button.Add_Click({
$InputBox.Text=Read-FolderBrowserDialog
$InputBox4.Text = "Set ISO Parameters..."

})
$Form.Controls.Add($Button)

$Button2 = New-Object System.Windows.Forms.Button
$Button2.Location = New-Object System.Drawing.Size(470,120)
$Button2.Size = New-Object System.Drawing.Size(80,80)
$Button2.Text = "CreateISO"
$Button2.Add_Click({

if(($InputBox.Text -eq "") -or ($InputBox3.Text -eq "")){
Read-MessageBoxDialog "You have to select folder and specify ISO Volume Name" "Error: No Parameters entered!"
} else{
$SaveDialog = Get-SaveFile
#If you click cancel when save file dialog is called
if ($SaveDialog -eq ""){
return
}
$InputBox2.Text= $SaveDialog
$InputBox2.Refresh()
if($checkBox1.Checked){
$includeRoot=$true
}
else{
$includeRoot=$false
}
$InputBox4.BackColor = "Red"
$InputBox4.Text = "Generating ISO File!"
$InputBox4.Refresh()
createISO $InputBox3.Text $InputBox.Text $includeRoot $InputBox2.Text
$InputBox4.BackColor = "LimeGreen"
$InputBox4.Text = "ISO Creation Finished!"
$InputBox4.Refresh()
}
})
$Form.Controls.Add($Button2)

$objLabel5 = New-Object System.Windows.Forms.Label
$objLabel5.Location = New-Object System.Drawing.Size(20,160)
$objLabel5.Size = New-Object System.Drawing.Size(280,20)
$objLabel5.Text = "Check the box if you want to include the top folder:"
$Form.Controls.Add($objLabel5)

$checkBox1 = New-Object System.Windows.Forms.CheckBox
$checkBox1.Location = New-Object System.Drawing.Size(300,156)
$Form.Controls.Add($checkBox1)

$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()

回答by alexandrul

I am using mkisofs.exefrom the installation kit of nLiteor BartPE, from where I also learned the required parameters for building a bootable cd.

我正在使用nLiteBartPEmkisofs.exe的安装工具包,从那里我还学习了构建可启动 cd 所需的参数。