是否有一种相对简单的方法可以在 C# 或 PowerShell 中完成 CD 或 DVD?

2023-11-24

首先,对术语进行一些澄清。经过最终确定,我的意思并不是要结束会议;而是要结束会议。我的意思是,将导出内容写入 CD 或 DVD 时,信息将无法再通过通常的方式(Roxio、Nero、Windows 资源管理器等)添加到其中。

我对此做了相当多的研究。有一些开源程序,例如红外记录仪我们可以从中汲取一些灵感,但它们似乎都涉及使用 IMAPI 的相当复杂的 C++ 代码,这似乎是一种非常低级的做事方式。我们团队中的开发人员都没有 C++ 或 IMAPI 专业知识来支持这样的代码库。

互联网上最有前途的资源似乎是this one,但它似乎不包含 Finalize 函数。这是“写入图像”的代码:

public void WriteImage(BurnVerificationLevel verification, bool finalize, bool eject)
{
    if (!_recorderLoaded)
        throw new InvalidOperationException("LoadMedia must be called first.");

    MsftDiscRecorder2 recorder = null;
    MsftDiscFormat2Data discFormatData = null;

    try
    {
        recorder = new MsftDiscRecorder2();
        recorder.InitializeDiscRecorder(_recorders.SelectedItem.InternalUniqueId);

        discFormatData = new MsftDiscFormat2Data
        {
            Recorder = recorder,
            ClientName = ClientName,
            ForceMediaToBeClosed = finalize
        };

        //
        // Set the verification level
        //
        var burnVerification = (IBurnVerification)discFormatData;
        burnVerification.BurnVerificationLevel = IMAPI_BURN_VERIFICATION_LEVEL.IMAPI_BURN_VERIFICATION_NONE;

        //
        // Check if media is blank, (for RW media)
        //
        object[] multisessionInterfaces = null;
        if (!discFormatData.MediaHeuristicallyBlank)
            multisessionInterfaces = discFormatData.MultisessionInterfaces;

        //
        // Create the file system
        //
        IStream fileSystem;
        _CreateImage(recorder, multisessionInterfaces, out fileSystem);

        discFormatData.Update += _discFormatWrite_Update;

        //
        // Write the data
        //
        try
        {
            discFormatData.Write(fileSystem);
        }
        finally
        {
            if (fileSystem != null) Marshal.FinalReleaseComObject(fileSystem);                    
        }

        discFormatData.Update -= _discFormatWrite_Update;

        if (eject) recorder.EjectMedia();
    }
    finally
    {
        _isWriting = false;
        if (discFormatData != null) Marshal.ReleaseComObject(discFormatData);
        if (recorder != null) Marshal.ReleaseComObject(recorder);                
    }
}

代码的关键部分似乎是这样的:

discFormatData = new MsftDiscFormat2Data
{
    Recorder = recorder,
    ClientName = ClientName,
    ForceMediaToBeClosed = finalize // <-- Here
};

但这不是一个终结函数;而是一个终结函数。它是一个将实际数据刻录到磁盘上的函数。您是否必须实际创建一个新会话才能在现有磁盘上执行终结?


The ForceMediaToBeClosed的财产IDiscFormat2Data 控制 IMAPI 是否终结光盘之后next write:

设置为 VARIANT_TRUE 将光盘标记为已关闭,以在下一个写入会话结束时禁止其他写入。

Image Mastering API 没有提供专门用于完成光盘的抽象,因此我们需要执行写入操作。如果我们打开,API 将在初始刻录期间最终确定空白光盘ForceMediaToBeClosed与主要图像作家。对于现有的多会话光盘,我们需要附加另一个会话。

这是一个简单的 PowerShell 示例,我们可以尝试一下,这样我们就不需要构建项目。 C# 中的概念类似:

$drives = New-Object -ComObject 'IMAPI2.MsftDiscMaster2'
$recorder = New-Object -ComObject 'IMAPI2.MsftDiscRecorder2'
$recorder.InitializeDiscRecorder($drives[0])  # Choose a drive here

$disc = New-Object -ComObject 'IMAPI2.MsftDiscFormat2Data'
$disc.ClientName = 'PowerShell Recorder'
$disc.Recorder = $recorder
$disc.ForceMediaToBeClosed = $true  # Finalize the next session

$image = New-Object -ComObject 'IMAPI2FS.MsftFileSystemImage'

if (!$disc.IsCurrentMediaSupported($recorder)) {
    throw 'Disc is not writeable.'
} elseif ($disc.MediaHeuristicallyBlank) {
    $image.ChooseImageDefaults($recorder)
} else {
    $image.MultisessionInterfaces = $disc.MultisessionInterfaces
    $image.ImportFileSystem() > $null
}

这将设置一些我们将在下面用来刻录光盘的样板。我们需要添加错误处理和功能检测以供实际使用,但作为演示它效果很好。如果我们将此代码粘贴或点源到 PowerShell 会话中,我们就可以交互地使用 COM 对象。

此时,如果我们检查空白或打开光盘的状态,我们应该看到值2, 4, or 6对应于“空白”或“可附加”位掩码(6对于两者)枚举IMAPI_FORMAT2_DATA_MEDIA_STATE.

PS> $disc.CurrentMediaStatus  # 4 for an open, multi-session disc 

然后,我们可以添加一些文件。如果我们只想关闭多会话光盘,则无需向映像添加任何内容。 API 使用空数据轨道记录会话的导入和导出。

PS> $image.Root.AddTree('path\to\root\folder', $false)

最后,我们将更改刻录到光盘上。因为我们设定$disc.ForceMediaToBeClosed to $true,此操作完成光盘,并且不允许进一步的写入操作:

PS> $disc.Write($image.CreateResultImage().ImageStream)

如果我们现在检查光盘状态,应该表明该光盘不可写:

PS> $disc.CurrentMediaStatus  # 16384 or 40960

对于单会话光盘,我们应该看到16384 (0x4000,“最终确定”)。我的系统报告40960包含位的取消赎回权的多区段光盘0x2000(“写保护”)和0x8000(“不受支持的媒体”)。我们可能需要弹出或重新启动某些硬件才能在刻录后看到准确的值。

Remarks:

  • 一般来说,多会话光盘上的每个会话都以导入开始并以导出结束。当我们最终完成光盘时,最后一个会话的导入将永久关闭介质以进行进一步写入。这就是为什么我们需要向未封闭的光盘附加一个额外的会话,即使我们没有更多的数据要添加。

  • 如果可用空间低于 2%,IMAPI 将自动终结光盘。

  • InfraRecorder(问题中提到的工具)不使用 IMAPI。该应用程序提供了一个前端cdrtools直接控制设备IO。如果我们只需要完成未封闭的光盘,我们可能需要使用CD记录此软件包中包含 CLI 程序,以避免维护额外的代码库:

    PS> cdrecord -scanbus          # Show <drive> IDs to choose from
    PS> cdrecord -fix dev=<drive>  # Close an open session
    

    作为一个简单的起点,我们可以通过以下方式完成多会话光盘:

    PS> $session = cdrecord -msinfo dev=<drive>
    PS> mkisofs -rJ -C $session -M <drive> 'path\to\root' | cdrecord dev=<drive> -
    

    这实现了与使用 IMAPI 的 PowerShell 脚本相同的结果:我们导入最后一个会话,创建映像,然后刻录一个新会话来完成光盘。通过省略-multicdrecord 的参数,该命令不会以允许多会话光盘继续的方式写入导入。

    虽然我们通常在类 Unix 系统上看到这个工具集,版本可用对于 Windows。

  • 对于更高级的应用程序,我们可以使用较低级别的实现IDiscRecorderEx查询并向录音设备发送命令。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否有一种相对简单的方法可以在 C# 或 PowerShell 中完成 CD 或 DVD? 的相关文章

  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 在 PowerShell 中从文件名中删除路径和扩展名

    我有一系列字符串 它们是文件的完整路径 我想只保存文件名 不保存文件扩展名和主路径 所以由此可知 c temp myfile txt to myfile 我实际上并没有遍历目录 在这种情况下类似于 PowerShell 的目录basenam
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐

  • jQuery 真正支持哪些 CSS3 选择器,例如:第n个最后一个孩子()?

    根据http api jquery com category selectors 我们可以在 jQuery 中使用大量的 CSS 选择器 但是例如 nth last child 那里没有提到 然而 当我测试以下内容时 使用来自 Google
  • 生成固定长度整数分区的所有唯一排列的算法?

    我正在寻找一种生成整数固定长度分区的所有排列的算法 顺序并不重要 例如 对于 n 4 且长度 L 3 0 2 2 2 0 2 2 2 0 2 1 1 1 2 1 1 1 2 0 1 3 0 3 1 3 0 1 3 1 0 1 3 0 1 0
  • 单个 Git 存储库中的公共和私有代码

    我参与的一个研究小组目前将所有代码托管在一个私有 SVN 存储库中 我们想开放我们的代码并将大部分代码移至 Github 上 问题是 有些代码是敏感的 不应该开放 但我们仍然希望它处于版本控制之下 目前 我们在 Github 上有开放代码
  • WPF:PropertyChangedCallback 仅触发一次

    我有一个用户控件 它公开一个名为 VisibileItems 的 DependencyProperty 每次更新该属性时 我都需要触发另一个事件 为了实现这一点 我添加了带有 PropertyChangedCallback 事件的 Fram
  • 限制对 Elastic Beanstalk 的 HTTP 访问

    是否可以将对 Elastic Beanstalk 应用程序的 HTTP 访问限制为仅某些 IP 地址 我已尝试向环境的安全组添加规 则 但这些规则似乎没有任何效果 这是因为所有 HTTP 流量都是通过弹性负载均衡器路由的吗 isn t安全组
  • C# 继承和默认构造函数

    假设有一个基类A和一个班级B源自A 那么我们知道类的构造函数A永远不会被类继承B 然而 当一个新对象B创建 然后 类的默认构造函数A在类的默认 自定义构造函数之前调用B被调用 也许这样做的目的是类的字段A需要初始化为默认值 现在 假设该类A
  • 如何在 Kubernetes Pod 之间共享存储?

    我正在评估 Kubernetes 作为我们新应用程序的平台 现在看来 一切都非常令人兴奋 但是 我遇到了一个问题 我在 GCE 上托管集群 并且需要某种机制在两个 pod 持续集成服务器和我的应用程序服务器 之间共享存储 使用 kubern
  • 起订量索引属性并在返回/回调中使用索引值

    我想要起订量一个具有索引的属性 并且我希望能够在回调中使用索引值 就像您可以在回调中使用起订量方法的方法参数一样 可能最容易用一个例子来演示 public interface IToMoq int Add int x int y int t
  • Android + Proguard + Apache POI

    有人能够在混淆后让 Apache POI 库正常工作 我查阅了很多资料 尝试了不同的方法 但仍然得到错误 a a b a Provider com bea xml stream EventFactory not found org apac
  • 使用 Sed 替换包含字符串的整行

    我有一个文本文件 其中有一个特定的行 例如 sometext sometext sometext TEXT TO BE REPLACED sometext sometext sometext 我需要将上面的整行替换为 This line i
  • 智能感知中的自定义代码片段

    我已经开始将一些常用的代码块导出到自定义片段 有没有办法让这些显示在 IntelliSense 中 而不必使用上下文菜单或代码片段管理器中的代码片段浏览器 起初 我以为这与 ReSharper 有关 但当我禁用 ReSharper Inte
  • Android webkit 浏览器中的宽度不正确

    我注意到 Android 默认浏览器上有一个问题 100 宽度实际上可能会超出屏幕边缘 这是一个最小的测试用例 div class separator width 100 style border 2px padding 2px nbsp
  • 如何编写一个返回仅存在于类中的类型的成员函数?

    我实际上正在用 C 实现一个双向链表 这是某种 MWE namespace mynamespace template
  • 哪里有可靠的注册表项来查找 Excel 2007 的安装位置?

    哪里有可靠的注册表项来查找 Excel 2007 的安装位置 怎么样 HKEY LOCAL MACHINE SOFTWARE Microsoft Office X 0 Common InstallRoot 其中包含一个名为 Path 的键
  • django-rest-framework:如何序列化已包含 JSON 的字段?

    我对 django rest framework 很陌生 所以需要一些帮助 我有一个带有 TextField 的对象 该对象是包含 JSON 的字符串 我正在使用 django rest framework 将整个对象序列化为 JSON 然
  • 为什么禁止内联脚本(内容安全策略)?

    我想知道规范中的引用 https dvcs w3 org hg content security policy raw file tip csp specification dev html 为了获得最大的好处 作者需要将所有内联脚本和样式
  • Keras:制作神经网络来查找数字的模数

    我是一位经验丰富的 Python 开发人员 但在机器学习方面完全是新手 这是我第一次尝试使用 Keras 你能告诉我我做错了什么吗 我正在尝试制作一个神经网络 它接受二进制形式的数字 并在除以 7 时输出其模数 我的目标是执行一个非常简单的
  • HTTP重定向代码之间的区别

    我不清楚各种 HTTP 3XX 重定向代码之间的差异 是的 我已经阅读了规范 但标准与实际实践之间似乎存在一些差异 The 301重定向代码似乎足够清楚 这意味着资源已永久移动到另一个 URI 并且将来的请求应使用该 URI And the
  • IIS HTTP 到 HTTPS 相对重定向

    我最近为我的网站获得了 SSL 证书 并希望将所有流量重定向到 HTTPS 我已经拥有了一切要去的地方https mydomain com但如果有人进来http mydomain com anotherpage它会删除其他页面 只将用户带到
  • 是否有一种相对简单的方法可以在 C# 或 PowerShell 中完成 CD 或 DVD?

    首先 对术语进行一些澄清 经过最终确定 我的意思并不是要结束会议 而是要结束会议 我的意思是 将导出内容写入 CD 或 DVD 时 信息将无法再通过通常的方式 Roxio Nero Windows 资源管理器等 添加到其中 我对此做了相当多