├── 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 | [](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);
--------------------------------------------------------------------------------