tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^6: PowerPointのオブジェクト開放ができません
投稿日: 2009/08/27(Thu) 22:04
投稿者Hongliang
解決おめでとうございます。
正直なところ PowerPoint どころか Excel も手元にないので、プロセスが終了するかどうかの確認はしてませんでした。
// 参照カウンタの確認は IE のオートメーションで代用してました。

> Dim myShapesNum As IEnumerator = myShapes.GetEnumerator()
> Dim obj3 As Object = TryCast(myShapesNum, ICustomAdapter)
> Dim obj4 As Object = obj3.GetUnderlyingObject
> MRComObject(obj3) : obj3 = Nothing
> MRComObject(obj4) : obj4 = Nothing
書くの 3 回目のような気もしますが。
myShapesNum、obj3、obj4 とありますが、
これらは全て同一にして単一の COM オブジェクトを指しています。
違いは、
obj4 : 列挙処理を実装する生の COM オブジェクト
myShapesNum : .NET で列挙処理を行うためのインターフェイス
obj3 : 生の COM オブジェクトを取得するためのインターフェイス
であり、myShapesNum 及び obj3 は生の COM オブジェクトではなく、ラップされたクラスです。
適当なクラス実装のイメージはこんな感じ。

Class ComObjectEnumerator
    Implements IEnumerator, ICustomAdapter
    Private _comObject As Object
    Public Function GetUnderlyingObject() As Object Implements ICustomAdapter
        Return _comObject
    End Function
    Public Function MoveNext() As Boolean Implements IEnumerator
        ' _comObject を使って実装する
    End Function
    ... ' 他のインターフェイスの実装は省略
End Class

myShapesNum 及び obj3 は ComObjectEnumerator のインスタンスそのもので、
obj4 が _comObject です。obj4 だけ違うインスタンスですね。
ReleaseComObject が必要なのは生の COM オブジェクトである obj4 のみであり、
純粋なマネージオブジェクトである obj3 は ReleaseComObject に渡せません。
(MRComObject メソッドでは内部に IsComObject 判定があるので問題ありませんが、
不要であることは明らかなので呼び出すべきではないと思います)

> >・mySlides が追加で 1 つ
> >増えることになります。
> については,MRComObject(mySlides) : mySlides = Nothingを2回やる必要があるのでしょうか?

ReleaseComObject メソッドは参照カウントを 1 減らしますが、
そのときまだ残っている参照カウントを返します。
MRComObject メソッドでは、Debug.WriteLine を使ってこの残りの参照カウントを出力しているので、
デバッグ時にこれで ReleaseComObject が余計に必要かどうか確認できます。
// そういう意味で、MRComObject は Function As Integer にして count を返すようにした方が良いかも。
また、MRComObject は第二引数に強制的に全ての参照を解放する引数を指定できるようなので、
問答無用でこれを呼ぶことも考えられます。
ローカル変数でメソッド外部に出すこともない変数ならそれでも特に問題ないでしょう。
あと、
MRComObject(mySlides) : mySlides = Nothing
を 2 回やったら 2 回目は必ず失敗(MRComObject 先頭で Return)しますよ。Nothing 代入済みですから。
前にも言いましたが Nothing の代入は特にローカル変数の場合意味がほぼ無いので、あまりお勧めしません。

>  また,以前Excelで同様に↓のようなコードを書いたときはExcel.EXEが残らなかったのですが,
> For Each mySheet In mySheets
> Next
> こちらについてもきちんと今回教えていただいたような書き直しておく方が無難でしょうか?

プロセスが残りそうなアウトプロセスサーバが手元にないっぽいので、私からは何とも言えません。
理屈はさんざん述べてきましたが、個々の案件によって違いがあることは考えられます。
しかし web をあさってみる限り、Excel の各コレクションオブジェクトについては
みんな For Each で処理して特に問題も起こってないみたいですね。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。