Skip to content

Commit ae6b53c

Browse files
update to branch
1 parent b46ae5f commit ae6b53c

File tree

12 files changed

+1458
-0
lines changed

12 files changed

+1458
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
FLEXINSTALLER - ALL-IN-ONE INSTALLER v3.0
2+
=========================================
3+
4+
STEP 1: CONFIGURE YOUR APP
5+
- Edit Config.cs with your app details
6+
- Set your Dropbox download URL
7+
- Customize messages, paths, and options
8+
9+
STEP 2: BUILD INSTALLER
10+
- Run build.bat
11+
- Enter output filename
12+
- .exe file created in output\ folder
13+
14+
STEP 3: DISTRIBUTE
15+
- Just share the .exe file!
16+
17+
DROPBOX SETUP:
18+
1. Go to https://www.dropbox.com/developers/apps
19+
2. Create new app
20+
3. Upload your program file
21+
4. Get direct download link (replace "?dl=0" at the end with "?dl=1" to share URL) !!!VERY IMPORTANT OR IT WONT WORK!!!
22+
5. Put the URL into config
23+
24+
HOW IT WORKS:
25+
- Single .exe contains both installer and uninstaller
26+
- During installation, copies itself as "uninstall.exe"
27+
- Windows Add/Remove Programs points to uninstall.exe
28+
- When uninstall.exe runs it detects its an uninstaller and shows uninstall GUI
29+
- Completely removes app, shortcuts registry entries, and itself

FlexInstaller/Config.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
3+
namespace FlexInstaller
4+
{
5+
public static class AppConfig
6+
{
7+
public static string appName="Sample App";
8+
public static string appVer="1.0.0";
9+
public static string pubName="Your Company Name";
10+
public static string dlUrl="https://www.dropbox.com/scl/fi/TESTURL123?dl=1";
11+
public static string instPath=@"C:\Program Files\Sample Application";
12+
public static string exeName="app.exe";
13+
public static bool showLicense=true;
14+
public static bool createDesktop=true;
15+
public static bool createStartMenu=true;
16+
public static bool runAfter=true;
17+
public static string welcomeMsg="Welcome to the installation wizard!";
18+
public static string licenseText=@"
19+
END USER LICENSE AGREEMENT
20+
21+
This software is provided 'as is' without warranty of any kind.
22+
By installing this software, you agree to these terms and conditions.
23+
24+
1. You may install and use this software on your computer.
25+
2. You may not redistribute this software without permission.
26+
3. The publisher is not liable for any damages caused by this software.
27+
28+
Do you accept these terms?";
29+
public static string completeMsg="Installation completed successfully!";
30+
public static bool requireAdmin=true;
31+
public static string supportUrl="https://support.example.com";
32+
public static string website="https://example.com";
33+
}
34+
}

FlexInstaller/LICENSE

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FlexInstaller License
2+
3+
Copyright (c) 2025 iamsopotatoe
4+
5+
Permission is hereby granted to use this software for personal and commercial purposes, subject to the following restrictions:
6+
7+
PERMITTED:
8+
- Use the software to create installers for your own applications
9+
- Distribute installers created with this software
10+
- Study the source code for educational purposes
11+
12+
PROHIBITED:
13+
- Modifying, adapting, or creating derivative works of this source code
14+
- Redistributing, selling, or sublicensing this source code or modified versions
15+
- Removing or modifying copyright notices
16+
- Using this software to create competing installer tools
17+
18+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

FlexInstaller/build.bat

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
@echo off
2+
cls
3+
echo FLEXINSTALLER BUILDER v3.0
4+
echo ============================
5+
6+
set /p OUTPUT_NAME=Filename:
7+
if "%OUTPUT_NAME%"=="" set OUTPUT_NAME=Installer
8+
9+
for %%I in (csc.exe) do set CSC_PATH=%%~$PATH:I
10+
if "%CSC_PATH%"=="" (
11+
for /d %%F in (C:\Windows\Microsoft.NET\Framework*) do (
12+
for /d %%V in (%%F\v*) do (
13+
if exist "%%V\csc.exe" set CSC_PATH=%%V\csc.exe
14+
)
15+
)
16+
)
17+
18+
if not exist "%CSC_PATH%" (
19+
echo ERROR: C# compiler not found!
20+
echo.
21+
echo Download Microsoft Build Tools:
22+
echo https://aka.ms/vs/17/release/vs_buildtools.exe
23+
echo.
24+
echo Or install Visual Studio Community (free^):
25+
echo https://visualstudio.microsoft.com/downloads/
26+
goto :end
27+
)
28+
29+
echo Building %OUTPUT_NAME%.exe...
30+
if not exist output mkdir output
31+
32+
"%CSC_PATH%" /target:winexe /out:output\%OUTPUT_NAME%.exe /win32icon:src\installer.ico /reference:System.dll /reference:System.Core.dll /reference:System.Drawing.dll /reference:System.Windows.Forms.dll /reference:System.Net.Http.dll src\Program.cs src\MainForm.cs src\DownloadManager.cs src\InstallationManager.cs src\UninstallerForm.cs Config.cs >nul 2>&1
33+
34+
if exist output\%OUTPUT_NAME%.exe (
35+
echo BUILD SUCCESS: output\%OUTPUT_NAME%.exe
36+
for %%A in (output\%OUTPUT_NAME%.exe) do echo Size: %%~zA bytes
37+
) else (
38+
echo BUILD FAILED - Check your Config.cs file
39+
)
40+
41+
:end
42+
pause
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System;
2+
using System.IO;
3+
using System.Net;
4+
using System.Net.Security;
5+
using System.Threading.Tasks;
6+
using System.Windows.Forms;
7+
using System.ComponentModel;
8+
9+
namespace FlexInstaller {
10+
public class FileTransferManager
11+
{
12+
private ProgressBar barProgress;
13+
private Label txtStatus;
14+
private WebClient client;
15+
private bool finished;
16+
private bool worked;
17+
18+
public FileTransferManager(ProgressBar progress,Label status) {
19+
barProgress=progress;
20+
txtStatus=status;
21+
}
22+
23+
public async Task<bool> RetrieveFileFromCloud(string webUrl,string localFile)
24+
{
25+
try {
26+
if(string.IsNullOrEmpty(webUrl)||!Uri.IsWellFormedUriString(webUrl,UriKind.Absolute)) {
27+
txtStatus.Text="Invalid download URL";
28+
return false;
29+
}
30+
31+
txtStatus.Text="Connecting to download server...";
32+
Application.DoEvents();
33+
34+
ServicePointManager.SecurityProtocol=(SecurityProtocolType)3072|(SecurityProtocolType)768|(SecurityProtocolType)192;
35+
ServicePointManager.ServerCertificateValidationCallback=delegate{return true;};
36+
37+
client=new WebClient();
38+
client.Headers.Add("User-Agent",AppConfig.appName+" Installer v"+AppConfig.appVer);
39+
40+
finished=false;
41+
worked=false;
42+
43+
client.DownloadProgressChanged+=(sender,e)=> {
44+
barProgress.Value=e.ProgressPercentage;
45+
txtStatus.Text=string.Format("Downloading... {0}% ({1:F1} MB of {2:F1} MB)",
46+
e.ProgressPercentage,
47+
e.BytesReceived/1024.0/1024.0,
48+
e.TotalBytesToReceive/1024.0/1024.0);
49+
Application.DoEvents();
50+
};
51+
52+
client.DownloadFileCompleted+=(sender,e)=> {
53+
finished=true;
54+
if(e.Error!=null) {
55+
txtStatus.Text=string.Format("Download failed: {0}",e.Error.Message);
56+
worked=false;
57+
} else if(e.Cancelled) {
58+
txtStatus.Text="Download was cancelled";
59+
worked=false;
60+
} else {
61+
txtStatus.Text="Download completed successfully";
62+
worked=true;
63+
}
64+
};
65+
66+
client.DownloadFileAsync(new Uri(webUrl),localFile);
67+
68+
while(!finished) {
69+
await Task.Delay(100);
70+
Application.DoEvents();
71+
}
72+
73+
client.Dispose();
74+
return worked;
75+
} catch(Exception ex) {
76+
txtStatus.Text=string.Format("Download error: {0}",ex.Message);
77+
if(client!=null) {
78+
client.Dispose();
79+
}
80+
return false;
81+
}
82+
}
83+
84+
public static void Dispose() {
85+
}
86+
}
87+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
using System;
2+
using System.IO;
3+
using System.Diagnostics;
4+
using System.Windows.Forms;
5+
using Microsoft.Win32;
6+
7+
namespace FlexInstaller
8+
{
9+
public class SetupManager
10+
{
11+
private string temporaryFilePath;
12+
private string finalInstallLocation;
13+
14+
public SetupManager()
15+
{
16+
temporaryFilePath = Path.Combine(Path.GetTempPath(), AppConfig.exeName);
17+
finalInstallLocation = Path.Combine(AppConfig.instPath, AppConfig.exeName);
18+
}
19+
20+
public bool CreateDirectoryStructure()
21+
{
22+
try
23+
{
24+
if (!Directory.Exists(AppConfig.instPath))
25+
{
26+
Directory.CreateDirectory(AppConfig.instPath);
27+
}
28+
return true;
29+
}
30+
catch (Exception ex)
31+
{
32+
MessageBox.Show(string.Format("Failed to create installation directory: {0}", ex.Message), "Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
33+
return false;
34+
}
35+
}
36+
37+
public bool InstallApplication(string downloadedFile)
38+
{
39+
try
40+
{
41+
if (!File.Exists(downloadedFile))
42+
{
43+
MessageBox.Show("Downloaded file not found.", "Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
44+
return false;
45+
}
46+
47+
FileInfo fileInfo = new FileInfo(downloadedFile);
48+
if (fileInfo.Length < 1024)
49+
{
50+
MessageBox.Show("Downloaded file appears to be invalid or corrupted.", "Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
51+
return false;
52+
}
53+
if (File.Exists(finalInstallLocation))
54+
{
55+
try
56+
{
57+
File.Delete(finalInstallLocation);
58+
}
59+
catch
60+
{
61+
MessageBox.Show("Cannot overwrite existing installation. Please close " + AppConfig.appName + " and try again.", "File In Use", MessageBoxButtons.OK, MessageBoxIcon.Warning);
62+
return false;
63+
}
64+
}
65+
66+
File.Move(downloadedFile, finalInstallLocation);
67+
68+
CreateUninstaller();
69+
70+
if (AppConfig.createStartMenu)
71+
{
72+
CreateStartMenuLink();
73+
}
74+
75+
RegisterInControlPanel();
76+
return true;
77+
}
78+
catch (Exception ex)
79+
{
80+
MessageBox.Show(string.Format("Installation failed: {0}", ex.Message), "Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
81+
return false;
82+
}
83+
}
84+
85+
public void CreateDesktopShortcutManual()
86+
{
87+
try
88+
{
89+
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
90+
string shortcutPath = Path.Combine(desktopPath, AppConfig.appName + ".lnk");
91+
92+
if (File.Exists(shortcutPath))
93+
{
94+
File.Delete(shortcutPath);
95+
}
96+
97+
ProcessStartInfo psi = new ProcessStartInfo();
98+
psi.FileName = "powershell.exe";
99+
psi.Arguments = string.Format("-Command \"$WshShell = New-Object -comObject WScript.Shell; $Shortcut = $WshShell.CreateShortcut('{0}'); $Shortcut.TargetPath = '{1}'; $Shortcut.WorkingDirectory = '{2}'; $Shortcut.Save()\"",
100+
shortcutPath, finalInstallLocation, AppConfig.instPath);
101+
psi.WindowStyle = ProcessWindowStyle.Hidden;
102+
psi.CreateNoWindow = true;
103+
Process.Start(psi).WaitForExit();
104+
}
105+
catch
106+
{
107+
}
108+
}
109+
110+
private void CreateDesktopLink()
111+
{
112+
}
113+
114+
private void CreateStartMenuLink()
115+
{
116+
}
117+
118+
private void CreateUninstaller()
119+
{
120+
try
121+
{
122+
string uninstallerPath = Path.Combine(AppConfig.instPath, "uninstall.exe");
123+
124+
File.Copy(Application.ExecutablePath, uninstallerPath, true);
125+
}
126+
catch
127+
{
128+
}
129+
}
130+
131+
private void RegisterInControlPanel()
132+
{
133+
try
134+
{
135+
string uninstallKey = string.Format(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0}", AppConfig.appName);
136+
string uninstallerPath = Path.Combine(AppConfig.instPath, "uninstall.exe");
137+
138+
using (RegistryKey key = Registry.LocalMachine.CreateSubKey(uninstallKey))
139+
{
140+
key.SetValue("DisplayName", AppConfig.appName);
141+
key.SetValue("DisplayVersion", AppConfig.appVer);
142+
key.SetValue("Publisher", AppConfig.pubName);
143+
key.SetValue("InstallLocation", AppConfig.instPath);
144+
key.SetValue("UninstallString", string.Format("\"{0}\"", uninstallerPath));
145+
key.SetValue("DisplayIcon", finalInstallLocation);
146+
key.SetValue("HelpLink", AppConfig.supportUrl);
147+
key.SetValue("URLInfoAbout", AppConfig.website);
148+
key.SetValue("NoModify", 1);
149+
key.SetValue("NoRepair", 1);
150+
}
151+
}
152+
catch
153+
{
154+
}
155+
}
156+
157+
public void LaunchInstalledApplication()
158+
{
159+
try
160+
{
161+
if (File.Exists(finalInstallLocation))
162+
{
163+
ProcessStartInfo startInfo = new ProcessStartInfo();
164+
startInfo.FileName = finalInstallLocation;
165+
startInfo.WorkingDirectory = AppConfig.instPath;
166+
startInfo.UseShellExecute = true;
167+
Process.Start(startInfo);
168+
}
169+
}
170+
catch (Exception ex)
171+
{
172+
MessageBox.Show(string.Format("Could not launch application: {0}", ex.Message), "Launch Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
173+
}
174+
}
175+
176+
public string GetTemporaryPath()
177+
{
178+
return temporaryFilePath;
179+
}
180+
}
181+
}

0 commit comments

Comments
 (0)