VBAでCD,DVDを焼くための参照設定 と光学ドライブを開くためのコード

#Excel2013以降は参照設定を呼び出しても直接現れない場合がある
その時は、DLLがどこにあるか指定しなければならない

### Dllの場所
C:\Windows\System32\imapi2.dll
C:\Windows\System32\imapi2fs.dll

64/32とも同じようである。

###参照設定欄

次のようにみえる。
Microsoft IMAPI2 Base Functionality
Microsoft IMAPI2 File System Image Creator


#IMAPのマニュアル 日本語はない

[Image Mastering API]( https://msdn.microsoft.com/en-us/library/aa366450(VS.85).aspx)
https://docs.microsoft.com/ja-jp/windows/win32/imapi/portal?redirectedfrom=MSDN

#サンプルコード
[Burning a Disc Image]( https://msdn.microsoft.com/ja-jp/library/windows/desktop/aa364817(v=vs.85).aspx)
>Mastering (burning a disc) using IMAPI consists of the following steps:
<ol>
<li>Construct a file system image that contains the directories and files to write disc.
<li>Set up a disc recorder to communicate with the optical device.
<li>Create a data writer and burn the image to disc.
</OL>
For an example that burns a disc image, see VBScript example.

IMAPIを使用したマスタリング（ディスクの書き込み）は、次の手順で構成されます。
<ol>
<li>ディスクに書き込むディレクトリとファイルを含むファイルシステムイメージを作成します。
<li>光学装置と通信するようにディスクレコーダーをセットアップします。
<li>データライターを作成し、イメージをディスクに書き込みます。
</OL>
ディスクイメージを書き込む例については、VBScriptの例を参照してください。

>##Construct a burn image

> A burn image is a data stream that is ready to be written to optical media. The burn image for ISO9660, Joliet and UDF formats consists of a file system of individual files and directories. The CFileSystemImage object is the file system object that holds the files and directories to place on the optical media. The IFileSystemImage interface provides access to the file system object and settings.

> After creating the file system object, call the IFileSystemImage::CreateFileItem and IFileSystemImage::CreateDirectoryItem methods to create the file and directory objects, respectively. The file and directory objects can be used to provide specific details about the file and directory. The event handler methods available for IFileSystemImage can identify the current file being added to the file system image, the number of sectors already copied, and the total number of sectors to be copied.

> Optionally, a boot image can be attached to the file system using the IFileSystemImage::put_BootImageOptions property. For an example, see Adding a Boot Image.

> Finally, call IFileSystemImage::CreateResultImage to create a data stream and provides access through IFileSystemImageResult. The new data stream can then be provided directly to the IDiscFormat2Data::Write method or be saved to a file for later use.

>##書き込みイメージ(Burn Image,バーニングイメージ、焼線、焼き込みイメージ）を作成する
書き込みイメージは(Burn Image,バーニングイメージ、焼線、焼き込みイメージ）、光メディアに書き込むために予め作成されるデータのストリームです。 ISO9660、Joliet、UDF形式の書き込みイメージは、個々のファイルとディレクトリのファイルシステムで構成されています。CFileSystemImageのオブジェクトは、光メディア上の場所にファイルやディレクトリを保持するファイルシステムオブジェクトです。IFileSystemImageのインタフェースは、ファイル・システム・オブジェクトおよび設定へのアクセスを提供します。

> ファイルシステムオブジェクトを作成したら、`IFileSystemImage::CreateFileItem`メソッドと`IFileSystemImage::CreateDirectoryItem`メソッドを呼び出して、それぞれファイルオブジェクトとディレクトリオブジェクトを作成します。（つまりファイルとフォルダの階層構造を作る）ファイルおよびディレクトリオブジェクトを使用して、ファイルおよびディレクトリに関する特定の詳細を提供できます。IFileSystemImageで使用できるイベントハンドラーメソッドは、ファイルシステムイメージに追加されている現在のファイル、既にコピーされているセクターの数、およびコピーされるセクターの総数を識別できます。

> オプションで、`IFileSystemImage :: put_BootImageOptions`プロパティを使用して、ブートイメージをファイルシステムにアタッチできます。例については、ブートイメージの追加を参照してください。


> 最後に、`IFileSystemImage::CreateResultImage`を呼び出してデータストリームを作成し、IFileSystemImageResultを介したアクセスを提供します。次に、新しいデータストリームを`IDiscFormat2Data::Write`に直接提供できます。メソッドにか、後で使用するためにファイルに保存できます。

>##Set up a disc recorder

> The MsftDiscMaster2 object provides an enumeration of the optical devices on the system. The IDiscMaster2 interface provides access to the resultant device enumeration. Traverse the enumerations to locate an appropriate recording device. The MsftDiscMaster2 object also provides event notifications when optical devices are added to or deleted from a computer.

> After finding an optical recorder and retrieving its ID, create an MsftDiscRecorder2 object and initialize the recorder using the device ID. The IDiscRecorder2 interface provides access to the recorder object as well as some basic device information such as vendor ID, product ID, product revision, and methods to eject the media and close the tray.


>##ディスクレコーダーをセットアップする

> MsftDiscMaster2のオブジェクトは、システム上の光学デバイスの列挙を提供します。IDiscMaster2のインターフェースは、得られたデバイスの列挙へのアクセスを提供します。列挙をトラバースして、適切な記録デバイスを見つけます。MsftDiscMaster2目的は、光学デバイスが追加またはコンピュータから削除されたイベント通知を提供します。

> 光学レコーダーを見つけてそのIDを取得したら、MsftDiscRecorder2オブジェクトを作成し、デバイスIDを使用してレコーダーを初期化します。IDiscRecorder2インターフェースは、レコーダオブジェクトへのアクセスならびにベンダID、プロダクトID、製品改定、およびメディアを取り出し、トレイを閉じる方法として、いくつかの基本的なデバイス情報を提供します。

>##Create a data writer and write the burn image

> The MsftDiscFormat2Data object provides the writing method, the properties about the write function and media-specific properties. The IDiscFormat2Data interface provides access to the MsftDiscFormat2Data object.

> The disc recorder links to the format writer using the IDiscFormat2Data::put_Recorder property. After the recorder is bound to the format writer, you can perform queries regarding the media and update write-specific properties before writing the result image to disc using the IDiscFormat2Data::Write method.

> Other format writing interfaces provided by IMAPI work similarly; additional format writing interfaces include:
<UL>
<li>IDiscFormat2Erase erases rewritable optical media.
<li>IDiscFormat2RawCD writes a raw image to optical media.
<li>IDiscFormat2TrackAtOnce writes audio tracks to optical media.
</UL>

>###Note
It is possible for a power state transition to take place during a burn operation (i.e. user log-off or system suspend) which leads to the interruption of the burn process and possible data loss. For programming considerations, see Preventing Logoff or Suspend During a Burn.



>##データライターを作成し、書き込みイメージを書き込む
> MsftDiscFormat2Dataのオブジェクトは、書き込み方法は、書き込み機能とメディア固有のプロパティについてのプロパティを提供します。IDiscFormat2Dataのインターフェースは、へのアクセスを提供MsftDiscFormat2Dataのオブジェクトを。

> ディスクレコーダーは、IDiscFormat2Data :: put_Recorderプロパティを使用してフォーマットライターにリンクします。レコーダーがフォーマットライターにバインドされたら、IDiscFormat2Data :: Writeを使用して結果イメージをディスクに書き込む前に、メディアに関するクエリを実行し、書き込み固有のプロパティを更新できます。メソッド。

> IMAPIによって提供される他のフォーマット書き込みインターフェースも同様に機能します。追加のフォーマット書き込みインターフェースは次のとおりです。
<ul>
<li>DiscFormat2Eraseは、書き換え可能な光学メディアを消去します。
<li>IDiscFormat2RawCDは、未加工のイメージを光学メディアに書き込みます。
<li>IDiscFormat2TrackAtOnceは、オーディオトラックを光学メディアに書き込みます。
</ul>
###注意
書き込み操作（つまり、ユーザーのログオフまたはシステムの一時停止）中に電源状態の遷移が発生し、書き込みプロセスが中断され、データが失われる可能性があります。プログラミングに関する考慮事項については、「書き込みの際のログオフまたは中断の防止」を参照してください。

>##VBScriptの例

>このスクリプト例は、IMAPIオブジェクトを使用して光学メディアを書き込む方法を示しています。具体的には、空のディスクにディレクトリを書き込みます。コードにはエラーチェックが含まれておらず、次のことを前提としています。
<UL>
<li>互換性のあるディスクデバイスがシステムにインストールされています。
<li>ディスクデバイスは、システムの2番目のドライブです。
<li>互換性のあるディスクがディスクデバイスに挿入されています。
<li>ディスクが空です。
<li>ディスクに書き込むファイルは「~~g：\ burndir~~E:\Burn」にあります。
</ul>
エラーチェック、デバイスとメディアの互換性、イベント通知、ディスクの空き容量の計算などの追加機能をこのスクリプトに追加できます。

>

```vb
' This script burns data files to disc in a single session < 1回限り書き込み（といいつつ追記できる場合もある）
' using files from a single directory tree.
 
' Copyright (C) Microsoft Corp. 2006 ’このように前提が00年代中期とかなり古い。

Option Explicit

' *** CD/DVD disc file system types
Const FsiFileSystemISO9660 = 1
Const FsiFileSystemJoliet  = 2
Const FsiFileSystemUDF102  = 4

WScript.Quit(Main) ’Mainサブプロシージャではなく、Mainユーザー定義関数を起動して終了する

Function Main
    Dim Index                ' Index to recording drive.
    Dim Recorder             ' Recorder object
    Dim Path                 ' Directory of files to burn
    Dim Stream               ' Data stream for burning device
    
    Index = 1                ' Second drive on the system
    Path = "E:\Burn"         ' Files to transfer to disc 現在はG自体が光学ドライブのケースが多い。ハードディスクまたは保護解除されたドライブ、あるいはスペースにデータを置かなければ焼くこと（書き込むこと）ができない。Gでは光学ドライブのように読めてしまうため、誤解を防ぐためにEドライブとした。

    ' Create a DiscMaster2 object to connect to optical drives.
    Dim g_DiscMaster
    Set g_DiscMaster = WScript.CreateObject("IMAPI2.MsftDiscMaster2")

    ' Create a DiscRecorder object for the specified burning device.
    Dim uniqueId
    set recorder = WScript.CreateObject("IMAPI2.MsftDiscRecorder2")
    uniqueId = g_DiscMaster.Item(index) '<通常はドライブレター順に0,1となる。本体Fと外付けGという光学ドライブがあると、本体が0、外付けが1となる。ここがIndexについてなにも処理していないのはUniqueIdが0の本体の光学ドライブに焼く前提のため。
    recorder.InitializeDiscRecorder( uniqueId )
'上記2行は、通常は次のように記述する
    'uniqueId = g_DiscMaster.Item(0)
    'recorder.InitializeDiscRecorder(uniqueId)


    ' Create an image stream for a specified directory.
    Dim FSI                  ' Disc file system
    Dim Dir                  ' Root directory of the disc file system
    Dim dataWriter    
        
    ' Create a new file system image and retrieve root directory
    Set FSI = CreateObject("IMAPI2FS.MsftFileSystemImage")
    Set Dir = FSI.Root

    'Create the new disc format and set the recorder
    Set dataWriter = CreateObject ("IMAPI2.MsftDiscFormat2Data")
    dataWriter.recorder = Recorder
    dataWriter.ClientName = "IMAPIv2 TEST"

    FSI.ChooseImageDefaults(recorder)
        
    ' Add the directory and its contents to the file system 
    Dir.AddTree Path, false
        
    ' Create an image from the file system
    Dim result
    Set result = FSI.CreateResultImage()
    Stream = result.ImageStream 'ここでデータを焼くための一本のデータの糸、データの流れ、ストリームにする。
    
    ' Write stream to disc using the specified recorder.
    WScript.Echo "Writing content to disc.../光学ドライブのCD/DVDディスクにデータを焼いています。"
    dataWriter.write(Stream) 'これが実際に焼くことを命令しているコード

    WScript.Echo "----- Finished writing content -----/終了"
    Main = 0
End Function
```

ちなみにこのサンプルはDVD-R、DVD-RWもそのまま焼ける。ただし、CDを焼くためのデータが残るのが欠点。



https://ja.wikipedia.org/wiki/Image_Mastering_API
#トレイを開くことはVBA VBSでも可能

[Eject/Close CD/DVD drive using PowerShell]( https://gallery.technet.microsoft.com/scriptcenter/EjectClose-CDDVD-drive-56d39361)

これをVBA/VBSに置き換えると以下のとおりである。なお、光学ドライブは本体についているものから0番としてカウントする。外付けを1台つけると1番になる。このコードは、何番が該当するのか確かめるためにも使える。サンプルは本体の光学ドライブを0番として、本体の光学ドライブにEjectMedia命令をかけて、ディスクを取り出すということになるコードである。
従来はWindows Media Playerを呼び出すコードしかなかったが、現在はこれでオープンはできる。ただ今は光学ドライブ自体が手動でしか閉まらないものが多く、閉じる方は難しい。
VBA版は上記の参照設定をしてから起動しすること。

```vb:OpenCdTray

Sub OpenCdTray()
Dim objDiscMaster As IMAPI2.MsftDiscMaster2: Set objDiscMaster = New IMAPI2.MsftDiscMaster2
Dim objRecorder As IMAPI2.MsftDiscRecorder2
Set objRecorder = New IMAPI2.MsftDiscRecorder2
objRecorder.InitializeDiscRecorder (objDiscMaster.Item(0))
objRecorder.EjectMedia
End Sub
```

##VBScript版のEjectTray

```vb:OpenCdTray.vbs
Dim objDiscMaster:set objDiscMaster  =CreateObject("IMAPI2.MsftDiscMaster2")
Dim objRecorder : Set objRecorder = CreateObject("IMAPI2.MsftDiscRecorder2")
objRecorder.InitializeDiscRecorder (objDiscMaster.Item(0))
objRecorder.EjectMedia
```


##Preventing Logoff or Suspend During a Burn
###編注
以前はCDを書き込むのは最大4倍速（CD-RWは現在でも最大2倍速）で焼き込む前に電源が自動的にサスペンドに入ったり、また、バッテリーで駆動している場合にシャットダウンする可能性があった。
データが1本の線、ストリームとなっているため、電源が切れれば糸が切れてしまい、読めなくなる。またディスクの焼き方に不良セクタが生じるため、途中で電源が切れる、電源がバッテリーで安定しない場合、、光学ディスクの焼き込みはほぼ失敗すると考えておいて差し支えない。
もちろん現在でもバッテリー駆動では不安があるため、シャットダウンを回避するより、最初からバッテリーでは焼かないようにしなければならない。また実際上、バッテリーで5分でサスペンドのような機能を使っている、セキュリティの関係で数分で電源が切れる、数分でサスペンドする、ということではない限り、通常は焼けてしまうこと、VBSではこの関数を呼び出すのが困難なことから、実際はほとんど考慮しなくて良い。

https://docs.microsoft.com/ja-jp/windows/win32/imapi/preventing-logoff-or-suspend-during-a-burn
    2018/05/31
> If proper precautions are not made within an application, it is possible for a user to log off during a burn operation. This leads to the interruption of the burn process, which can result in lost data and possibly render the disc unusable.

> To avoid this problem, the application should process the WM_QUERYENDSESSION message which is delivered prior to log off. If the application receives this message while performing a burn operation, return FALSE to cancel the logoff procedure. If the application allows the user to decide whether to continue logging off, a warning should be provided indicating that user will lose data.

> Power transitions during the burn process can also create potential problems in the success of a burn activity. Preventing these complications during the burn process requires an application to be aware of when power transitions are about to take place. This is accomplished by by enabling the application to process the WM_POWERBROADCAST message. Applications developed for Windows XP or Windows Server 2003 can return BROADCAST_QUERY_DENY in response to PBT_APMQUERYSUSPEND, preventing Suspend during the burn process.

> Due to changes in the Power Management Model for Windows Vista and Windows Server 2008, the PBT_APMQUERYSUSPEND event is no longer delivered to applications. Instead the PBT_APMSUSPEND event is delivered, providing two seconds for an application to prepare for the transition.

> As a result of these changes, it is recommended that applications call the SetThreadExecutionState function to prevent a system idle time-out which ordinarily results in the transition to Suspend. It is important to remember that calling this function with the appropriate flags set will only prevent system idle, not an in-progress Suspend.

###書き込み中のログオフまたは一時停止の防止
2018/05/31
 アプリケーション内で適切な予防措置が講じられていない場合、ユーザーは書き込み操作中にログオフすることができます。これにより、書き込み処理が中断され、データが失われ、ディスクが使用できなくなる可能性があります。

 この問題を回避するには、ログオフする前に配信されるWM_QUERYENDSESSIONメッセージをアプリケーションで処理する必要があります。書き込み操作の実行中にアプリケーションがこのメッセージを受け取った場合は、FALSEを返してログオフ手順をキャンセルしてください。アプリケーションでユーザーがログオフを続行するかどうかを決定できる場合は、ユーザーがデータを失うことを示す警告を提供する必要があります。

 書き込みプロセス中の電力の移行は、書き込みアクティビティの成功に潜在的な問題を引き起こす可能性もあります。書き込みプロセス中にこれらの複雑な問題を防止するには、アプリケーションが電源の移行が発生する時期を認識する必要があります。これは、アプリケーションがWM_POWERBROADCASTメッセージを処理できるようにすることによって達成されます。 Windows XPまたはWindows Server 2003用に開発されたアプリケーションは、PBT_APMQUERYSUSPENDへの応答としてBROADCAST_QUERY_DENYを返すことができ、書き込みプロセス中の中断を防ぎます。

 Windows VistaおよびWindows Server 2008の電源管理モデルの変更により、PBT_APMQUERYSUSPENDイベントはアプリケーションに配信されなくなりました。代わりに、PBT_APMSUSPENDイベントが配信され、アプリケーションが移行の準備をするのに2秒かかります。

 これらの変更の結果として、アプリケーションがSetThreadExecutionState関数を呼び出して、通常はサスペンドに移行するシステムアイドルタイムアウトを防ぐことをお勧めします。適切なフラグを設定してこの関数を呼び出すと、システムのアイドル状態のみが防止され、進行中のサスペンドは防止されないことに注意してください。