Click here to Skip to main content
15,867,308 members
Articles / Desktop Programming / Win32

How to Utilise the Shell32 Library in .NET as a COM Import – A Neat little Hack

Rate me:
Please Sign up or sign in to vote.
4.00/5 (5 votes)
15 Mar 2009CPOL3 min read 122.7K   2.1K   20   21
Using the Shell32 Library to write Files or Folders to a Zip File

Introduction

Ever wanted to know how to compress files without using a 3rd party library? Well as pointless as it may seem, I'm going to explain how.

Background

My drive to get this working was to allow me to use ExpressMaint utility and compress my databases. So here I am writing my first article on The Code Project.

Breaking Down a Zip File

Firstly this is hack, so we need to understand how a zip file is made, to demonstrate I've used a hex editor (binary editor) to show you.

I created an empty zip file in Windows by right clicking in a folder:

EmptyZipFile.jpg

Great, now we see an empty zip file, of 22 bytes.
Then we add a text file which contains the text “Hello World”, just for comparison:

SimpleZipFile.jpg

For those of you who'd like to get a better understanding of what the header of a *.zip comprises, this is the header break down:

  • local file header signature 4 bytes (0x04034b50)
  • version needed to extract 2 bytes
  • general purpose bit flag 2 bytes
  • compression method 2 bytes
  • last mod file time 2 bytes
  • last mod file date 2 bytes
  • crc-32 4 bytes
  • compressed size 4 bytes
  • uncompressed size 4 bytes
  • file name length 2 bytes
  • extra field length 2 bytes
  • file name (variable size)
  • extra field (variable size)

Ok, so looking at this we obviously don't need to cater for the following fields in the header, as we only need 22 bytes for an empty file:

  • uncompressed size 4 bytes
  • file name length 2 bytes
  • extra field length 2 bytes

Ok, enough theory, let’s have some fun...

The reason I suffixed this article with “Neat little Hack” is because we are going to use the Shell32.dll to copy a file or folder to the destination zip file, which Windows supports natively.
This leaves one flaw; we need a destination file... which we will create manually, hence getting to know the theory.

How to create the *.zip file in VB.NET and C#.

VB.NET

VB.NET
Public Sub CreateZipFile(ByVal Filename As String) 'create a new empty zip file
        'Create Header of Zip File
        Dim Encoder As New System.Text.ASCIIEncoding
        Dim Header As String = "PK" & Chr(5) & Chr(6)
        Header = Header.PadRight(22, Chr(0))

        'Save file - Make sure your file ends with .zip!
        My.Computer.FileSystem.WriteAllBytes(Filename, Encoder.GetBytes(Header), False)
        
    End Sub

C#

C#
public void CreateZipFile(string filename)
    {
        //Create the header of the Zip File 
        System.Text.ASCIIEncoding Encoder = new System.Text.ASCIIEncoding();
        string sHeader = "PK" + (char)5 + (char)6;
        sHeader = sHeader.PadRight(22, (char)0);
        //Convert to byte array
        byte[] baHeader = System.Text.Encoding.ASCII.GetBytes(sHeader);

        //Save File - Make sure your file ends with .zip!
        FileStream fs = File.Create(filename);
        fs.Write(baHeader, 0, baHeader.Length);
        fs.Flush();
        fs.Close();
        fs = null;
    } 

So what exactly have we accomplished? We have created an empty zip file which is the same as right clicking in a folder in Windows and choosing New > Compressed (Zipped) folder.

Now we have the function for creating the empty *.zip file, we are now ready to copy data to the file.

You need to add a reference to your shell32.dll file, which is found in your System32 folder.

As not all computer running Windows are setup the same, this is how you will find your Windows folder (including drive letter):

SET_Get_WinDir.jpg

Now I can see my Windows folder is in the drive lettered C, and the folder is Windows. I now know that the file I'm looking for is in C:\Windows\System32.

In our Visual Studio project, we need to add a reference to this file, so right click on your Project in the Solution Explorer and select Add Reference:

AddRef1.jpg

Then select Browse, and locate the file:

AddRef2.jpg

How to copy a file or folder to a *.zip file in VB.NET and C#:

VB.NET

VB.NET
 Public Sub ZipFile(ByVal Input As String, ByVal Filename As String)
    Dim Shell As New Shell32.Shell

    'Create our Zip File
    CreateZipFile(Filename) 'Create a new .zip file

    'Copy the file or folder to it
    Shell.NameSpace(Filename).CopyHere(Input)

    'Wait until the File/Folder has finished writing to zip file...
    Do Until Shell.NameSpace(Filename).Items.Count =
            Shell.NameSpace(Input).Items.Count
        System.Threading.Thread.Sleep(200)
        System.Diagnostics.Debug.Print("Waiting...")
    Loop
End Sub

C#

C#
public void ZipFile(string Input, string Filename)
    {
        Shell32.Shell Shell = new Shell32.Shell();
        
        //Create our Zip File
        CreateZipFile(Filename);

        //Copy the file or folder to it
        Shell.NameSpace(Filename).CopyHere(Input,0);
          
        //If you can write the code to wait for the code to finish, please let me know
        System.Threading.Thread.Sleep(2000);

        }
    }

Conclusion

Although it's not practical as one would need to code logic to handle existing zip files, it was fun writing this article and hopefully someone finds it interesting.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
South Africa South Africa
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionFound a simpler solution Pin
Member 1454180525-Jul-19 16:48
Member 1454180525-Jul-19 16:48 
GeneralExcellent and appretiable Pin
kuntal4110116-May-13 7:38
kuntal4110116-May-13 7:38 
Questionnot working on xp Pin
Member 346192224-Jun-12 23:58
Member 346192224-Jun-12 23:58 
AnswerRe: not working on xp Pin
Sam Hobbs26-Jan-18 8:56
Sam Hobbs26-Jan-18 8:56 
Me too. I have Windows 10 and it does not work for me either. I assume Microsoft has decided that the interface can't work in .Net and I have not found something that works.

System.InvalidCastException
  HResult=0x80004002
  Message=Unable to cast COM object of type 'System.__ComObject' to interface type 'Shell32.Shell'. 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 (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

AnswerRe: not working on xp Pin
Sam Hobbs27-Jan-18 12:03
Sam Hobbs27-Jan-18 12:03 
GeneralLooping Pin
zhtway18-Mar-11 13:06
zhtway18-Mar-11 13:06 
GeneralMy vote of 3 Pin
Vikas Kmr Chaturvedi9-Jul-10 0:17
Vikas Kmr Chaturvedi9-Jul-10 0:17 
GeneralYou Are The Man! Pin
mynameused27-Jun-10 16:05
mynameused27-Jun-10 16:05 
GeneralWaiting Pin
magerain3-May-10 0:11
magerain3-May-10 0:11 
GeneralRe: Waiting Pin
magerain3-May-10 0:18
magerain3-May-10 0:18 
GeneralCopying files within a folder Pin
NapkinBob14-Feb-10 5:33
NapkinBob14-Feb-10 5:33 
GeneralRe: Copying files within a folder Pin
NapkinBob12-Mar-10 9:45
NapkinBob12-Mar-10 9:45 
GeneralAnother way to reference Shell32 Pin
Juan1R23-Mar-09 23:53
Juan1R23-Mar-09 23:53 
GeneralRe: Another way to reference Shell32 Pin
NapkinBob12-Mar-10 9:48
NapkinBob12-Mar-10 9:48 
GeneralRe: Another way to reference Shell32 Pin
mynameused27-Jun-10 16:06
mynameused27-Jun-10 16:06 
GeneralCaveat Pin
The_Mega_ZZTer16-Mar-09 4:25
The_Mega_ZZTer16-Mar-09 4:25 
GeneralRe: Caveat Pin
Justin Porteous16-Mar-09 19:53
Justin Porteous16-Mar-09 19:53 
GeneralNice: [modified] Pin
johannesnestler16-Mar-09 2:16
johannesnestler16-Mar-09 2:16 
GeneralRe: Nice: Pin
Justin Porteous16-Mar-09 2:22
Justin Porteous16-Mar-09 2:22 
Generalcool trick Pin
tamash_ionut16-Mar-09 2:02
tamash_ionut16-Mar-09 2:02 
GeneralRe: cool trick Pin
Justin Porteous16-Mar-09 2:24
Justin Porteous16-Mar-09 2:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.