1

この記事のコードを変更して、ディレクトリを圧縮およびコピーするプログラムを作成しました。コードにバックグラウンド ワーカーを含めたので、zip ルーチンを非同期で実行してインターフェイスのフリーズを防ぐことができます。これが私が適応させたコードです:

private void StartZipping()
{
    var zipWorker = new BackgroundWorker { WorkerReportsProgress = true };

    zipWorker.DoWork += ZipWorkerWork;
    zipWorker.RunWorkerCompleted += ZipWorkerCompleted;

    zipWorker.RunWorkerAsync();
}

private void ZipWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    WriteLogEntry("Zip Worker Finished");
    var sleep = new Timer();
    sleep.Tick += SleepTick;
    sleep.Interval = DEBUG ? SecondsToMilliseconds(45) : MinutesToMilliseconds(15);
    sleep.Start();
}

private void ZipWorkerWork(object sender, DoWorkEventArgs e)
{
    WriteLogEntry("Zip Worker Started");
    var checkedItems = GetCheckedItems();
    if (checkedItems.Count() <= 0) return;

    foreach (var p in checkedItems)
        ZipFiles(((BackupProgram)p.Tag));
}

private static void ZipFiles(BackupProgram program)
{
    var zipPath = string.Format("{0}{1}.ZIP", TempZipDirectory, program.Name.ToUpper());
    WriteLogEntry(string.Format("Zipping files from '{0}' to '{1}'...", program.Path, zipPath));
    try
    {
        var emptyzip = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        if (File.Exists(zipPath)) File.Delete(zipPath);

        var fs = File.Create(zipPath);
        fs.Write(emptyzip, 0, emptyzip.Length);
        fs.Flush();
        fs.Close();
        //fs = null;

        //Copy a folder and its contents into the newly created zip file
        var sc = new Shell32.ShellClass();
        var srcFlder = sc.NameSpace(program.Path);
        var destFlder = sc.NameSpace(zipPath);
        var items = srcFlder.Items();
        destFlder.CopyHere(items, 20);
        //sc = null;

        System.Threading.Thread.Sleep(1000);
        ZippedPrograms.Add(zipPath);
        WriteLogEntry("Zip Succeeded");
    }
    catch (Exception ex)
    {
        WriteLogEntry(string.Format("Zipping Failed: {0} >> {1}", ex.Message, ex.InnerException.Message));
        MessageBox.Show(ex.InnerException.Message, ex.Message);
    }
}

internal class BackupProgram
{
    public string Name { get; set; }
    public string Path { get; set; }

    public BackupProgram(string name, string path)
    {
        Name = name;
        Path = path;
    }
}

明らかに、現状では、このコードがヒットすると、すべての圧縮ウィンドウが表示されます。サンプル プログラム (ウィンドウを非表示にするプログラム) を模倣しようとしましたが、わずかな成功しかありませんでした。窓は隠されていましたが、ジッパーは部分的にしか完成していませんでした。記事のものとほぼ同じように動作するように変更されたコードを次に示します。

private static void ZipFiles(BackupProgram program)
{
    try
    {
        var zipPath = string.Format("{0}{1}.ZIP", TempZipDirectory, program.Name.ToUpper());

        var i = new ProcessStartInfo(AppDomain.CurrentDomain.BaseDirectory + "zip.exe");
        i.Arguments = string.Format("\"{0}\" \"{1}\"", program.Path, zipPath);
        //i.CreateNoWindow = false;
        //i.WindowStyle = ProcessWindowStyle.Normal;
        i.CreateNoWindow = true;
        i.WindowStyle = ProcessWindowStyle.Hidden;

        if (File.Exists(zipPath))
        {
            WriteLogEntry(string.Format("'{0}' exists, deleting...",zipPath));
            File.Delete(zipPath);
        }

        var process = Process.Start(i);
        WriteLogEntry(string.Format("Zipping files from '{0}' to '{1}'...", program.Path, zipPath));

        process.WaitForExit();
        ZippedPrograms.Add(zipPath);
        WriteLogEntry("Zip Succeeded");
    }
    catch (Exception ex)
    {
        WriteLogEntry(string.Format("Zipping Failed: {0} >> {1}", ex.Message, ex.InnerException.Message));
        MessageBox.Show(ex.InnerException.Message, ex.Message);
    }
}

私が知りたいのは、元の適応コードを使用する方法はありますが、進行状況ウィンドウを非表示にする方法はありますか?

ありがとう!

編集

サンプル ソリューションのコード (投稿の上部にあるリンクからダウンロードできます) は、zip.exe です。

using System;
using System.IO;

namespace zip
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {

            //Create an empty zip file
            byte[] emptyzip = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

            FileStream fs = File.Create(args[1]);
            fs.Write(emptyzip, 0, emptyzip.Length);
            fs.Flush();
            fs.Close();
            fs = null;

            //Copy a folder and its contents into the newly created zip file
            Shell32.ShellClass sc = new Shell32.ShellClass();
            Shell32.Folder SrcFlder = sc.NameSpace(args[0]);
            Shell32.Folder DestFlder = sc.NameSpace(args[1]);
            Shell32.FolderItems items = SrcFlder.Items();
            DestFlder.CopyHere(items, 20);

            //Ziping a file using the Windows Shell API creates another thread where the zipping is executed.
            //This means that it is possible that this console app would end before the zipping thread 
            //starts to execute which would cause the zip to never occur and you will end up with just
            //an empty zip file. So wait a second and give the zipping thread time to get started
            System.Threading.Thread.Sleep(1000);

        }
    }
}
4

2 に答える 2

1

ウィンドウ、進行状況、またはその他のUI表示なしで圧縮し、バックグラウンドで非表示にして実行したい場合は、dotnetzipなどのzipライブラリを使用して、スレッドをスピンオフし、必要なロジックを呼び出して実行します。 zip操作ワークフロー。

http://dotnetzip.codeplex.com http://dotnetzip.codeplex.com/wikipage?title=CS-Examples

于 2012-11-03T20:16:40.373 に答える
1

このリンクは、同じことを達成する良い例を提供します: http://geraldgibson.net/dnn/Home/CZipFileCompression/tabid/148/Default.aspx

答えを表示するには、リンクされたページを下にスクロールする必要があります。お役に立てれば!

于 2012-11-03T23:52:53.653 に答える