HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0922
サンダーボルト標準DLLを使った圧縮解凍ってできないでしょうか?17未解決


サンダーボルト

リンク

2014/9/22(Mon) 23:53:20|NO.65140

プラグインはあまり使いたくない(というか事情により使えない)

ので、win標準DLLで圧縮解凍ジpか7zか、lzmなど。
できないでしょうか?

いろいろ調べましたがわかりません。

ソースの破片みたいなのでもいいので、教えてください



この記事に返信する


ふぁるこn

リンク

2014/9/23(Tue) 08:36:59|NO.65145

>プラグインはあまり使いたくない
HSPは圧縮ファイルを解凍(展開)する能力は持ってません。
そこで、解凍処理を専門に行う外部汎用ライブラリ(DLL形式)の力を借りることになります。

>配布時の注意
ちなみに、外部プラグインは素のパソコンには当然入っていないので、
各ユーザーに別途入手してもらって、Windowsのシステムフォルダなり実行ファイルと同じフォルダなりに
置いてもらう形になります。(このページで紹介してるZIPとLZHの2ライブラリは、DLLファイル単体での配布が禁止されてるので注意)

>使うDLL
Windows XP〜環境では標準で圧縮と解凍の機能が用意されてますが、
Windowsの世界でもっとも普及している超定番の圧縮形式です。
shoda T.さんらによるZIPファイル解凍ライブラリ「unzip32.dll」を利用します。

>ソース

// ZIPファイルの解凍サンプル (by Kpan) #uselib "unzip32" #func UnZip "UnZip" nullptr, str, int, int #func UnZipGetFileCount "UnZipGetFileCount" str #func UnZipGetVersion "UnZipGetVersion" ; unzip32.dllが存在するか簡易チェック if varptr(UnZipGetVersion) = 0 { dialog "unzip32.dll が見つからん" end } sdim filepath, 256 sdim outpath, 256 sdim szOutput,1024 ; ZIPファイルのパス (例、Cドライブの直下にある場合) filepath = "C:\\sample.zip" mes "ZIPファイル : "+filepath+"" ; 解凍したファイルの出力フォルダ outpath = "C:\\" mes "出力フォルダ : "+outpath+"" button "解凍", *unpack button "情報", *info button "ファイル数", *count button "バージョン", *version stop ; ZIPファイルの解凍 ; 正常に終了すればstatに0が、エラーなら0以外が返ります。 ; オプションとして、--i、-n、-o、-P*****、というようなものがあり、詳細は ; DLL同封の「UNZIP32D.TXT」を参照のこと。たとえば解凍状況ダイアログ非表示なら、 ; (Ex) UnZip "--i \""+filepath+"\" 〜 *unpack UnZip "\""+filepath+"\" \""+outpath+"\"" mes "解凍 : "+stat stop ; ZIPファイル内の情報をszOutputに出力 (解凍処理なし) ; ファイルの内容の一覧表示(-l、-lv、-v)やCRCチェック(-t)などある。 *info UnZip "-lv \""+filepath+"\"", varptr(szOutput), 1024 dialog ""+szOutput stop ; ZIPファイル内に格納されているファイル数を取得 ; ファイルが存在しない、ZIPファイルでない、書庫が壊れている、ような場合は ; -1が返るので、書庫チェック的なこととして利用可。 *count UnZipGetFileCount filepath mes "ファイル数 : "+stat+" コ" stop ; unzip32.dllのバージョン取得 ; 戻り値は下のような感じで返る。 ; 75 -> Version 0.75 、100 -> Version 1.00 、540 -> Version 5.4 *version UnZipGetVersion value = stat value = wpeek(value) ; これがないと2回目以降に正しく取得できない mes "バージョン : "+value+" -> "+(value / 100)+"."+(value \ 100)+"" stop


全ての説明とソースはhttp://lhsp.s206.xrea.com/hsp_file.html#5からの抜粋



サンダーボルト2

リンク

2014/9/23(Tue) 11:43:57|NO.65153

プラグイン遣うしかないようです。


LZM ファイルでいいのでしょうか



ふぁるこn

リンク

2014/9/23(Tue) 11:49:58|NO.65154

LZHは危険、作者が使用中止を呼びかけてる。
http://pc.nikkeibp.co.jp/article/trend/20100810/1026829/

個人的にはZIP使った方が良い。



Starg

リンク

2014/9/23(Tue) 14:23:48|NO.65158

Microsoft は推奨していませんが、こんな方法も。


zip = /* Zip ファイルへのフルパス */ dest = /* 展開先ディレクトリへのフルパス (あらかじめ mkdir などでディレクトリを作っておくこと) */ // 4 : プログレス表示なし // 8 : 同名のファイルが存在したらリネーム // 16 : ダイアログで常に「すべてにはい」を選択 // (以下略) flag = 8 + 16 newcom app, "Shell.Application" comres nsZip app->"NameSpace" zip comres nsDest app->"NameSpace" dest nsDest->"CopyHere" nsZip("Items"), flags stop



サンダーボルト

リンク

2014/9/23(Tue) 14:54:19|NO.65160

インクルード済みだとして、
lzdist "C:\\Users\\desktop"
lzcopy "BatchWOO!.zip"

にしたのですが、コピーされません。
なぜでしょうか?



kanahiron

リンク

2014/9/23(Tue) 19:11:58|NO.65173


「自分はドキュメント(HDL)なんか見ないで質問してるぜ!!!」 って大声で言ってるようですよ
HDLから引用
"name"には、拡張子を含まない名前(8文字まで)を指定してください。



kanahiron

リンク

2014/9/23(Tue) 19:52:13|NO.65177

あ それ以前の問題でしたね
lzcopyでは当然zipなんか解凍できません

Microsoftの compress.exe形式の圧縮ファイルを解凍
参考サイト

Win32API Compress.exeで圧縮されたファイルを解凍する LZCopy http://d.hatena.ne.jp/s-kita/20110430/1304158084 圧縮・解凍形式 - その1:ファイル圧縮 http://www.geocities.jp/matsuhp/pc/arc1.html

ちなみに"compress.exe"はLZ77というアルゴリズムで圧縮しています
LZ77は旧世代の圧縮アルゴリズムで、LZ77を改良したLZSSに、さらに別の技術(ハフマン符号化)を組み合わせたものをDeflateといい、大体のzipの圧縮アルゴリズムとして使われています

しかもcompress.exeって今のwindowsには同梱されてないものだと思います



サンダーボルト2

リンク

2014/9/23(Tue) 21:58:34|NO.65183

えーと。

読んで無いんじゃなくて、見落としです。

では、zip以外だと、lzmけいしきだといいのでしょうか?



ふぁるこn

リンク

2014/9/23(Tue) 22:14:40|NO.65185

誤:lzm
正:LZH

誤字に気をつけよう。

それとLZH形式のアーカイブの使用は危険だと先程発言した。
http://pc.nikkeibp.co.jp/article/trend/20100810/1026829/



ZAP

リンク

2014/9/23(Tue) 22:50:36|NO.65189

検索してみたらlzmという圧縮形式も一応存在するみたいですね。
これってすごくマイナーな形式なのではないですか?
なんかSlax module managerとか出ますが・・・



ZAP

リンク

2014/9/23(Tue) 22:55:18|NO.65190

というか、いったい具体的にはどういうことがしたいのか、
なにゆえプラグインが使えないのか、
そちらの事情を書けばまた別の解決方法が提示してもらえるかも?



kanahiron

リンク

2014/9/23(Tue) 23:17:02|NO.65192

失礼 lzmは普通の圧縮ファイルですね 無知でした

で、
では、zip以外だと、lzmけいしきだといいのでしょうか?
自分が貼ったURL見ればわかると思いますが…
見落としです。
って言われそう

lzcopyで解凍できるのはあくまでも「Compress.exe」で圧縮されたファイルのみです
ぐぐってくださいよ



サンダーボルト

リンク

2014/9/26(Fri) 23:00:19|NO.65264

Compress.exe

ってのがよくわかんないんですよね。

ググったら、LZHがどうこう出てきたんで・・・



774

リンク

2014/9/28(Sun) 18:17:17|NO.65318

ファイル形式を問わないなら
バイナリデータをVRAMに書き込んでPNG画像として保存する事で
多少は圧縮できるかも知れません。(要:GDI+)

PNG保存にはコチラで提示されているモジュールを利用させて頂いてます。
>http://fs-cgi-basic01.freespace.jp/~hsp/ver3/hsp3.cgi?print+201201/12010002.txt

;http://fs-cgi-basic01.freespace.jp/~hsp/ver3/hsp3.cgi?print+201201/12010002.txt #include "GDIplusImgSaveMod.hsp" #module ;--データをVRAMに書き込んで保存("FileName", <buf>, size, winID) <stat:FileSize> #deffunc bPicSave str p0, var p1, int p2, int p3, local a, local b If(p2<1){Return 0} :a.0=512, (p2+4)/(512*3)+1, gInfo.3, gInfo.25 If(p3>0){a.3=p3} :Buffer a.3, a.0, a.1 :mRef b, 66 lPoke b, 0, p2 :MemCpy b, p1, p2, 4 imgsave p0 :Buffer a.3, 1, 1 :gSel a.2 :Exist p0 Return strsize ;--VRAMからデータ取り出し("FileName", <buf>, winID) <stat:size> #deffunc bPicLoad str p0, array p1, int p2, local a, local b Exist p0 :a=strsize, 0, gInfo.3, gInfo.25 :If(a<1){Return 0} If(p2>0){a.3=p2} :Buffer a.3 :PicLoad p0 :mRef b, 66 a.1=lPeek(b) :sDim p1, a.1 :MemCpy p1, b, a.1, 0, 4 Buffer a.3, 1, 1 :gSel a.2 Return a.1 #global *test Screen 0, 320, 56, 2 SysColor 15 :BoxF :sDim s, $100 :sDim si, $100 Pos 4, 4 :Input si, 292, 20 Pos 296, 4 :ObjSize 20, 20 :Button gosub "...", *btn Pos 236, 28 :ObjSize 80, 24 :Button gosub "TEST", *btn gSel 0, 1 :Redraw 0 Stop *btn i=gInfo.2*100+stat If(i==1){Dialog "", 16 :If(stat){ObjPrm 0, refstr}} If(i==2){ Exist si :i.1=strsize :If(i.1<1){Title "File not found" :Return} //保存 sDim buf_0, i.1 :bLoad si, buf_0, i.1 bPicSave si+"_TEST.png", buf_0, i.1, 9 :i.2=stat s=StrF("SAVE: %d => %d", i.1, i.2) :LogMes s :Title s //読み込み Wait 4 :Dim buf_1 bPicLoad si+"_TEST.png", buf_1 :i.3=stat s=StrF("LOAD: %d => %d", i.2, i.3) :LogMes s :Title s //復元チェック Wait 4 :If(i.1^i.3){Goto *@f} :i.0=0 :i.2=0, 0 Color :BoxF 4, 28, 203, 51 :Redraw 1 :Redraw 0 Repeat ;size\4のチェック If(((i^i.1)&3)==0){Break} If(Peek(buf_0, i)^Peek(buf_1, i)){i=-1 :Break} :i++ Loop :If(i<0){Goto *@f} Repeat :If(i>=i.1){Break} If(lPeek(buf_0, i)^lPeek(buf_1, i)){Break} i+=4 :i.3=(i*200)/i.1 :If(i.2==i.3){Continue} :i.2=i.3 GradF 4, 28, i.2, 24, 0, $ff0000, $ffff00 :Redraw 1 :Redraw 0 :aWait 1 Loop *@ :If(i^i.1){s=" failed..."}else{s=" OK"} :LogMes s Pos 8, 32 :Color , 255 :Mes s :Redraw 1 :Redraw 0 :Dim buf_0 :Dim buf_1 } Return
モノによっては逆に増えます…orz



yu

リンク

2014/9/28(Sun) 20:08:51|NO.65319

774さん、そういう発想面白くて好きだなあ



shiva

リンク

2014/10/3(Fri) 22:14:29|NO.65401

Windows 8 以降であれば Compression API を使って実装することもできます。
ただし、.zip や .7z といったアーカイブファイルを取り扱えるようになるわけではありません。念のため。

// データを圧縮・展開するサンプル #cmpopt varinit 1 #module #uselib "kernel32.dll" #cfunc GetLastError "GetLastError" #const ERROR_INSUFFICIENT_BUFFER 122 #uselib "cabinet.dll" #const COMPRESS_ALGORITHM_MSZIP 2 #const COMPRESSDATA_DEFAULT_ALGORITHM COMPRESS_ALGORITHM_MSZIP #func CreateCompressor "CreateCompressor" int, int, int #func Compress "Compress" int, int, int, int, int, int #func CloseCompressor "CloseCompressor" int #func CreateDecompressor "CreateDecompressor" int, int, int #func Decompress "Decompress" int, int, int, int, int, int #func CloseDecompressor "CloseDecompressor" int // データを圧縮する。 // uncompressed_buffer: 圧縮したいデータを保持する変数 // uncompressed_size : 圧縮したいデータのサイズ (bytes) // compressed_buffer : 圧縮結果を受け取る変数 // compressed_size : 圧縮結果のデータサイズを受け取る変数 // 戻り値: 成功時 stat != 0、失敗時 stat == 0 #deffunc CompressData var uncompressed_buffer, int uncompressed_size, var compressed_buffer, var compressed_size, local handle, local result // 環境チェック if varptr(CreateCompressor) == 0 : return 0 // 圧縮ハンドル作成 handle = 0 : CreateCompressor COMPRESSDATA_DEFAULT_ALGORITHM, 0, varptr(handle) if stat == 0 : return 0 // サイズ計算 result = 0 : compressed_size = 0 Compress handle, varptr(uncompressed_buffer), uncompressed_size, 0, 0, varptr(compressed_size) if GetLastError() == ERROR_INSUFFICIENT_BUFFER { // 圧縮する sdim compressed_buffer, compressed_size Compress handle, varptr(uncompressed_buffer), uncompressed_size, varptr(compressed_buffer), compressed_size, varptr(compressed_size) result = (stat != 0) } CloseCompressor handle return result // データを展開する。 // compressed_buffer : 展開したいデータを保持する変数 // compressed_size : 展開したいデータのサイズ (bytes) // uncompressed_buffer: 展開結果を受け取る変数 // uncompressed_size : 展開結果のデータサイズを受け取る変数 // 戻り値: 成功時 stat != 0、失敗時 stat == 0 #deffunc DecompressData var compressed_buffer, int compressed_size, var uncompressed_buffer, var uncompressed_size, local handle, local result // 環境チェック if varptr(CreateDecompressor) == 0 : return 0 // 圧縮ハンドル作成 handle = 0 : CreateDecompressor COMPRESSDATA_DEFAULT_ALGORITHM, 0, varptr(handle) if stat == 0 : return 0 // サイズ計算 result = 0 : uncompressed_size = 0 Decompress handle, varptr(compressed_buffer), compressed_size, 0, 0, varptr(uncompressed_size) if GetLastError() == ERROR_INSUFFICIENT_BUFFER { // 展開する sdim uncompressed_buffer, uncompressed_size Decompress handle, varptr(compressed_buffer), compressed_size, varptr(uncompressed_buffer), uncompressed_size, varptr(uncompressed_size) result = (stat != 0) } CloseDecompressor handle return result #global // ------------ // 以下サンプル // ------------ // 圧縮したいデータを用意する // サンプル: 「吾輩は猫である」より http://www.aozora.gr.jp/cards/000148/card789.html uncompressed_buffer = {" 吾輩《わがはい》は猫である。名前はまだ無い。 どこで生れたかとんと見当《けんとう》がつかぬ。 何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。 吾輩はここで始めて人間というものを見た。 しかもあとで聞くとそれは書生という人間中で一番|獰悪《どうあく》な種族であったそうだ。 この書生というのは時々我々を捕《つかま》えて煮《に》て食うという話である。 しかしその当時は何という考もなかったから別段恐しいとも思わなかった。 ただ彼の掌《てのひら》に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。 "} uncompressed_size = strlen(uncompressed_buffer) + 1 // 圧縮したいデータのサイズ compressed_buffer = "" // 圧縮結果が格納される変数 compressed_size = 0 // compressed のサイズ。あとで計算する title "元のデータ" : mes uncompressed_buffer dialog "圧縮します" CompressData uncompressed_buffer, uncompressed_size, compressed_buffer, compressed_size if stat { dialog strf("圧縮成功\n圧縮前: %d byte(s)\n圧縮後: %d byte(s)\n圧縮率: %.1f %%", uncompressed_size, compressed_size, 100.0 * compressed_size / uncompressed_size) } else { dialog "圧縮失敗", 1 stop } // クリアして元のデータが存在しない状態にする memset uncompressed_buffer, 0, uncompressed_size : cls : title "展開中" dialog "展開します" DecompressData compressed_buffer, compressed_size, uncompressed_buffer, uncompressed_size if stat { title "展開したデータ" : mes uncompressed_buffer dialog strf("展開成功\n展開前: %d byte(s)\n展開後: %d byte(s)\n圧縮率: %.1f %%", compressed_size, uncompressed_size, 100.0 * compressed_size / uncompressed_size) } else { dialog "展開失敗", 1 stop } stop

Windows 7 以前にも対応させたい場合は Cabinet API というのがありますが(Win98くらいからずっとある)
HSP から使うには難易度が高く(マシンコードを埋め込む or DLL作成)難しいと思います。



サンダーボルト

リンク

2014/10/3(Fri) 23:24:29|NO.65402

みなさん。ありがとうございます。


もとはといえば、インストーラーが作りたくて、圧縮ファイルをパックファイルに入れて解凍すればいい
だろうと始めたわけです。

そういえば、バイナリ化してデータファイル送ればいいわけだ・・・(バイナリ化にしくじったが)



ONION software Copyright 1997-2021(c) All rights reserved.