Developing Matt

My Technical Journal

Unzip and the copyHere command (with vUseless vOptions)

with 15 comments

If you want to copy a file from one location to another you can certainly do it with using a folder shell object. A bonus: using the shell object enables you to copy from a zipped location. this is great until you need to use it as a hidden process requiring no user input. The problem is that if the file you are unzipping already exists you’ll get a prompt asking if you want to overwrite. The solution that doesn’t work: the shell32.folder.copyhere(sourcefolder, vOptions) has a vOptions which enables you to answer ‘yes to all’ for all overwrite prompts. Let me save you some time: contrary to the msdn article, it doesn’t work. My solution: create an unzip application and call it from another application as a process…setting the visible property to false.

Unzip vb script:

 

Dim sourcefile As String = Command$()
If Right(sourcefile, 1) = “\” Then sourcefile = Left(sourcefile, Len(sourcefile) – 1)
Dim sPath As String = Left(sourcefile, InStrRev(sourcefile, “\”))

Dim myShell As New Shell32.Shell
Dim sourceFolder As Shell32.Folder = myShell.NameSpace(sourcefile)
Dim destinationFolder As Shell32.Folder = myShell.NameSpace(sPath)
Try
Dim i As Integer
For i = 0 To sourceFolder.Items.Count – 1
If System.IO.File.Exists(destinationFolder.Items.Item.Path & “\” & sourceFolder.Items.Item(i).Name) Then _
System.IO.File.Delete(destinationFolder.Items.Item.Path & “\” & sourceFolder.Items.Item(i).Name)
destinationFolder.CopyHere(sourceFolder.Items.Item(i))
Console.WriteLine(“Unzipped ” & sourceFolder.Items.Item(i).Name & ” to ” & destinationFolder.Items.Item.Path)
Next
Return 0
Catch ex As Exception
Console.WriteLine(“Could not unzip from ” & sourcefile & ” to ” & destinationFolder.Items.Item.Path)
Console.WriteLine(“Error: ” & Err.Description)
Return Err.Number
Finally
destinationFolder = Nothing
sourceFolder = Nothing
myShell = Nothing
End Try

After you create this exe you can call it as a process:

 

Dim iProcess As New System.Diagnostics.ProcessStartInfo(AppDomain.CurrentDomain.BaseDirectory + “unzip.exe”)

iProcess.CreateNoWindow = True
Dim sArgs As String = ZippedFile
iProcess.Arguments = sArgs
iProcess.WindowStyle = ProcessWindowStyle.Hidden
Dim p As New System.Diagnostics.Process
iProcess.UseShellExecute = False
p = System.Diagnostics.Process.Start(iProcess)
p.WaitForExit(30000)
Dim s As Integer = p.ExitCode
iProcess.UseShellExecute = True

p.Dispose()
iProcess = Nothing

edit 1/13/2011: please read all the comments as some others have posted some great additions to this method and made it even better. Thank you everyone for the great input!!

About these ads

Written by matt

August 8, 2007 at 2:28 pm

Posted in VB.net

15 Responses

Subscribe to comments with RSS.

  1. This is a old post, but ill post the solution for whomever maybe have the same problems.

    The garbage collector of this function does not work. The variable passed pertains to where you are attempting to copy to, not the functions temporary scratch space. The first time you use this function, it will work, but if you try to run it multiple times from the same zip file, you will receive “the file exists” error because the scratch space already contains a file of that name. It gets confused and errors with “the file exists”

    Go to “c:\documents and settings\username\localsettings\temp\temporary directory xx for whatever.zip\”

    Delete all of the “temporary directory for” directories and run it again and it will function.

    aasdf

    October 9, 2008 at 11:37 am

  2. great information. thank you for posting.

    matt

    October 9, 2008 at 2:29 pm

  3. Thanks – I execute CopyHere in a powershell script, which stopped working mysteriously due to this error.

    Doug

    February 16, 2009 at 10:54 am

  4. Thanks alot – I have been having this problem for days and still pulling my hair out until I see this post. What a lifesaver. Thanks again.

    andy

    April 14, 2009 at 9:42 pm

  5. Thanks for this wonderful post…
    Great Job!

    Johnjames

    May 18, 2009 at 3:15 am

  6. Thanks!!! My hair turned grey in my trial-and-error’s to solve this problem. You really made my day!

    Håkan from Sweden

    June 30, 2009 at 11:16 am

  7. Thanks so much for the information! I wasn’t able to solve the problem by clearing out the “temp” directories, but from what you explained, I assumed if I changed the name of the zip folder then it might solve the issue – which it did! Thanks again!!!!

    Kristin

    September 10, 2009 at 6:31 am

  8. How should we get rid of the the temporary directory mentioned in the solution that is created whenever we unzip, which is causing the file exists error. Will the directory be created in the same location on all windows OSs? Can this be programably deleted instead of manual operation.Or is there any option not to create the temporary directory?

    Bhanu

    February 25, 2010 at 12:51 pm

  9. Bhanu,
    From the external application I would recommend managing the file management there. In other words, check for the file, unzip, and then clean up. Separating this process enables you to have a little more management flexibility over the locked files issue.

    matt

    February 25, 2010 at 1:45 pm

  10. this will clear the temp directory on the fly:

    call cleanTemp

    Private Sub cleanTemp()
    Dim wshNet, objFolder, fsoObj, objFolderLoop
    Dim x

    Set wshNet = CreateObject(“Wscript.network”)
    Set fsoObj = CreateObject(“Scripting.Filesystemobject”)
    Set objFolder = fsoObj.GetFolder(“c:\documents and settings\” & wshNet.UserName & “\local settings\temp\”)
    x = 0

    For Each objFolderLoop In objFolder.subfolders
    If (InStr(1, objFolderLoop.Name, “Temporary Directory”) > 0) Then
    fsoObj.DeleteFolder “c:\documents and settings\” & wshNet.UserName & “\local settings\temp\” & objFolderLoop.Name, 1
    x = x + 1
    End If
    Next

    Set wshNet = Nothing
    Set fsoObj = Nothing
    Set objFolder = Nothing
    Set objFolderLoop = Nothing

    End Sub

    aasdf

    March 22, 2010 at 12:17 pm

    • I know a year late, but the one issue with this delete method is that you could end up deleting something that is still required. It would be nice if either the options specified by MS worked, and secondly if there was a cleanup switch to folder.copyhere. I am in the process of putting writing a method to do this, and will post up if I finish.

      Turbo

      January 6, 2011 at 3:48 am

      • As promised, here’s the code I’ve used. Change CompressedFileName as an input, it should be the original zip name. This should be enough to clean-up.

        Turbo.

        //Where are the tmp files held?
        string TMPUnzipFolder = Path.GetTempPath();

        //Get a list of the directories
        List dirs = Directory.GetDirectories(TMPUnzipFolder);

        //Put a try wrapper in place, but don’t action anything on fail, not needed.
        try
        {
        //Now clearup the temp directory left by windows
        foreach (string dirName in dirs)
        {
        //Is directory the one we’ve just unzipped?
        if (dirName.Contains(CompressedFileName))
        {
        //Delete it
        Directory.Delete(dirName);
        }
        }
        }
        catch { }

        Turbo

        January 13, 2011 at 5:28 am

      • Thank you Turbo! Great stuff. Thank you for taking the time to make this code better! You rock!!

        matt

        January 13, 2011 at 11:31 am

  11. What I love about forums and blogs is how people contribute code for free….just for the sake of learning. Thank you, mr. anonymous nospam@dontemailme (aasdf) for the cleanup code! Very alturistic of you.

    matt

    March 22, 2010 at 1:42 pm

  12. HI I have a problem when a try to unzzip on windows server do you know if a need install something, when I test in win 7 it works

    sory

    March 5, 2013 at 10:08 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: