tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルCreateObjectにてShell32を使用してZIPが展開されない。
記事No8444
投稿日: 2008/12/01(Mon) 15:23
投稿者おばおば
開発環境: Microsoft Visual Studio 2005 Version 8.0.50727.762
OS: Mirosoft Windows XP Professional Version2002 ServicePack 2

はじめまして。いつも参考にさせていただいております。
VB.NETでShell32を使用してZIPを展開しようとしております。
開発中に不可解な現象に遭遇いたしました。
お分かりになる方、おられませんでしょうか。

下記コードのように、destFlderにShell32.Folderを指定すると問題なく展開できます。

' zip展開
Dim sc As Object = Nothing
Dim srcFlder As Object = Nothing
Dim items As Object = Nothing
Dim destFlder As Shell32.Folder = Nothing
Try
    sc = CreateObject("Shell.Application")
    srcFlder = sc.NameSpace(mcnsWorkPath & mcnsMenuZipName)
    items = srcFlder.items
    destFlder = sc.NameSpace(mcnsWorkPath)
    destFlder.CopyHere(items, FOF_NOCONFIRMATION + FOF_SILENT + FOF_NOCONFIRMMKDIR)
Finally
    If Not sc Is Nothing Then
        System.Runtime.InteropServices.Marshal.ReleaseComObject(sc)
        sc = Nothing
    End If
    If Not destFlder Is Nothing Then
        System.Runtime.InteropServices.Marshal.ReleaseComObject(destFlder)
        destFlder = Nothing
    End If
    If Not srcFlder Is Nothing Then
        System.Runtime.InteropServices.Marshal.ReleaseComObject(srcFlder)
        srcFlder = Nothing
    End If
    If Not items Is Nothing Then
        System.Runtime.InteropServices.Marshal.ReleaseComObject(items)
        items = Nothing
    End If
End Try

しかし、このコードでShell32.Folderの部分をObjectに置き換えると、
展開が行われず、エラーにもならずに処理が終わってしまいます。

Webを検索してみたところ、
通常はObjectで問題なく処理出来ているように見えましたので、
私の環境だけかと思い、
私のOSだけでなく他のOSでも試してみたのですが、同様の結果となりました。

Shell32.DLLは1MBもあり、配布を避けるために、
参照に追加しない方法を考えており、上記のコードにて実装しようとしております。

よろしくお願いします。

[ツリー表示へ]
タイトルRe: CreateObjectにてShell32を使用してZIPが展開されない。
記事No8445
投稿日: 2008/12/01(Mon) 17:07
投稿者魔界の仮面弁士
> sc = CreateObject("Shell.Application")
unzip32.dll や #ziplib を使った方が良いんじゃないかな…。
http://dobon.net/vb/dotnet/links/createzipfile.html


> 通常はObjectで問題なく処理出来ているように見えましたので、
細かい事情を端折って言えば、『ByRef』と『ByVal』の違いによる物です。

この場合は、CallByName を使って呼び出してください。
  CallByName(destFlder, "CopyHere", vbMethod, items, FOF_NOCONFIRMATION Or FOF_SILENT Or FOF_NOCONFIRMMKDIR)
もしくは、
  destFlder.CopyHere((items), FOF_NOCONFIRMATION Or FOF_SILENT Or FOF_NOCONFIRMMKDIR)
のように、「変数」を括弧で囲んで、「式」として渡すようにしてみてください。


> Shell32.DLLは1MBもあり、配布を避けるために、
最近のバージョンだと 8MB 近くありますけれどね。
http://support.microsoft.com/dllhelp/?dlltype=file&l=55&alpha=shell32.dll&S=1

ただし、Shell32.DLL は配布してはいけませんし、配布する必要もありません。
配布すべきは、参照設定によって自動生成される「Interop.Shell32.dll」の方ですよ。

[ツリー表示へ]
タイトルRe^2: CreateObjectにてShell32を使用してZIPが展開されない。
記事No8446
投稿日: 2008/12/01(Mon) 17:49
投稿者おばおば
魔界の仮面弁士様

ご提示いただきました、両方の方法にて実行できることを確認いたしました。
StrictOnでの遅延バインディング警告も出なくなることから、CallByNameにて実装しようと思います。

また、FOF_NOCONFIRMATIONの指定において、+と記載していたのですが、本来はOrが正しい点についても修正いただきありがとうございます。

> 配布すべきは、参照設定によって自動生成される「Interop.Shell32.dll」の方ですよ。
別物だということに気付いていませんでした。
同一と思い込んでサイズをShell32.dllにて判断していました。

複数のプロジェクトにて汎用的に使用する部品として作成しており、
今後の展開次第では、unzip32.dll や ziplibでは、ライセンスに違反する場合が出てくるのではと考え、shell32を使用することにいたしました。

よろしくお願いします。

[ツリー表示へ]
タイトルRe^3: CreateObjectにてShell32を使用してZIPが展開されない。
記事No8447
投稿日: 2008/12/01(Mon) 21:22
投稿者魔界の仮面弁士
> CallByNameにて実装しようと思います。
ただし CallByName では、「ByRef」なメソッドを呼び出せない事に注意してください。
引数の内容が変化せずに、ByVal 相当の呼び出しになってしまいますので。
(今回の件では ByVal 専用でも困らないのかも知れませんけれどね)

もしも ByRef / ByVal を指定した呼び出しを行いたいのであれば、
 ・参照設定して、厳密な型を使って呼び出すようにする。
 ・Guid 属性等を用いて、ActiveX のインターフェイス定義を自分で記述して利用。
 ・リフレクションを使って呼び出すようにする。
などの対応が必要になります。


> また、FOF_NOCONFIRMATIONの指定において、
提示されたコードでは、そもそも、FOF_NOCONFIRMATION 定数の宣言が
書かれていないので、提示されたコードを確認するのが面倒でした…。
(こういう時は、定数定義も書いておいていただけるとありがたいです)


> > 配布すべきは、参照設定によって自動生成される「Interop.Shell32.dll」の方ですよ。
> 別物だということに気付いていませんでした。
ちなみに次期バージョンである VB2010 では、参照設定した DLL 内の
型定義(のうち、使用されている部分)を EXE 内に取り込む機能があり、
こうした配布物を減らせるようになるのだとか。


> 今後の展開次第では、unzip32.dll や ziplibでは、
"ziplib" ではなく、"#ziplib" ですよ。


> ライセンスに違反する場合が出てくるのではと考え、
いっその事、展開機能を自力実装するとか…
http://books.google.co.jp/books?vid=ISBN4797324287

というのは冗談として:

"unzip32" はフリーソフトですが、商用目的なのでライセンス契約が必要となりますね。

"#ziplib" の方は GPL です。改変せずに、ライブラリとして使用する分には
商用利用も可能です。(改変する場合はソースコードの開示が必要)

あとは、DotNetZip なんてのもありますね。こちらは Microsoft Public License です。
http://www.codeplex.com/DotNetZip

その他には、J# の vjslib.dll を使う方法も有名ですね。
こちらの再配布には、"Microsoft Visual J#2.0 Redistributable Package" を使えば OK。


> shell32を使用することにいたしました。
それも一つの方法ですね。COM ベースである点と、今回のような問題に
気をつけていれれば大丈夫でしょう。LZH の解凍にも使えるかな?
http://www.vector.co.jp/magazine/spotlight/050530/sl0505301.html


.NET 標準の機能が良ければ、System.IO.Packaging.ZipPackage クラスなんてのも
あるのですが……Open Package Conventions 形式の zip しか読み書きできないので、
今回の目的には適していないですね。

C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll
http://msdn.microsoft.com/ja-jp/library/system.io.packaging.zippackage.aspx


> よろしくお願いします。
何を? (^^;

[ツリー表示へ]