tag:crieit.net,2005:https://crieit.net/tags/7Zip/feed
「7Zip」の記事 - Crieit
Crieitでタグ「7Zip」に投稿された最近の記事
2019-08-16T09:47:02+09:00
https://crieit.net/tags/7Zip/feed
tag:crieit.net,2005:PublicArticle/15325
2019-08-16T09:46:46+09:00
2019-08-16T09:47:02+09:00
https://crieit.net/posts/C-7zip-Sfx-exe
【C#】7zip(Sfx)で自己解凍exeを作成する
<p>今回は「7zip」を利用して自己解凍形式の実行ファイルを作成してみます。</p>
<p>プログラムは前回のものを流用します。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2018/02/07/post-3858/" target="_blank" rel="noopener">【C#】7zip を使って圧縮ファイルを展開する</a></p>
<h2 id="自己解凍形式について"><a href="#%E8%87%AA%E5%B7%B1%E8%A7%A3%E5%87%8D%E5%BD%A2%E5%BC%8F%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">自己解凍形式について</a></h2>
<p>7zip形式の圧縮ファイルと、設定ファイルをひとまとめにして実行ファイルとし、<br />
ファイルの展開後に任意のプログラムを実行することができます。</p>
<p>主にインストーラーなんかに使われているようです。詳しくは調べてみてください。</p>
<h2 id="画面の修正"><a href="#%E7%94%BB%E9%9D%A2%E3%81%AE%E4%BF%AE%E6%AD%A3">画面の修正</a></h2>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpSfx000-1.jpg" alt="自己解凍exe出力ボタンの追加" /></p>
<p>自己解凍exe出力ボタンを追加します。</p>
<h2 id="SFXのDLLをダウンロードして配置"><a href="#SFX%E3%81%AEDLL%E3%82%92%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%81%97%E3%81%A6%E9%85%8D%E7%BD%AE">SFXのDLLをダウンロードして配置</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://ja.osdn.net/projects/sevenzip/downloads/64455/7z920_extra.7z/" target="_blank" rel="noopener">https://ja.osdn.net/projects/sevenzip/downloads/64455/7z920_extra.7z/</a></p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpSfx001.jpg" alt="dllの追加" /></p>
<p>パッケージエクスプローラーで、ダウンロードした「7zS.sfx」をプロジェクトに追加します。</p>
<p><span style="color: #d92121;">※参照の追加ではありません</span></p>
<h2 id="設定ファイルの作成"><a href="#%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90">設定ファイルの作成</a></h2>
<p>config.txt</p>
<pre><code>;!@Install@!UTF-8!
Title="VisualStudioSolution実行"
BeginPrompt="自己解凍exeを実行しますか?"
Directory=""
ExecuteFile=".\\archive\\WpfApp1.sln"
RunProgram=""
;!@InstallEnd@!
</code></pre>
<p>作成したファイルは、実行ファイルから参照できる場所においてください。</p>
<h2 id="プログラムの修正"><a href="#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E4%BF%AE%E6%AD%A3">プログラムの修正</a></h2>
<h3 id="新規メソッドの追加"><a href="#%E6%96%B0%E8%A6%8F%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E8%BF%BD%E5%8A%A0">新規メソッドの追加</a></h3>
<p>自己解凍exeを出力する処理を追加します。</p>
<pre><code> /// <summary>
/// 自己解凍exeを出力します.
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private int OutputSelfExtractFile(string filePath, string outputDir)
{
// 指定したディレクトリにフォルダ構成を保持した形で出力
string strCommandLine = "copy /b 7zS.sfx + " + "config.txt + " + filePath + " " + outputDir + "\\SelfExtract.exe";
// コマンドプロンプトで実行
Process p = new Process();
//ComSpec(cmd.exe)のパスを取得して、FileNameプロパティに指定
p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec");
//出力を読み取れるようにする
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = false;
//ウィンドウを表示しないようにする
p.StartInfo.CreateNoWindow = true;
//コマンドラインを指定("/c"は実行後閉じるために必要)
p.StartInfo.Arguments = @"/c " + strCommandLine;
//起動
p.Start();
//出力を読み取る
string results = p.StandardOutput.ReadToEnd();
//プロセス終了まで待機する
//WaitForExitはReadToEndの後である必要がある
//(親プロセス、子プロセスでブロック防止のため)
p.WaitForExit();
p.Close();
return 0;
}
</code></pre>
<h3 id="新規イベントの追加"><a href="#%E6%96%B0%E8%A6%8F%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E8%BF%BD%E5%8A%A0">新規イベントの追加</a></h3>
<p>追加したボタンのクリック時の処理を追加します。</p>
<pre><code> /// <summary>
/// 自己解凍exe出力ボタンクリックイベント.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSfx_Click(object sender, EventArgs e)
{
int count = 0;
// 選択されたファイルを解凍
var selectedItems = listView1.SelectedItems;
foreach (ListViewItem item in selectedItems)
{
// ファイルの情報を取得
FileInfo fi = new FileInfo(item.Name);
FileVersionInfo vi = FileVersionInfo.GetVersionInfo(item.Name);
// shell32で取得
string type = "";
SHFILEINFO shinfo = new SHFILEINFO();
IntPtr hSuccess = SHGetFileInfo(item.Name, 0, out shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
if (hSuccess != IntPtr.Zero)
{
type = shinfo.szTypeName;
}
// 圧縮ファイルの判定
// shll32、FileInfo、FileVersionInfoなどから判定できる
// if (vi.FileDescription.IndexOf("7Z") > -1)
// if (fi.Attributes == FileAttributes.Archive)
// ファイル種別で判定
if (type.IndexOf("7Z") > -1)
{
MessageBox.Show(item.Name + "の自己解凍exeを作成します。", "自己解凍exe出力処理");
int ret = OutputSelfExtractFile(item.Name, fi.DirectoryName);
if (ret != 0)
{
MessageBox.Show(item.Name + "の自己解凍exe出力に失敗しました。", "自己解凍exe出力処理");
}
count++;
}
}
// 展開を実行したかどうかでメッセージを変更
if (count == 0)
{
MessageBox.Show("自己解凍する対象が存在しません。", "自己解凍exe出力処理");
}
else
{
MessageBox.Show("自己解凍exeの出力が完了しました。", "自己解凍exe出力処理");
}
}
</code></pre>
<h2 id="起動してみる"><a href="#%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">起動してみる</a></h2>
<p>起動、「7zip」形式のファイルを選択し、「自己解凍exe出力」ボタンをクリックします。</p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpSfx002.jpg" alt="確認メッセージ" /></p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpSfx003.jpg" alt="完了メッセージの表示" /></p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpSfx004-1.jpg" alt="出力されたファイル" /></p>
<p>圧縮ファイルと同じディレクトリに「SelfExtraxt.exe」が出力されます。</p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpSfx005-1.jpg" alt="自己解凍exeの実行" /></p>
<p>出力された「SelfExtraxt.exe」を実行してみます。</p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpSfx006.jpg" alt="プログレスの表示" /></p>
<p>プログレスも表示されます。</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>色々使いどころはあるかと思います。</p>
<p>7-zip32.dll には内蔵されている自己解凍処理もあり、そちらは設定ファイルを画面から設定できたりもするので気になる方は調べてみてください。</p>
<p>ではでは。</p>
<p> </p>
doraxdora
tag:crieit.net,2005:PublicArticle/15306
2019-08-07T10:15:11+09:00
2019-08-07T10:15:11+09:00
https://crieit.net/posts/C-7zip-5d4a261fb618d
【C#】7zip を使って圧縮ファイルを展開する
<p>前回に引き続き「7zip」を利用して、圧縮したファイルを展開してみます。</p>
<p>プログラムは前回のものを流用します。<br />
<a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2018/02/04/post-3838/" target="_blank" rel="noopener" data-blogcard="1">【C#】7zipを使ってファイル・フォルダの圧縮をしてみる</a></p>
<h2 id="プログラムの修正"><a href="#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E4%BF%AE%E6%AD%A3">プログラムの修正</a></h2>
<h3 id="ライブラリ使用宣言の追加"><a href="#%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E4%BD%BF%E7%94%A8%E5%AE%A3%E8%A8%80%E3%81%AE%E8%BF%BD%E5%8A%A0">ライブラリ使用宣言の追加</a></h3>
<p>ファイルの情報取得</p>
<pre><code>using System.Diagnostics;
</code></pre>
<h3 id="新規メソッドの追加"><a href="#%E6%96%B0%E8%A6%8F%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E8%BF%BD%E5%8A%A0">新規メソッドの追加</a></h3>
<p>ファイルを展開する処理を追加します。</p>
<pre><code> /// <summary>
/// 圧縮ファイルを展開します.
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private int FileExpansion(string filePath, string outputDir)
{
// 長いパスを短くする
IntPtr hWnd = this.Handle;
StringBuilder strShortPath = new StringBuilder(1024);
GetShortPathName(filePath, strShortPath, 1024);
// 指定したディレクトリにフォルダ構成を保持した形で出力
string strCommandLine = "x " + strShortPath.ToString() + " -o" + outputDir;
StringBuilder strOutPut = new StringBuilder(1024);
int ret = SevenZip(hWnd, strCommandLine, strOutPut, 1024);
return ret;
}
</code></pre>
<h3 id="展開ボタンクリック時のイベント"><a href="#%E5%B1%95%E9%96%8B%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E6%99%82%E3%81%AE%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88">展開ボタンクリック時のイベント</a></h3>
<p>画面に追加した「展開」ボタンをクリックした際のイベントを追加します。</p>
<pre><code> /// <summary>
/// 展開ボタンクリックイベント
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnExpansion_Click(object sender, EventArgs e)
{
int count = 0;
// 選択されたファイルを解凍
var selectedItems = listView1.SelectedItems;
foreach (ListViewItem item in selectedItems)
{
// ファイルの情報を取得
FileInfo fi = new FileInfo(item.Name);
FileVersionInfo vi = FileVersionInfo.GetVersionInfo(item.Name);
// shell32で取得
string type = "";
SHFILEINFO shinfo = new SHFILEINFO();
IntPtr hSuccess = SHGetFileInfo(item.Name, 0, out shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
if (hSuccess != IntPtr.Zero)
{
type = shinfo.szTypeName;
}
// 圧縮ファイルの判定
// shll32、FileInfo、FileVersionInfoなどから判定できる
//if (type.IndexOf("圧縮") > -1 || type.IndexOf("7z") > -1)
//if (vi.FileDescription.IndexOf("7Z") > -1)
// FileInfoのAttributesで判定
if (fi.Attributes == FileAttributes.Archive)
{
MessageBox.Show(item.Name + "を展開します。", "展開処理");
int ret = FileExpansion(item.Name, fi.FullName.Replace(fi.Extension, ""));
if (ret != 0)
{
MessageBox.Show(item.Name + "の展開に失敗しました。", "展開処理");
}
count++;
}
}
// 展開を実行したかどうかでメッセージを変更
if (count == 0)
{
MessageBox.Show("展開する対象が存在しません。", "展開処理");
}
else
{
MessageBox.Show("ファイルの展開が完了しました。", "展開処理");
}
}
</code></pre>
<h2 id="起動してみる"><a href="#%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">起動してみる</a></h2>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpExpansion000.jpg" alt="対象のファイルを選択する" /></p>
<p>前回の記事で圧縮したファイルを選択して、下のリストに追加します。</p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpExpansion001.jpg" alt="展開ボタンクリック" /></p>
<p>「展開」ボタンをクリックします。</p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpExpansion002.jpg" alt="展開プログレスダイアログ" /></p>
<p>展開中のプログレスダイアログも表示されます。</p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/CSharpExpansion003.jpg" alt="完了メッセージ" /></p>
<p>メッセージが表示されれば完了です。</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>ひとまず、圧縮・展開までをやってみました。<br />
色々オプションなんかもあるので、試してみたいと思います。</p>
<p>次回は自己解凍形式の実行ファイルを作成してみます。</p>
<p>ではでは。</p>
<p> </p>
doraxdora
tag:crieit.net,2005:PublicArticle/15304
2019-08-06T10:14:01+09:00
2019-08-06T10:14:01+09:00
https://crieit.net/posts/C-7zip
【C#】7zipを使ってファイル・フォルダの圧縮をしてみる
<p>今回は画面で選択したファイルやフォルダをまとめて圧縮してみようと思います。<br />
圧縮するためのライブラリで、圧縮率の高さなどが人気の「7zip」というツールを使用します。</p>
<p>プログラムは前回のものを流用します。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://www.doraxdora.com/blog/2018/02/03/post-3831/" target="_blank" rel="noopener" data-blogcard="1">【C#】ListViewの項目を別のListViewへ追加する</a></p>
<h2 id="7zipのdllを入手、配置"><a href="#7zip%E3%81%AEdll%E3%82%92%E5%85%A5%E6%89%8B%E3%80%81%E9%85%8D%E7%BD%AE">7zipのdllを入手、配置</a></h2>
<p>下記サイトより入手。<br />
<a target="_blank" rel="nofollow noopener" href="http://www.vector.co.jp/soft/win95/util/se252429.html" target="_blank" rel="noopener">http://www.vector.co.jp/soft/win95/util/se252429.html</a></p>
<p>作者:秋田 稔 様<br />
<a target="_blank" rel="nofollow noopener" href="http://www.vector.co.jp/vpack/browse/person/an018964.html" target="_blank" rel="noopener">http://www.vector.co.jp/vpack/browse/person/an018964.html</a></p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/Compress000.jpg" alt="パッケージエクスプローラー" /></p>
<p>ダウンロードした「7-zip32.dll」をプロジェクトの直下にコピーします。</p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/Compress001.jpg" alt="プロパティ画面" /></p>
<p>プロパティから「出力ディレクトリにコピー」オプションを「常にコピーする」に変更します。</p>
<h2 id="画面の修正"><a href="#%E7%94%BB%E9%9D%A2%E3%81%AE%E4%BF%AE%E6%AD%A3">画面の修正</a></h2>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/Compress005.jpg" alt="ボタンの追加" /></p>
<p>画面に圧縮ボタン、展開ボタン(今回は未使用)を追加</p>
<h2 id="プログラムの修正"><a href="#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E4%BF%AE%E6%AD%A3">プログラムの修正</a></h2>
<h3 id="ライブラリ使用宣言の追加"><a href="#%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E4%BD%BF%E7%94%A8%E5%AE%A3%E8%A8%80%E3%81%AE%E8%BF%BD%E5%8A%A0">ライブラリ使用宣言の追加</a></h3>
<p>実行ディレクトリのパスを取得するために利用</p>
<pre><code>using System.Reflection;
</code></pre>
<h3 id="新規メソッドの追加"><a href="#%E6%96%B0%E8%A6%8F%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E8%BF%BD%E5%8A%A0">新規メソッドの追加</a></h3>
<p>圧縮対象のフォルダを一時ディレクトリにコピーするために再帰処理をするメソッドを追加</p>
<pre><code> /// <summary>
/// ディレクトリをコピーする
/// </summary>
/// <param name="from">コピー元</param>
/// <param name="to">コピー先</param>
public static void CopyDirectory(string from, string to)
{
// ディレクトリが存在しない場合は作成
if (!Directory.Exists(to))
{
Directory.CreateDirectory(to);
File.SetAttributes(to,File.GetAttributes(from));
}
// コピー先のディレクトリ名の末尾に"\"をつける
if (!to.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
to += Path.DirectorySeparatorChar;
}
// コピー元のディレクトリにあるファイルをコピー
string[] files = Directory.GetFiles(from);
foreach (string file in files)
{
File.Copy(file, to + Path.GetFileName(file), true);
}
// サブディレクトリを再帰処理する
string[] dirs = Directory.GetDirectories(from);
foreach (string dir in dirs)
{
CopyDirectory(dir, to + Path.GetFileName(dir));
}
}
</code></pre>
<h3 id="圧縮ボタンクリックイベントの追加"><a href="#%E5%9C%A7%E7%B8%AE%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E8%BF%BD%E5%8A%A0">圧縮ボタンクリックイベントの追加</a></h3>
<pre><code> /// <summary>
/// 圧縮ボタンクリックイベント.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnCompless_Click(object sender, EventArgs e)
{
// 実行ディレクトリパスの取得
Assembly mainAssembly = Assembly.GetExecutingAssembly();
// 実行フォルダ取得
string appDir = Path.GetDirectoryName(mainAssembly.Location);
// 一時フォルダパス
string copyTo = appDir + "\\Compress";
try
{
// なければ作成
if (!Directory.Exists(copyTo))
{
Directory.CreateDirectory(copyTo);
}
// 選択されたファイルを一時ディレクトリにコピー
var selectedItems = listView1.SelectedItems;
foreach (ListViewItem item in selectedItems)
{
// ファイル・ディレクトリを判定
if (File.Exists(item.Name))
{
// 存在する場合は上書きする
File.Copy(item.Name, copyTo + "\\" + item.Text, true);
}
else if (Directory.Exists(item.Name))
{
// サブディレクトリも再帰処理でコピーする
CopyDirectory(item.Name, copyTo);
}
}
// 圧縮処理
IntPtr hWnd = this.Handle;
StringBuilder strShortPath = new StringBuilder(1024);
GetShortPathName(copyTo, strShortPath, 1024);
// zip圧縮
string strCommandLine = "a -tzip archive.zip " + strShortPath.ToString() + "\\*";
// 7z圧縮
// string strCommandLine = "a -t7z archive.7z " + strShortPath.ToString() + "\\*";
// zip超圧縮
//string strCommandLine = "a -tzip archive.zip " + strShortPath.ToString() + "\\* -mx9";
// zip無圧縮
//string strCommandLine = "a -tzip archive.zip " + strShortPath.ToString() + "\\* -mx0";
// zipパスワード("password")付圧縮(処理状況ダイアログ非表示)
//string strCommandLine = "a -tzip -hide archive.zip " + strShortPath.ToString() + "\\* -ppassword";
// 7zパスワード("password")付圧縮(書庫のヘッダも暗号化)
//string strCommandLine = "a -t7z archive.7z " + strShortPath.ToString() + "\\* -ppassword -mhe";
StringBuilder strOutPut = new StringBuilder(1024);
int ret = SevenZip(hWnd, strCommandLine, strOutPut, 1024);
if (ret == 0)
{
MessageBox.Show(appDir + "に archive.zip を作成しました。", "圧縮処理");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "圧縮エラー");
}
finally
{
//Directory.Delete(copyTo, true);
}
}
</code></pre>
<h2 id="起動してみる"><a href="#%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">起動してみる</a></h2>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/Compress002.jpg" alt="対象のファイルを選択" /></p>
<p>対象のファイル(今回はフォルダ)を選択して「追加」ボタンをクリック、下のリストに追加されたら「圧縮」ボタンをクリックします。</p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/Compress003.jpg" alt="圧縮中" /></p>
<p>ちゃんと圧縮中のプログレスダイアログも表示できます。</p>
<p><img src="https://www.doraxdora.com/wp-content/uploads/2018/02/Compress004.jpg" alt="完了メッセージ" /></p>
<p>無事に圧縮ファイルを作成できました。</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>ちょっと長くなったので、展開(解凍)はまた次回。</p>
<p>ではでは。</p>
<p> </p>
doraxdora