33

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

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

构建环境为:

  • 视窗服务器 2003
  • .NET 1.1 - 3.5(我们正在创建的应用程序基于 2.0)
  • NullSoft 安装程序 (NSIS)
  • CruiseControl.net
  • 南安特

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

有人有推荐吗?

4

8 回答 8

17

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

于 2008-10-21T20:17:16.070 回答
14

创建一个简单的 CD ISO

我发现了一种简单得多的方法,并且不需要 Cygwin:CDBurnerXP

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

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

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

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


创建可引导 ISO

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

  • 加载 CDBurnerXP GUI 版本
  • 以交互方式添加文件
  • 选择光盘->刻录选项...
  • 设置启动映像
  • 选择File->Save创建一个DXP文件(是CDBurnerXP的编译格式)

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

cdbxpcmd --burn-data -layout:mycompilation.dxp -iso:output.iso -format:iso
于 2010-08-19T06:53:23.210 回答
13

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

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(在 GitHub 上)

于 2008-12-06T13:15:47.370 回答
12

mkisofs 到这里——它是 cdrtools 的一部分。适用于大多数平台。

用法示例:

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
于 2008-11-06T08:30:16.573 回答
6

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

于 2008-11-06T09:11:54.040 回答
4

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()
于 2017-09-06T06:22:22.803 回答
3

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

http://www.magiciso.com/

这是我努力让它在 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()
于 2008-10-22T09:18:49.613 回答
2

我正在使用nLiteBartPEmkisofs.exe的安装套件,从中我还学习了构建可启动 cd 所需的参数。

于 2008-12-06T13:27:19.233 回答