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;
})(this.Object.prototype);
(function(str) {
str.trim = function str_trim() {
return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
};
})(this.String.prototype);
(function(arr) {
arr.contains = function arr_contains(needle) {
for (var i in this) {
if (this[i] == needle) {
return true;
}
}
return false;
}
})(this.Array.prototype);
/* 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 = "";
for (var n = 0; n < arguments.length; n++) {
msg += arguments[n];
msg += " ";
}
if(!emptyStr(msg))
WScript.Echo(msg);
}
function fatal(msg)
{
echo("Fatal Error:", msg);
WScript.Quit(1);
}
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 + ";" +
WSH.ExpandEnvironmentStrings("%PATH%")
).split(";");
for(var i in arrPath) {
// Skip empty directory values, caused by the PATH;
// variable being terminated with a semicolon;
if (arrPath[i] == "")
continue;
// 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..");
break;
}
var ext = pathParts[2].toLowerCase();
if(!ArchiveExts.contains(ext)) {
echo("Extension", ext, "not recognized. Skipping.");
break;
}
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)
break;
WScript.Sleep(100);
} else {
allInput += input;
tryCount = 0;
}
}
if(oExec. ExitCode!= 0) {
echo("Non-zero return code detected.");
break;
}
WScript.Echo(allInput);
strTmp = pathParts[1];
if(!FSO.FileExists(strTmp))
break;
}
WSH.CurrentDirectory = PWD;
}
function printUsage()
{
echo("Usage:\r\n", __file__, "archive1 [archive2] ...");
WScript.Quit(0);
}
function main(args)
{
var exe = findExecutable();
if(emptyStr(exe))
fatal("Could not find 7zip executable.");
if(!args.length || args(0) == "-h" || args(0) == "--help" || args(0) == "/?")
printUsage();
for (var i = 0; i < args.length; i++) {
var archive = FSO.GetAbsolutePathName(args(i));
if(!FSO.FileExists(archive)) {
echo("File", archive, "does not exist. Skipping..");
continue;
}
xtract(exe, archive);
}
echo("\r\nDone.");
}
main(WScript.Arguments.Unnamed);
There is a new answer with the one-step instructions. – Barett – 2018-06-01T02:40:51.173
Is there a solution for users of 7-zip app on Windows OS, using context menu? – android developer – 2018-10-10T07:10:19.903
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 – 2012-10-19T13:18:57.833
73If 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 – 2009-12-07T20:35:43.757
6@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 – 2009-12-07T20:52:17.390
9Note that the "in one step" instructions doesn't actually do it in one step, it actually decompresses the .gz into a temporary folder, then opens the .tar file in 7-zip. When the archives are small enough, it's hardly noticeable, but it's very noticeable on large archives. Just thought that deserved clarification. – naasking – 2013-10-25T18:29:31.940