- PR -

ASP.NETで動作ディレクトリを変えるとEXCELが終了しない

投稿者投稿内容
会議室デビュー日: 2003/12/01
投稿数: 8
投稿日時: 2003-12-01 11:26
初めまして、今までROMってましたが、調べても判らなくなってしまいましたので、
質問させて頂きます。
こちらの「EXCELが終了しない」系のログを参考にして無事エクセルのプロセスを殺すことが出来るようになったのですが、
別のディレクトリでどうやってもプロセスが残ってしまい、試しに成功した処理を呼んでみても、
何故かプロセスが残ってしまうようになり、
残ったプロセスが増えてしまいました。

SaveAsを呼ばない場合はプロセスは消えてくれるのですが、
SaveAsでファイルは正しく生成されているようです。

環境は、
 IIS5.1 + ASP.NET(VB.NET)
ディレクトリ構成が、
wwwroot直下のディレクトリをアプリケーション登録
 アプリケーションディレクトリ直下に機能別で複数のディレクトリ
となっており、
メンテ機能のディレクトリから、共通関数のディレクトリに在るdllを参照してエクセル作成が成功していました。


[ メッセージ編集済み 編集者: 煉 編集日時 2003-12-01 11:34 ]
会議室デビュー日: 2003/12/01
投稿数: 8
投稿日時: 2003-12-01 11:31
ソースは

Dim xlsApp As New Excel.Application()
Dim xlsBooks As Excel.Workbooks
Dim xlsBook As Excel.Workbook
Dim xlsSht As Excel.Worksheet
Dim xlsNewSheetCount As Integer

xlsBooks = xlsApp.Workbooks

'' Excelの設定変更
xlsApp.IgnoreRemoteRequests = True
xlsApp.ScreenUpdating = False
xlsApp.DisplayAlerts = False
xlsApp.Visible = False
xlsNewSheetCount = xlsApp.SheetsInNewWorkbook
xlsApp.SheetsInNewWorkbook = 1

xlsBook = xlsBooks.Add()

xlsSht = xlsBook.ActiveSheet
xlsSht.Cells.NumberFormatLocal = "@"

-- 現在途中の処理はコメントアウトしています --

xlsBook.SaveAs(FilePath)
xlsBook.Close()
xlsBook = Nothing

'' Excelの設定を戻して終了
xlsApp.IgnoreRemoteRequests = False
xlsApp.ScreenUpdating = True
xlsApp.DisplayAlerts = True
xlsApp.SheetsInNewWorkbook = xlsNewSheetCount
xlsApp.Application.Quit()
xlsApp = Nothing

GC.Collect(2)

上記の様になっており、
この関数の呼び出し元でも直後にガベージコレクトを発動しています。
ご協力お願い致します。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-12-01 13:54
引用:

煉さんの書き込み (2003-12-01 11:26) より:

こちらの「EXCELが終了しない」系のログを参考にして無事エクセルのプロセスを殺すことが出来るようになったのですが、別のディレクトリでどうやってもプロセスが残ってしまい、試しに成功した処理を呼んでみても、何故かプロセスが残ってしまうようになり、
残ったプロセスが増えてしまいました。



http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=3343&forum=7
これのNothingButXMLInfoSetさんの、入っていないようですけど、入れてみました?
会議室デビュー日: 2003/12/01
投稿数: 8
投稿日時: 2003-12-01 14:21
Jitta様、お返事ありがとうございます

参照カウントを減らすSystem.Runtime.InteropServices.Marshal.ReleaseComObjectだと思いますが、
既に入れてみて駄目だったのですが、
もう一度入れてみましたが、やはり変化ありませんでした
コード:
        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsSht)
        xlsBook.SaveAs(FilePath)
        xlsBook.Close()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsBook)
        xlsBook = Nothing

        '' Excelの設定を戻して終了
        xlsApp.IgnoreRemoteRequests = False
        xlsApp.ScreenUpdating = True
        xlsApp.DisplayAlerts = True
        xlsApp.SheetsInNewWorkbook = xlsNewSheetCount
        xlsApp.Application.Quit()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsApp)
        xlsApp = Nothing

        GC.Collect(2)


タスクマネージャーで見ていると、上記の処理を行っている関数を抜けた後も処理が走っているようでしたので、
試しに呼び出し元で
コード:
        '' エクセル作成
        intRet = newCreateXlsImg()     '' 今回問題の関数です
        System.Threading.Thread.Sleep(5000)
        GC.Collect(2)


と、5秒待たせて見たのですが、やはり無理でした。
成功したディレクトリとは異なるディレクトリなので、
ソースではなく環境の問題なのでしょうか??
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-12-01 14:39
引用:

煉さんの書き込み (2003-12-01 14:21) より:

成功したディレクトリとは異なるディレクトリなので、
ソースではなく環境の問題なのでしょうか??


これ、どういう意味でしょうか。ASP.NETのプロジェクトでやるとOKだけれども、そのプロジェクトを共通関数にして(その辺だけ抜き出してDLLプロジェクトにして)、他のASP.NETアプリケーションのプロジェクトから実行するとNGだった、ということでしょうか。

 私の方でも、そういうことをやっているので、関係はないと思います。ただし、エクセルを呼び出したインスタンスは破棄してください。それが残っていると、参照が残っていると勘違いされるようです。

Sub RunExcel
GC.Collect
Dim exop as new ExcelOperation
exop.run
exop = nothing
GC.Collect
end sub

Class ExcelOperation
public sub run
エクセル操作は全てこのメソッド内で完結する
end sub
End Class

こんな感じ。RunExcelがnull参照になることでエクセルを操作したオブジェクトが全て、必ず解放対象になります。

 また、ガベージコレクタのコールは、エクセル呼び出しの直前にも行っておくのが、より効果的かと思います。
会議室デビュー日: 2003/12/01
投稿数: 8
投稿日時: 2003-12-01 15:02
引用:

成功したディレクトリとは異なるディレクトリなので、
ソースではなく環境の問題なのでしょうか??


上記のことですが、
Aappのアプリケーション内のAprjと、Bprjの二つのプロジェクトがあり、
両方から同じDLL(Cprj)内の共通関数を使用したのですが、
Aprjから呼ぶと問題なく動き、Bprjから呼ぶとエクセルが落ちなくなっています。
それで、環境の違いかとも思ったのですが、
先ほど試して見たら、Aprjから共通化していないエクセル処理を、
ファイル一式Bprjに移して見たら問題なく動きました。
会議室デビュー日: 2003/12/01
投稿数: 8
投稿日時: 2003-12-01 16:03
処理部分をクラス化してみましたが、
それでも駄目でした。
コード:
        '' エクセル作成
        GC.Collect(2)
        clsProc = New clsXlsProc()
        clsProc.strHuka1 = boxTitle.Attributes("ddlHFukajyoho1")
        clsProc.strHuka2 = boxTitle.Attributes("ddlHFukajyoho2")
        clsProc.strNendo = strNendo
        clsProc.strKi = strKi
        clsProc.newCreateXlsImg(System.Web.HttpContext.Current.Server.MapPath(boxTitle.Attributes("fileName")), boxTitle.Attributes("ddlHito"))
        lblSimei.Text = clsProc.strSimei
        clsProc = Nothing
        GC.Collect(2)


会議室デビュー日: 2003/12/01
投稿数: 8
投稿日時: 2003-12-01 16:43
先ほど、共通関数化していない別プロジェクトの関数をそのままコピーしてきたら何故か動きましたので、
その関数をスケルトン化して少しづつ処理を組み込んでいってます。

コード:
        Dim xlsApp As New Excel.Application()
        Dim xlsBooks As Excel.Workbooks
        Dim xlsBook As Excel.Workbook
        Dim xlsSheet As Excel.Worksheet
        Dim xlsNewSheetCount As Integer
        Dim FilePath As String

        FilePath = System.Web.HttpContext.Current.Server.MapPath(strXlsFileName & ".xls")

        xlsBooks = xlsApp.Workbooks

        '' Excelの設定変更
        xlsApp.IgnoreRemoteRequests = True
        xlsApp.ScreenUpdating = False
        xlsApp.DisplayAlerts = False
        xlsApp.Visible = False
        xlsNewSheetCount = xlsApp.SheetsInNewWorkbook
        xlsApp.SheetsInNewWorkbook = 1

        xlsBook = xlsBooks.Add()

        xlsSheet = xlsBook.ActiveSheet
        xlsSheet.Name = strXlsFileName
        xlsSheet.Cells.NumberFormatLocal = "@"

        xlsBook.SaveAs(FilePath)

        xlsBook.Close()
        xlsBook = Nothing

        '' Excelの設定を戻して終了
        xlsApp.IgnoreRemoteRequests = False
        xlsApp.ScreenUpdating = True
        xlsApp.DisplayAlerts = True
        xlsApp.SheetsInNewWorkbook = xlsNewSheetCount
        xlsApp.Application.Quit()
        xlsApp = Nothing

        GC.Collect(2)


スキルアップ/キャリアアップ(JOB@IT)