📄 main.cpp
字号:
// Main.cpp#include "StdAfx.h"#include "Common/MyInitGuid.h"#include "Common/CommandLineParser.h"#include "Common/StdOutStream.h"#include "Common/Wildcard.h"#include "Common/StringConvert.h"#include "Common/MyCom.h"#include "Common/Exception.h"#include "Windows/FileDir.h"#include "Windows/FileName.h"#include "Windows/Defs.h"#include "Windows/System.h"#include "../../IPassword.h"#include "../../ICoder.h"#include "../../UI/Common/OpenArchive.h"#include "../../UI/Common/DefaultName.h"#include "../../UI/Common/ExitCode.h"#include "../../UI/Common/Extract.h"#include "../../UI/Console/List.h"#include "../../UI/Console/OpenCallbackConsole.h"#include "../../UI/Console/ExtractCallbackConsole.h"#include "../../MyVersion.h"using namespace NWindows;using namespace NFile;using namespace NCommandLineParser;extern CStdOutStream *g_StdStream;static const char *kCopyrightString = "\n7-Zip SFX " MY_VERSION_COPYRIGHT_DATE "\n""p7zip Version " P7ZIP_VERSION ;static const int kNumSwitches = 6;#ifdef _WIN32static const wchar_t *kDefaultExt = L".exe";static const int kDefaultExtLength = 4;#endifnamespace NKey {enum Enum{ kHelp1 = 0, kHelp2, kDisablePercents, kYes, kPassword, kOutputDir};}namespace NRecursedType {enum EEnum{ kRecursed, kWildCardOnlyRecursed, kNonRecursed,};}static const char kRecursedIDChar = 'R';static const wchar_t *kRecursedPostCharSet = L"0-";namespace NRecursedPostCharIndex { enum EEnum { kWildCardRecursionOnly = 0, kNoRecursion = 1 };}static const char kFileListID = '@';static const char kImmediateNameID = '!';static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must bestatic const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must bestatic const CSwitchForm kSwitchForms[kNumSwitches] = { { L"?", NSwitchType::kSimple, false }, { L"H", NSwitchType::kSimple, false }, { L"BD", NSwitchType::kSimple, false }, { L"Y", NSwitchType::kSimple, false }, { L"P", NSwitchType::kUnLimitedPostString, false, 1 }, { L"O", NSwitchType::kUnLimitedPostString, false, 1 }, };static const int kNumCommandForms = 3;namespace NCommandType {enum EEnum{ kTest = 0, // kExtract, kFullExtract, kList};}static const CCommandForm commandForms[kNumCommandForms] = { { L"T", false }, // { "E", false }, { L"X", false }, { L"L", false }};static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] = { NRecursedType::kRecursed};static const bool kTestExtractRecursedDefault = true;static const bool kAddRecursedDefault = false;static const int kMaxCmdLineSize = 1000;static const wchar_t *kUniversalWildcard = L"*";static const int kMinNonSwitchWords = 1;static const int kCommandIndex = 0;static const char *kHelpString = "\nUsage: 7zSFX [<command>] [<switches>...]\n" "\n" "<Commands>\n" " l: List contents of archive\n" " t: Test integrity of archive\n" " x: eXtract files with full pathname (default)\n" "<Switches>\n" // " -bd Disable percentage indicator\n" " -o{Directory}: set Output directory\n" " -p{Password}: set Password\n" " -y: assume Yes on all queries\n";// ---------------------------// exception messagesstatic const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserErrorstatic const char *kIncorrectListFile = "Incorrect wildcard in listfile";static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line";// static const CSysString kFileIsNotArchiveMessageBefore = "File \"";// static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive";static const char *kProcessArchiveMessage = " archive: ";static const char *kCantFindSFX = " cannot find sfx";struct CArchiveCommand{ NCommandType::EEnum CommandType; NRecursedType::EEnum DefaultRecursedType() const;};NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const{ return kCommandRecursedDefault[CommandType];}static NRecursedType::EEnum GetRecursedTypeFromIndex(int index){ switch (index) { case NRecursedPostCharIndex::kWildCardRecursionOnly: return NRecursedType::kWildCardOnlyRecursed; case NRecursedPostCharIndex::kNoRecursion: return NRecursedType::kNonRecursed; default: return NRecursedType::kRecursed; }}void PrintHelp(void){ g_StdOut << kHelpString;}static void ShowMessageAndThrowException(const char *message, NExitCode::EEnum code){ g_StdOut << message << endl; throw code;}static void PrintHelpAndExit() // yyy{ PrintHelp(); ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError);}static void PrintProcessTitle(const CSysString &processTitle, const UString &archiveName){ g_StdOut << endl << processTitle << kProcessArchiveMessage << archiveName << endl << endl;}bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command){ UString commandStringUpper = commandString; commandStringUpper.MakeUpper(); UString postString; int commandIndex = ParseCommand(kNumCommandForms, commandForms, commandStringUpper, postString) ; if (commandIndex < 0) return false; command.CommandType = (NCommandType::EEnum)commandIndex; return true;}// ------------------------------------------------------------------// filenames functionsstatic bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, const UString &name, bool include, NRecursedType::EEnum type){ /* if(!IsWildCardFilePathLegal(name)) return false; */ bool isWildCard = DoesNameContainWildCard(name); bool recursed; switch (type) { case NRecursedType::kWildCardOnlyRecursed: recursed = isWildCard; break; case NRecursedType::kRecursed: recursed = true; break; case NRecursedType::kNonRecursed: recursed = false; break; } wildcardCensor.AddItem(include, name, recursed); return true;}void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor, const UString &name, bool include, NRecursedType::EEnum type){ if (!AddNameToCensor(wildcardCensor, name, include, type)) ShowMessageAndThrowException(kIncorrectWildCardInCommandLine, NExitCode::kUserError);}static bool AreEqualNoCase(wchar_t c1, wchar_t c2){ return ::MyCharUpper(c1) == ::MyCharUpper(c2);}void AddToCensorFromNonSwitchesStrings(NWildcard::CCensor &wildcardCensor, const UStringVector &nonSwitchStrings, NRecursedType::EEnum type, bool thereAreSwitchIncludeWildCards){ AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type);}/*void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor, const UStringVector &strings, bool include, NRecursedType::EEnum commonRecursedType){ for(int i = 0; i < strings.Size(); i++) { const UString &string = strings[i]; NRecursedType::EEnum recursedType; int pos = 0; if (string.Length() < kSomeCludePostStringMinSize) PrintHelpAndExit(); if (AreEqualNoCase(string[pos], kRecursedIDChar)) { pos++; int index = UString(kRecursedPostCharSet).Find(string[pos]); recursedType = GetRecursedTypeFromIndex(index); if (index >= 0) pos++; } else recursedType = commonRecursedType; if (string.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize) PrintHelpAndExit(); UString tail = string.Mid(pos + 1); if (AreEqualNoCase(string[pos], kImmediateNameID)) AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType); else PrintHelpAndExit(); }}*/// ------------------------------------------------------------------/*static void ThrowPrintFileIsNotArchiveException(const CSysString &fileName){ CSysString message; message = kFileIsNotArchiveMessageBefore + fileName + kFileIsNotArchiveMessageAfter; ShowMessageAndThrowException(message, NExitCode::kFileIsNotArchive);}*/int Main2( #ifndef _WIN32 int numArguments, const char *arguments[] #endif){ #ifdef _WIN32 SetFileApisToOEM(); #endif UStringVector commandStrings; #ifdef _WIN32 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); #else extern void mySplitCommandLine(int numArguments,const char *arguments[],UStringVector &parts); mySplitCommandLine(numArguments,arguments,commandStrings); #endif // After mySplitCommandLine g_StdOut << kCopyrightString << " (locale=" << my_getlocale() <<",Utf16="; if (global_use_utf16_conversion) g_StdOut << "on"; else g_StdOut << "off"; g_StdOut << ",HugeFiles="; if (sizeof(off_t) >= 8) g_StdOut << "on,"; else g_StdOut << "off,"; int nbcpu = NWindows::NSystem::GetNumberOfProcessors(); if (nbcpu > 1) g_StdOut << nbcpu << " CPUs)\n"; else g_StdOut << nbcpu << " CPU)\n"; UString archiveName = commandStrings.Front(); commandStrings.Delete(0); NCommandLineParser::CParser parser(kNumSwitches); try { parser.ParseStrings(kSwitchForms, commandStrings); } catch(...) { PrintHelpAndExit(); } if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) { PrintHelp(); return 0; } const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; int numNonSwitchStrings = nonSwitchStrings.Size(); CArchiveCommand command; if (numNonSwitchStrings == 0) command.CommandType = NCommandType::kFullExtract; else { if (numNonSwitchStrings > 1) PrintHelpAndExit(); if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command)) PrintHelpAndExit(); } NRecursedType::EEnum recursedType; recursedType = command.DefaultRecursedType(); NWildcard::CCensor wildcardCensor; bool thereAreSwitchIncludeWildCards; thereAreSwitchIncludeWildCards = false; AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType, thereAreSwitchIncludeWildCards); bool yesToAll = parser[NKey::kYes].ThereIs; #ifdef _WIN32 if (archiveName.Right(kDefaultExtLength).CompareNoCase(kDefaultExt) != 0) archiveName += kDefaultExt; #endif // NExtractMode::EEnum extractMode; // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); bool passwordEnabled = parser[NKey::kPassword].ThereIs; UString password; if(passwordEnabled) password = parser[NKey::kPassword].PostStrings[0]; NFind::CFileInfoW archiveFileInfo; if (!NFind::FindFile(archiveName, archiveFileInfo)) throw kCantFindSFX; if (archiveFileInfo.IsDirectory()) throw kCantFindSFX; UString outputDir; if(parser[NKey::kOutputDir].ThereIs) { outputDir = parser[NKey::kOutputDir].PostStrings[0]; NName::NormalizeDirPathPrefix(outputDir); } { UStringVector v1, v2; v1.Add(archiveName); v2.Add(archiveName); const NWildcard::CCensorNode &wildcardCensorHead = wildcardCensor.Pairs.Front().Head; if(command.CommandType != NCommandType::kList) { CExtractCallbackConsole *ecs = new CExtractCallbackConsole; CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; ecs->OutStream = g_StdStream; ecs->PasswordIsDefined = passwordEnabled; ecs->Password = password; ecs->Init(); COpenCallbackConsole openCallback; openCallback.OutStream = g_StdStream; openCallback.PasswordIsDefined = passwordEnabled; openCallback.Password = password; CExtractOptions eo; eo.StdOutMode = false; eo.PathMode = NExtract::NPathMode::kFullPathnames; eo.TestMode = command.CommandType == NCommandType::kTest; eo.OverwriteMode = yesToAll ? NExtract::NOverwriteMode::kWithoutPrompt : NExtract::NOverwriteMode::kAskBefore; eo.OutputDir = outputDir; eo.YesToAll = yesToAll; HRESULT result = DecompressArchives( v1, v2, wildcardCensorHead, eo, &openCallback, ecs); if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0) { if (ecs->NumArchiveErrors != 0) (*g_StdStream) << endl << "Archive Errors: " << ecs->NumArchiveErrors << endl; if (ecs->NumFileErrors != 0) (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl; return NExitCode::kFatalError; } if (result != S_OK) throw CSystemException(result); } else { HRESULT result = ListArchives( v1, v2, wildcardCensorHead, true, false, passwordEnabled, password); if (result != S_OK) throw CSystemException(result); } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -