Take the 2-minute tour ×

I am using 7-Zip on Windows XP and whenever I download a .tar.gz file it takes me two steps to completely extract the file(s).

  1. I right-click on the example.tar.gz file and choose 7-Zip --> Extract Here from the context menu.
  2. I then take the resulting example.tar file and the right-click again and choose 7-Zip --> Extract Here from the context menu.

Is there a way through the context menu to do this in one step?

share|improve this question
add comment

3 Answers

up vote 23 down vote accepted

Not really. A .tar.gz or .tgz file really is two formats: .tar is the archive, and .gz is the compression. So the first step decompresses, and the second step extracts the archive.

To do it all in one step, you need the tar program. Cygwin includes this, as does GnuWin32.

tar xzvf foobaz.tar.gz

; x = eXtract 
; z = filter through gZip
; v = be Verbose (show activity)
; f = filename

You could also do it "in one step" by opening the file in the 7-zip GUI: Open the .tar.gz file, double click the included .tar file, then extract those files to your location of choice.

There's a long running thread here of people asking/voting for one-step handling of tgz and bz2 files. The lack action thus far indicates it's not going to happen until someone steps and contributes meaningfully (code, money, something).

share|improve this answer
Thanks - didn't know if I was missing something obvious...apparently not ;) –  quickcel Dec 7 '09 at 20:26
If 7zip were smart, it would do it in one step by default, since 99.99% of the time that's what the user wants to do. In fact, this is WinRar's default operation. –  davr Dec 7 '09 at 20:35
@davr: 7-zip is an open source effort; feel free to request this feature. this is how v4.65 operates; i haven't tried the newer v9.x alphas, so it may already be included. –  quack quixote Dec 7 '09 at 20:52
new user to 7z myself, i was interested in knowing if this was possible as well. –  Roy Rico Dec 8 '09 at 2:39
Yah, this is what I miss from WinRar's operation. I could confirm that up to today, Oct2012, 7zip still doesn't auto decompress with 1 step. sigh –  fedmich Oct 19 '12 at 13:18
show 1 more comment

Old question, but I was struggling with it today so here's my 2c. The 7zip commandline tool "7z.exe" (I have v9.22 installed) can write to stdout and read from stdin so you can do without the intermediate tar file by using a pipe:

@echo off
setlocal enabledelayedexpansion

rem Ensure 7z.exe is in your path... ie. set PATH=%PATH%;C:\Program Files\7-Zip

rem Loop through all commandline args - the tar.gz files
for %%i in (%*) do (

    rem Remove .gz
    set j=%%~dpni

    rem Remove .tar 
    for %%k in (!j!) do set k=%%~dpnk

    rem I'm sure there's other ways to strip the extension/s, 
    rem but this works for .tar.gz and .tgz which is all I need.

    rem Extract without an intermediate .tar
    7z x "%%i" -so | 7z x -aoa -si -ttar -o"!k!"


x    = Extract with full paths command
-so  = write to stdout switch
-si  = read from stdin switch
-aoa = Overwrite all existing files without prompt. 
-o   = output directory

See the help file (7-zip.chm) in the install directory for more info on the command line commands and switches.

You can create a context menu entry for .tar.gz/.tgz files that calls the above script using regedit or a 3rd party tool like stexbar.

share|improve this answer
what does the -aoa switch do? It's not listed in -? page –  Superole Oct 23 '13 at 8:40
..ahh but it is in the help file; -ao[a|s|t|u] (overwrite mode). thus: -aoa = overwrite all existing files w/o prompt –  Superole Oct 23 '13 at 8:47
Whoever downvoted, why not comment on your reason for doing so... –  Luke Dec 29 '13 at 9:31
add comment

You're using Windows XP, so you should have Windows Scripting Host installed by default. With that being said, here's a WSH JScript script to do what you need. Just copy the code to a file name xtract.bat or something along those lines (Can be whatever as long as it has the extension .bat), and run:

xtract.bat example.tar.gz

By default, the script will check the folder of the script, as well as your system's PATH environment variable for 7z.exe. If you want to change how it looks for stuff, you can change the SevenZipExe variable at the top of the script to whatever you want the executable name to be. (For instance, 7za.exe or 7z-real.exe) You can also set a default directory for the executable by changing SevenZipDir. So if 7z.exe is at C:\Windows\system32\7z.exe, you'd put:

var SevenZipDir = "C:\\Windows\\system32";

Anyways, here's the script:

@set @junk=1 /* vim:set ft=javascript:
@echo off
cscript //nologo //e:jscript "%~dpn0.bat" %*
goto :eof
/* Settings */
var SevenZipDir = undefined;
var SevenZipExe = "7z.exe";
var ArchiveExts = ["zip", "tar", "gz", "bzip", "bz", "tgz", "z", "7z", "bz2", "rar"]

/* Multi-use instances */
var WSH = new ActiveXObject("WScript.Shell");
var FSO = new ActiveXObject("Scripting.FileSystemObject");
var __file__ = WScript.ScriptFullName;
var __dir__ = FSO.GetParentFolderName(__file__);
var PWD = WSH.CurrentDirectory;

/* Prototypes */
(function(obj) {
    obj.has = function object_has(key) {
        return defined(this[key]);
    return obj;

(function(str) {
    str.trim = function str_trim() {
        return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');

(function(arr) {
    arr.contains = function arr_contains(needle) {
        for (var i in this) {
            if (this[i] == needle) {
                return true;
        return false;

/* Utility functions */
function defined(obj)
    return typeof(obj) != "undefined";

function emptyStr(obj)
    return !(defined(obj) && String(obj).length);

/* WSH-specific Utility Functions */
function echo()
    if(!arguments.length) return;
    var msg = "";
        msg += arguments[n];
        msg += " ";

function fatal(msg)
    echo("Fatal Error:", msg);

function findExecutable()
    // This function searches the directories in;
    // the PATH array for the specified file name;
    var dirTest = emptyStr(SevenZipDir) ? __dir__ : SevenZipDir;
    var exec = SevenZipExe;
    var strTestPath = FSO.BuildPath(dirTest, exec);
    if (FSO.FileExists(strTestPath))
        return FSO.GetAbsolutePathName(strTestPath);

    var arrPath = String(
            dirTest + ";" + 

    for(var i in arrPath) {
        // Skip empty directory values, caused by the PATH;
        // variable being terminated with a semicolon;
        if (arrPath[i] == "")

        // Build a fully qualified path of the file to test for;
        strTestPath = FSO.BuildPath(arrPath[i], exec);

        // Check if (that file exists;
        if (FSO.FileExists(strTestPath))
            return FSO.GetAbsolutePathName(strTestPath);
    return "";

function readall(oExec)
    if (!oExec.StdOut.AtEndOfStream)
      return oExec.StdOut.ReadAll();

    if (!oExec.StdErr.AtEndOfStream)
      return oExec.StdErr.ReadAll();

    return -1;

function xtract(exec, archive)
    var splitExt = /^(.+)\.(\w+)$/;
    var strTmp = FSO.GetFileName(archive);
    WSH.CurrentDirectory = FSO.GetParentFolderName(archive);
    while(true) {
        var pathParts = splitExt.exec(strTmp);
        if(!pathParts) {
            echo("No extension detected for", strTmp + ".", "Skipping..");

        var ext = pathParts[2].toLowerCase();
        if(!ArchiveExts.contains(ext)) {
            echo("Extension", ext, "not recognized. Skipping.");

        echo("Extracting", strTmp + "..");
        var oExec = WSH.Exec('"' + exec + '" x -bd "' + strTmp + '"');
        var allInput = "";
        var tryCount = 0;

        while (true)
            var input = readall(oExec);
            if (-1 == input) {
                if (tryCount++ > 10 && oExec.Status == 1)
             } else {
                  allInput += input;
                  tryCount = 0;

        if(oExec. ExitCode!= 0) {
            echo("Non-zero return code detected.");


        strTmp = pathParts[1];
    WSH.CurrentDirectory = PWD;

function printUsage()
    echo("Usage:\r\n", __file__, "archive1 [archive2] ...");

function main(args)
    var exe = findExecutable();
        fatal("Could not find 7zip executable.");

    if(!args.length || args(0) == "-h" || args(0) == "--help" || args(0) == "/?")

        var archive = FSO.GetAbsolutePathName(args(i));
        if(!FSO.FileExists(archive)) {
            echo("File", archive, "does not exist. Skipping..");
        xtract(exe, archive);

share|improve this answer
+1 for the @set @junk=1 trick (do you know if it's documented anywhere?) –  hdgarrood Jun 7 '13 at 10:21
Not that I'm aware of. I initially found it in the following source repository: github.com/ynkdir/winscript It works, because the WSH jscript engine apparently ignores the first bit, up until the comment begins. More information can be found at: stackoverflow.com/questions/4999395/… –  juntalis Jun 11 '13 at 1:39
awesome, thanks :) –  hdgarrood Jun 11 '13 at 10:31
found this: javascriptkit.com/javatutors/conditionalcompile2.shtml which seems to indicate that @set @var = value is JScript syntax for declaring compile-time variables. So it's both valid JScript and a CMD command –  hdgarrood Jun 11 '13 at 10:36
add comment

Your Answer


