Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

C# – Shell32 Kütüphanesi İle Dosya Sıkıştırma

Önceki yazılarımdan C# – System.IO.Packaging Kütüphanesi İle Dosya Sıkıştırma ve C# – DotNetZip Kütüphanesi İle Dosya Sıkıştırma başlıklı yazılarımda C# ile sıkıştırma tekniklerine değinmiştim.Bu yazımızda son olarak C#’ta Shell32 kütüphanesi ile dosya sıkıştırmayı değineceğiz.

Her iki yazımda da olduğu gibi bu yazımda da göstereceğim teknik diğerlerine benzeyecektir.

Bu teknikte herşeyden önce Shell32.dll dosyasını indirip projemize referans olarak entegre etmemiz gerekmektedir.

Dosyayı buradan indirebilirsiniz.

Öncelikle Base Class olarak kullanacağımız “ArchiveObj” ve “ArchiveCreator” isimli iki adet abstract sınıfımızı oluşturalım.

public abstract class ArchiveObj
{
    internal String strPath;
    internal List<String> lError;
    internal List<String> lFiles;
    public String[] ErrorList
    {
        get
        {
            return lError.ToArray();
        }
    }
    public ArchiveObj()
    {
        lFiles = new List<string>();
        lError = new List<string>();
    }
    public Boolean AddFile(String strFile)
    {
        lFiles.Add(strFile);
        return true;
    }
    public abstract int SaveArchive();
}
public abstract class ArchiveCreator
{
    internal String strPath;
    public abstract ArchiveObj GetArchieve();
}

Şimdide projemize “ZipShell.cs” isimli bir sınıf ekleyerek içeriğini aşağıdaki gibi oluşturalım.

    class ZipShell : ArchiveObj
    {
        private ZipShell() { }
        public ZipShell(String sPath)
        {
            strPath = sPath;
        }
        public override int SaveArchive()
        {
            CreateZip(strPath);
            foreach (String strFile in lFiles)
                ZipCopyFile(strFile);
            return 1;
        }
        public bool CreateZip(String strZipFile)
        {
            try
            {
                ASCIIEncoding Encoder = new ASCIIEncoding();
                byte[] baHeader = System.Text.Encoding.ASCII.GetBytes(("PK" + (char)5 + (char)6).PadRight(22, (char)0));
                FileStream fs = System.IO.File.Create(strZipFile);
                fs.Write(baHeader, 0, baHeader.Length);
                fs.Flush();
                fs.Close();
                fs = null;
            }
            catch (Exception ex)
            {
            }
            return true;
        }
        private bool ZipCopyFile(String strFile)
        {
            Shell Shell = new Shell();
            int iCnt = Shell.NameSpace(strPath).Items().Count;
            Shell.NameSpace(strPath).CopyHere(strFile, 0); // Copy file in Zip
            if (Shell.NameSpace(strPath).Items().Count == (iCnt + 1))
            {
                System.Threading.Thread.Sleep(100);
            }
            return true;
        }
    }

Hemen ardından “ZipShellCreator.cs” isimli sınıfımızı oluşturup içeriğini aşağıdaki gibi yazalım.

    public class ZipShellCreator : ArchiveCreator
    {
        private ZipShellCreator() { }
        public ZipShellCreator(String sPath)
        {
            strPath = sPath;
        }
        public override ArchiveObj GetArchieve()
        {
            return new ZipShell(strPath);
        }
    }

Bu işlemlerden sonra sıkıştırma işlemimizi yapan programımızı tamamlamış oluyoruz.Şimdi sıra programımızı kullanmaya geldi.

        private void Form1_Load(object sender, EventArgs e)
        {
            ArchiveCreator ssss = new ZipShellCreator(@"D:\Deneme\arsiv.zip");
            ArchiveObj xxxx = ssss.GetArchieve();
            xxxx.AddFile(@"D:\Deneme\a.txt");
            xxxx.AddFile(@"D:\Deneme\b.PNG");
            xxxx.AddFile(@"D:\Deneme\c.docx");
            xxxx.SaveArchive();
        }

Programı derleyip çalıştırdığınız zaman sıkıştırma işlemini başarıyla gerçekleştirdiğini göreceksiniz.

İyi çalışmalar diliyorum…

Bunlar da hoşunuza gidebilir...

1 Cevap

  1. Gençay dedi ki:

    Merhaba;

    Yukarıda verilen stratejiyle belirtilen dosyaları sıkıştırmaya çalıştığınızda aşağıdaki olası hatayı alabilirsiniz.

    Hatanın metinsel halinide paylaşmamız gerekirse eğer;
    System.InvalidCastException: ‘Unable to cast COM object of type ‘Shell32.ShellClass’ to interface type ‘Shell32.IShellDispatch6’. This operation failed because the QueryInterface call on the COM component for the interface with IID ‘{286E6F1B-7113-4355-9562-96B7E9D64C54}’ failed due to the following error: No such interface supported (0x80004002 (E_NOINTERFACE)).’

    Bu olası hatayı çözebilmek için aşağıdaki metodu;

            private bool ZipCopyFile(String strFile)
            {
                Shell shell = new Shell();
                int iCnt = shell.NameSpace(strPath).Items().Count;
                shell.NameSpace(strPath).CopyHere(strFile, 0);
                if (shell.NameSpace(strPath).Items().Count == (iCnt + 1))
                {
                    System.Threading.Thread.Sleep(100);
                }
                return true;
            }
    

    aşağıdakiyle değiştirmeniz yeterlidir.

            private bool ZipCopyFile(String strFile)
            {
                Shell shell = new Shell();
                int iCnt = GetShell32NameSpaceFolder(strPath).Items().Count;
                GetShell32NameSpaceFolder(strPath).CopyHere(strFile, 0);
                if (GetShell32NameSpaceFolder(strPath).Items().Count == (iCnt + 1))
                {
                    System.Threading.Thread.Sleep(100);
                }
                return true;
            }
            public Shell32.Folder GetShell32NameSpaceFolder(Object folder)
            {
                Type shellAppType = Type.GetTypeFromProgID("Shell.Application");
    
                Object shell = Activator.CreateInstance(shellAppType);
                return (Shell32.Folder)shellAppType.InvokeMember("NameSpace",
                System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { folder });
            }
    

    Sevgiler.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir