├── LICENSE ├── README.md ├── SolZipper.sln └── SolZipper ├── SolZipper.cpp ├── SolZipper.rc ├── SolZipper.vcxproj ├── SolZipper.vcxproj.filters ├── gh.ico ├── main.cpp ├── pch.cpp ├── pch.h ├── resource.h └── solzipper.h /LICENSE: -------------------------------------------------------------------------------- 1 | GuidedHacking.com Source Available License 2 | Version 1, 05-14-2025 3 | 4 | Disclaimer: 5 | This project contains code developed and published by Guided Hacking LLC. 6 | GuidedHacking® sells educational content including source codes like this. 7 | 8 | GuidedHacking® - The Game Hacking Bible® - © 2025 Guided Hacking LLC. All Rights Reserved. 9 | 10 | Licensed Materials: 11 | Source code, compiled binaries, documentation, image and video assets, including original, modified or derivative versions. 12 | 13 | Limited Use License: 14 | 1. You may use these materials only in non-commercial private, personal projects. 15 | 2. Distribution of these materials in any form, including compiled, modified, or derivative works is not permitted. 16 | 17 | This software is provided AS IS without any warranties, express or implied, and Guided Hacking LLC is not liable for any damages arising from the use of these materials. 18 | 19 | Any rights not expressly granted by the license are reserved by Guided Hacking LLC. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SolZipper - Visual Studio Solution Archiver 2 | Version 1.0 3 | 4 | ## What does this do? 5 | 6 | - Quickly zips up VS projects without the unnecessary bloat files 7 | - Adds Right Click Context Menu to Folders to Zip up Projects 8 | - You can also Drag & Drop your VS project onto the .exe 9 | 10 | ## Video Demo 11 | [![SolZipper Demo Video](http://img.youtube.com/vi/LDdOMEZz4Ik/0.jpg)](https://youtu.be/LDdOMEZz4Ik "SolZipper Demo") 12 | 13 | ## Why? 14 | 15 | Posting Visual Studio projects on forums in zips makes helping people 100% faster/easier than them pasting their code into the post. 16 | 17 | VS projects have lots of bloat and newbies don't understand what files we need so forums get bloated with worthless 100mb attachments. 18 | 19 | I wanted to do something with std::filesystem and encourage people to post entire projects that are easy to debug. 20 | 21 | ## Usage 22 | 23 | Run the exe, you have 3 basic options: 24 | 1. Install it, including the context menu handler 25 | 2. Uninstall it 26 | 3. Zip the folder 27 | 28 | You can use the right click menu or you can drag and drop your solution folder onto the .exe 29 | 30 | ## How does it work? 31 | It uses a blacklist of bad folder names and extensions similar to .gitignore. It copies the good files to a temp folder. Then it uses Powershell to zip the folder. 32 | 33 | ## Requirements 34 | - Visual C++ Redistributables 35 | - Powershell 36 | 37 | More info & release build @ https://guidedhacking.com/resources/solzipper-easily-zip-visual-studio-projects-for-uploading.21/ 38 | 39 | ## TODO 40 | * Replace powershell with actual zipping lib 41 | * Remove ghetto exclusion filter method 42 | * Fix exclusion false positives 43 | 44 | ## Development History 45 | Developed version 1.0 46 | 47 |

Official GH Courses

48 | 60 | 61 | GuidedHacking® - The Game Hacking Bible® - © 2025 Guided Hacking LLC. All Rights Reserved. 62 | -------------------------------------------------------------------------------- /SolZipper.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.106 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SolZipper", "SolZipper\SolZipper.vcxproj", "{A7CCDF4D-5F9D-43C9-941E-038BCD9D2A27}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {A7CCDF4D-5F9D-43C9-941E-038BCD9D2A27}.Debug|x64.ActiveCfg = Debug|x64 17 | {A7CCDF4D-5F9D-43C9-941E-038BCD9D2A27}.Debug|x64.Build.0 = Debug|x64 18 | {A7CCDF4D-5F9D-43C9-941E-038BCD9D2A27}.Debug|x86.ActiveCfg = Debug|Win32 19 | {A7CCDF4D-5F9D-43C9-941E-038BCD9D2A27}.Debug|x86.Build.0 = Debug|Win32 20 | {A7CCDF4D-5F9D-43C9-941E-038BCD9D2A27}.Release|x64.ActiveCfg = Release|x64 21 | {A7CCDF4D-5F9D-43C9-941E-038BCD9D2A27}.Release|x64.Build.0 = Release|x64 22 | {A7CCDF4D-5F9D-43C9-941E-038BCD9D2A27}.Release|x86.ActiveCfg = Release|Win32 23 | {A7CCDF4D-5F9D-43C9-941E-038BCD9D2A27}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {DBF22D66-E755-4C63-B1FE-1316C817D3FA} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /SolZipper/SolZipper.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "solzipper.h" 3 | 4 | void PrintMenu(fs::path dropped) 5 | { 6 | std::cout << "__...---=== SolZipper ===---...__\n"; 7 | std::cout << "| |\n"; 8 | std::cout << "| Drop solution on exe to zip |\n"; 9 | std::cout << "| Or Install & Right Click |\n"; 10 | std::cout << "| |\n"; 11 | std::cout << "| 1. Install |\n"; 12 | std::cout << "| 2. Uninstall |\n"; 13 | if (!dropped.empty()) 14 | { 15 | std::cout << "| 3. Zip it up |\n"; 16 | } 17 | else 18 | { 19 | std::cout << "| |\n"; 20 | } 21 | std::cout << "| 4. Exit |\n"; 22 | std::cout << "| |\n"; 23 | std::cout << "| Input Selection |\n"; 24 | std::cout << "|===============================|\n\n"; 25 | } 26 | 27 | void CopyRecursive(fs::path src, fs::path dst) 28 | { 29 | //Loop through all the dirs 30 | for (auto dir : fs::recursive_directory_iterator(src)) 31 | { 32 | //copy the path's string to store relative path string 33 | std::wstring relstr = dir.path().wstring(); 34 | 35 | //remove the substring matching the src path 36 | //this leaves only the relative path 37 | relstr.erase(0, src.wstring().size()); 38 | 39 | //combine the destination root path with relative path 40 | fs::path newFullPath = dst / relstr; 41 | 42 | //Create dir if it's a dir 43 | if (fs::is_directory(newFullPath)) 44 | { 45 | fs::create_directory(newFullPath); 46 | } 47 | 48 | //copy the files 49 | fs::copy(dir.path(), newFullPath, fs::copy_options::recursive | fs::copy_options::overwrite_existing); 50 | } 51 | } 52 | 53 | bool IsBadDir(fs::path path) 54 | { 55 | if (fs::is_directory(path)) 56 | { 57 | for (auto b : badFolders) 58 | { 59 | if (b == path.filename()) 60 | { 61 | return true; 62 | } 63 | } 64 | } 65 | return false; 66 | } 67 | 68 | bool IsBadPath(fs::path path) 69 | { 70 | if (!path.extension().empty()) 71 | { 72 | for (auto b : badExtensions) 73 | { 74 | if (b == path.extension()) 75 | { 76 | return true; 77 | } 78 | } 79 | } 80 | return false; 81 | } 82 | 83 | void CopyGoodFiles(fs::path src, fs::path dst) 84 | { 85 | std::vector badPaths; 86 | 87 | //Loop through all the dirs 88 | for (auto dir : fs::recursive_directory_iterator(src)) 89 | { 90 | if (dir.path().wstring().find(L".suo") != std::string::npos) 91 | { 92 | int x = 69; 93 | } 94 | 95 | //log all bad paths 96 | if (IsBadDir(dir.path()) || IsBadPath(dir.path())) 97 | { 98 | badPaths.push_back(dir.path()); 99 | continue; 100 | } 101 | } 102 | 103 | for (auto dir : fs::recursive_directory_iterator(src)) 104 | { 105 | bool bBadPath = false; 106 | 107 | //if path matches a logged bad path, skip 108 | for (auto bad : badPaths) 109 | { 110 | if (dir.path().wstring().find(L".suo") != std::string::npos) 111 | { 112 | int x = 69; 113 | } 114 | 115 | if (dir.path().wstring().find(bad) != std::string::npos) 116 | { 117 | bBadPath = true; 118 | break; 119 | } 120 | } 121 | 122 | if (!bBadPath) 123 | { 124 | //copy the path's string to store relative path string 125 | std::wstring relstr = dir.path().wstring(); 126 | 127 | //remove the substring matching the src path 128 | //this leaves only the relative path 129 | relstr.erase(0, src.wstring().size()); 130 | 131 | //combine the destination root path with relative path 132 | fs::path newFullPath = dst / relstr; 133 | 134 | //Create dir if it's a dir 135 | if (fs::is_directory(dir.path())) 136 | { 137 | fs::create_directory(newFullPath); 138 | continue; 139 | } 140 | 141 | //copy the files one at a time. If done recursively it'll copy bad sub paths 142 | fs::copy(dir.path(), newFullPath, fs::copy_options::overwrite_existing); 143 | } 144 | } 145 | } 146 | 147 | void ZipItUp(fs::path path) 148 | { 149 | if (path.empty()) { ShellExecute(0, 0, L"https://bit.ly/2Sa5Krt", 0, 0, SW_SHOW); return; } 150 | 151 | //Get solution parent path 152 | auto solParent = path.parent_path(); 153 | 154 | //Create temp folder to store files to keep 155 | wchar_t randfolder[L_tmpnam_s]; 156 | auto err = _wtmpnam_s(randfolder, L_tmpnam_s); 157 | 158 | //randomfolder\SolutionName 159 | fs::path randfolderFull = fs::path(randfolder) / fs::path(path.filename()); 160 | 161 | //Create random temp folder & the subfolder with the solution name 162 | fs::create_directory(randfolder); 163 | fs::create_directory(randfolderFull); 164 | 165 | CopyGoodFiles(path, randfolderFull); 166 | 167 | UnHideFiles(randfolderFull); //Compress-Archive skips them if they're hidden 168 | 169 | std::wstring cmd = LR"(powershell.exe Compress-Archive -Force -path ')" + randfolderFull.wstring() + LR"(' -DestinationPath ')" + path.wstring() + LR"(.zip')"; 170 | 171 | //convert cmd string to work in console and exec it 172 | //std::string smbcmd = ws2s(cmd); // 173 | _wsystem(cmd.c_str()); 174 | 175 | fs::remove_all(randfolder); //delete temp folder 176 | std::cout << "SolZip Completed\n"; 177 | } 178 | 179 | void Install(fs::path thisExe) 180 | { 181 | //copy to program files 182 | fs::create_directories(installPath); 183 | 184 | try 185 | { 186 | fs::copy_file(thisExe, file, fs::copy_options::overwrite_existing); 187 | } 188 | catch (fs::filesystem_error& e) 189 | { 190 | std::cout << "Error Could not " << e.what() << '\n'; 191 | return; 192 | } 193 | 194 | //Add context menu handler 195 | HKEY result; 196 | DWORD result2; 197 | RegCreateKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Folder\\shell\\SolZipper\\", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &result, &result2); 198 | RegSetValue(result, 0, REG_SZ, L"SolZip", 0); 199 | RegCreateKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Folder\\shell\\SolZipper\\command", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &result, &result2); 200 | RegSetValue(result, 0, REG_SZ, cmd.c_str(), 0); 201 | std::cout << "Installed\n"; 202 | } 203 | 204 | void Uninstall() 205 | { 206 | //remove context menu handler 207 | RegDeleteKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Folder\\shell\\SolZipper\\command", KEY_WOW64_32KEY, 0); 208 | RegDeleteKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Folder\\shell\\SolZipper", KEY_WOW64_32KEY, 0); 209 | //schedule file deletion 210 | MoveFileEx(file.c_str(), 0, MOVEFILE_DELAY_UNTIL_REBOOT); 211 | MoveFileEx(installPath.c_str(), 0, MOVEFILE_DELAY_UNTIL_REBOOT); 212 | std::cout << "You must reboot to complete uninstallation\n"; 213 | } 214 | 215 | void UnHideFiles(fs::path path) 216 | { 217 | for (auto dir : fs::recursive_directory_iterator(path)) 218 | { 219 | //Unhiding the file 220 | int attr = GetFileAttributes(dir.path().c_str()); 221 | if ((attr & FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN) 222 | { 223 | SetFileAttributes(dir.path().c_str(), attr & ~FILE_ATTRIBUTE_HIDDEN); 224 | } 225 | } 226 | } -------------------------------------------------------------------------------- /SolZipper/SolZipper.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guidedhacking/SolZipper/86235a2dc9619967f0007edf4dc0b9f661a7508c/SolZipper/SolZipper.rc -------------------------------------------------------------------------------- /SolZipper/SolZipper.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {A7CCDF4D-5F9D-43C9-941E-038BCD9D2A27} 24 | Win32Proj 25 | SolZipper 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | false 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | true 91 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 92 | true 93 | pch.h 94 | stdcpp17 95 | 96 | 97 | Console 98 | true 99 | RequireAdministrator 100 | 101 | 102 | 103 | 104 | Use 105 | Level3 106 | Disabled 107 | true 108 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 109 | true 110 | pch.h 111 | stdcpp17 112 | 113 | 114 | Console 115 | true 116 | 117 | 118 | 119 | 120 | Use 121 | Level3 122 | MaxSpeed 123 | true 124 | true 125 | true 126 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 127 | true 128 | pch.h 129 | stdcpp17 130 | 131 | 132 | Console 133 | true 134 | true 135 | true 136 | RequireAdministrator 137 | 138 | 139 | 140 | 141 | Use 142 | Level3 143 | MaxSpeed 144 | true 145 | true 146 | true 147 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 148 | true 149 | pch.h 150 | stdcpp17 151 | 152 | 153 | Console 154 | true 155 | true 156 | true 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | Create 167 | Create 168 | Create 169 | Create 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /SolZipper/SolZipper.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8cb310a8-66a7-4206-a202-21da1bc24675} 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | solzipper 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | solzipper 37 | 38 | 39 | Header Files 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | Resource Files 48 | 49 | 50 | 51 | 52 | Resource Files 53 | 54 | 55 | -------------------------------------------------------------------------------- /SolZipper/gh.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guidedhacking/SolZipper/86235a2dc9619967f0007edf4dc0b9f661a7508c/SolZipper/gh.ico -------------------------------------------------------------------------------- /SolZipper/main.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "solzipper.h" 3 | 4 | fs::path dropped; 5 | fs::path thisExe; 6 | 7 | int wmain(int argc, wchar_t* argv[]) 8 | { 9 | //Get Path of this process 10 | thisExe = fs::path(argv[0]); 11 | 12 | fs::path dropped; 13 | dropped.clear(); 14 | 15 | if (argv[1]) 16 | { 17 | dropped = fs::path(argv[1]); 18 | } 19 | //put test project here if running from debugger 20 | //else dropped = L"F:\\Projects\\ACHack Framework"; 21 | 22 | while (1) 23 | { 24 | PrintMenu(dropped); 25 | 26 | int x = 0; 27 | 28 | while (1) 29 | { 30 | std::cin >> x; 31 | 32 | if (x < 5 && x > 0) 33 | { 34 | switch (x) 35 | { 36 | case 1: 37 | { 38 | Install(thisExe); system("cls"); PrintMenu(dropped); std::cout << "\nInstalled \n\nInput Next Selection\n\n"; break; 39 | } 40 | case 2: 41 | { 42 | Uninstall(); system("cls"); PrintMenu(dropped); std::cout << "\nUninstalled \n\nInput Next Selection\n\n"; break; 43 | } 44 | case 3: 45 | { 46 | ZipItUp(dropped); system("cls"); PrintMenu(dropped); std::cout << "\nZipping complete! \n\nInput Next Selection\n\n"; break; 47 | } 48 | case 4: exit(0); 49 | default: break; 50 | } 51 | } 52 | 53 | else 54 | { 55 | system("cls"); PrintMenu(dropped); std::cout << "Invalid input. Try again\n\n"; 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /SolZipper/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed 2 | 3 | #include "pch.h" 4 | 5 | // In general, ignore this file, but keep it around if you are using pre-compiled headers. -------------------------------------------------------------------------------- /SolZipper/pch.h: -------------------------------------------------------------------------------- 1 | // Tips for Getting Started: 2 | // 1. Use the Solution Explorer window to add/manage files 3 | // 2. Use the Team Explorer window to connect to source control 4 | // 3. Use the Output window to see build output and other messages 5 | // 4. Use the Error List window to view errors 6 | // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project 7 | // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file 8 | 9 | #ifndef PCH_H 10 | #define PCH_H 11 | 12 | // TODO: add headers that you want to pre-compile here 13 | #include 14 | #include 15 | #include 16 | #include 17 | #endif //PCH_H 18 | -------------------------------------------------------------------------------- /SolZipper/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by SolZipper.rc 4 | // 5 | #define IDI_ICON1 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /SolZipper/solzipper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pch.h" 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | const std::wstring badFolders[] = { L"Release", L"Debug", L"ipch", L"x64", L"x86", L"Obj", L"Releases", L"Bin", L"Log", L"IPCH", L".git", L"bin", L"obj", L"Server" }; 8 | const std::wstring badExtensions[] = { L".db", L".pch", L".obj", L".pdb", L".tmp", L".opendb", L".opensdf", L".VC", L".zip", L".exe", L".dll", L".sqlite", L".json" }; 9 | const std::wstring badFilenames[] = { L"Browse.VC.db" }; 10 | 11 | const fs::path installPath = "C:\\Program Files (x86)\\SolZipper"; 12 | const fs::path file = "C:\\Program Files (x86)\\SolZipper\\SolZipper.exe"; 13 | const std::wstring cmd = LR"(C:\Program Files (x86)\SolZipper\SolZipper.exe "%1")"; 14 | 15 | void PrintMenu(fs::path dropped); 16 | 17 | void CopyRecursive(fs::path src, fs::path dst); 18 | 19 | bool IsBadDir(fs::path path); 20 | 21 | bool IsBadPath(fs::path path); 22 | 23 | void CopyGoodFiles(fs::path src, fs::path dst); 24 | 25 | void ZipItUp(fs::path path); 26 | 27 | void Install(fs::path thisExe); 28 | 29 | void Uninstall(); 30 | 31 | void UnHideFiles(fs::path path); --------------------------------------------------------------------------------