diff --git a/BuildTools/Build.bat b/BuildTools/Build.bat
new file mode 100644
index 00000000..e3dd3baf
--- /dev/null
+++ b/BuildTools/Build.bat
@@ -0,0 +1,176 @@
+@echo off
+setlocal EnableDelayedExpansion
+
+set VCVARSALL=%VS120COMNTOOLS%..\..\VC\vcvarsall.bat
+set MAKENSIS=%PROGRAMFILES%\NSIS\MakeNSIS.exe
+set GIT=%PROGRAMFILES%\Git\bin\git.exe
+
+:: Set VERSION_REVISION to non-zero value to override
+set VERSION_MAJOR=3
+set VERSION_MINOR=2
+set VERSION_SUBMINOR=0
+set VERSION_REVISION=0
+set ISBETA=true
+
+if "%1" == "RELEASE" set ISBETA=false
+if "%1" == "BUILDVERSION" goto BUILDVERSION
+echo Rainmeter Build
+echo ----------------------------------------------
+echo.
+
+if not exist "%VCVARSALL%" echo ERROR: vcvarsall.bat not found & goto END
+call "%VCVARSALL%" x86 > nul
+
+set MSBUILD="msbuild.exe" /nologo^
+ /p:PlatformToolset=v120_xp;VisualStudioVersion=12.0^
+ /p:ExcludeTests=true^
+ /p:Configuration=Release
+
+if exist "Certificate.bat" call "Certificate.bat" > nul
+set SIGNTOOL="signtool.exe" sign /t http://time.certum.pl /f "%CERTFILE%" /p "%CERTKEY%"
+
+if "%1" == "BUILDLANGUAGES" goto BUILDLANGUAGES
+
+if exist "%MAKENSIS%" goto NSISFOUND
+set MAKENSIS=%MAKENSIS:Program Files\=Program Files (x86)\%
+if not exist "%MAKENSIS%" echo ERROR: MakeNSIS.exe not found & goto END
+:NSISFOUND
+
+:BUILDVERSION
+
+if not exist "..\.git" goto UPDATEVERSION
+if not "%VERSION_REVISION%" == "0" goto UPDATEVERSION
+
+:: git
+if exist "%GIT%" goto GITFOUND
+set GIT=%GIT:Program Files\=Program Files (x86)\%
+if not exist "%GIT%" echo ERROR: git.exe not found & goto END
+:GITFOUND
+set /a VERSION_REVISION=0
+for /f "usebackq delims= " %%G in (`"%GIT%" rev-list --all --count`) do set VERSION_REVISION=%%G
+
+:UPDATEVERSION
+
+set VERSION_FULL=%VERSION_MAJOR%.%VERSION_MINOR%.%VERSION_SUBMINOR%.%VERSION_REVISION%
+set VERSION_SHORT=%VERSION_MAJOR%.%VERSION_MINOR%
+if not "%VERSION_SUBMINOR%" == "0" set VERSION_SHORT=!VERSION_SHORT!.%VERSION_SUBMINOR%
+
+:: Update Version.h
+> "..\Version.h" echo #pragma once
+>>"..\Version.h" echo #define FILEVER %VERSION_MAJOR%,%VERSION_MINOR%,%VERSION_SUBMINOR%,%VERSION_REVISION%
+>>"..\Version.h" echo #define PRODUCTVER FILEVER
+>>"..\Version.h" echo #define STRFILEVER "%VERSION_FULL%"
+>>"..\Version.h" echo #define STRPRODUCTVER STRFILEVER
+>>"..\Version.h" echo #define APPVERSION L"%VERSION_MAJOR%.%VERSION_MINOR%.%VERSION_SUBMINOR%"
+>>"..\Version.h" echo #define RAINMETER_VERSION ((%VERSION_MAJOR% * 1000000) + (%VERSION_MINOR% * 1000) + %VERSION_SUBMINOR%)
+>>"..\Version.h" echo const int revision_number = %VERSION_REVISION%;
+>>"..\Version.h" echo const bool revision_beta = %ISBETA%;
+
+:: Update Version.cs
+> "..\Version.cs" echo namespace Rainmeter
+>>"..\Version.cs" echo {
+>>"..\Version.cs" echo public class Version
+>>"..\Version.cs" echo {
+>>"..\Version.cs" echo #if X64
+>>"..\Version.cs" echo public const string Informational = "%VERSION_FULL% (64-bit)";
+>>"..\Version.cs" echo #else
+>>"..\Version.cs" echo public const string Informational = "%VERSION_FULL% (32-bit)";
+>>"..\Version.cs" echo #endif
+>>"..\Version.cs" echo }
+>>"..\Version.cs" echo }
+
+
+if "%1" == "BUILDVERSION" goto :eof
+echo * Updated Version.h
+
+:: Set vcbuild environment variables and begin build
+echo * Starting build for %VERSION_FULL%
+for /F "tokens=1-4 delims=:.," %%a in ("%TIME%") do (
+ set /A "BUILD_BEGIN_TIMESTAMP=(((%%a * 60) + 1%%b %% 100)* 60 + 1%%c %% 100) * 100 + 1%%d %% 100"
+)
+
+:: Build Library
+echo * Building 32-bit projects
+%MSBUILD% /t:rebuild /p:Platform=Win32 /v:q /m ..\Rainmeter.sln > "BuildLog.txt"
+if not %ERRORLEVEL% == 0 echo ERROR %ERRORLEVEL%: Build failed & goto END
+
+echo * Building 64-bit projects
+%MSBUILD% /t:rebuild /p:Platform=x64 /v:q /m ..\Rainmeter.sln > "BuildLog.txt"
+if not %ERRORLEVEL% == 0 echo ERROR %ERRORLEVEL%: Build failed & goto END
+
+:BUILDLANGUAGES
+echo * Building languages
+
+:: Build all language libraries
+>".\Installer\Languages.nsh" echo.
+for /f "tokens=1,2,3 delims=," %%a in (..\Language\List) do (
+ > "..\Language\Language.rc" echo #include "%%a.h"
+ >>"..\Language\Language.rc" echo #include "Resource.rc"
+ >>".\Installer\Languages.nsh" echo ${IncludeLanguage} "%%b" "%%a"
+ set LANGDLL_PARAMS='%%a - ${LANGFILE_%%b_NAME}' '${LANG_%%b}' '${LANG_%%b_CP}' !LANGDLL_PARAMS!
+ set LANGUAGE_IDS=${LANG_%%b},!LANGUAGE_IDS!
+
+ %MSBUILD% /t:Language /p:Platform=Win32;TargetName=%%c /v:q ..\Rainmeter.sln > "BuildLog.txt"
+ if not %ERRORLEVEL% == 0 echo ERROR: Building language %%a failed & goto END
+)
+>>".\Installer\Languages.nsh" echo ^^!define LANGDLL_PARAMS "%LANGDLL_PARAMS%"
+>>".\Installer\Languages.nsh" echo ^^!define LANGUAGE_IDS "%LANGUAGE_IDS%"
+
+:: Restore English
+echo #include "English.h"> "..\Language\Language.rc"
+echo #include "Resource.rc">> "..\Language\Language.rc"
+if "%1" == "BUILDLANGUAGES" (
+ xcopy /Q /S /Y ..\x32-Release\Languages\*.dll ..\x64-Release\Languages\ > nul
+ xcopy /Q /S /Y ..\x32-Release\Release\Languages\*.dll ..\x32-Debug\Languages\ > nul
+ xcopy /Q /S /Y ..\x32-Release\Release\Languages\*.dll ..\x64-Debug\Languages\ > nul
+ if exist "BuildLog.txt" del "BuildLog.txt"
+ goto END
+)
+
+:: Sign binaries
+if not "%CERTFILE%" == "" (
+ echo * Signing binaries
+ for %%Z in (Rainmeter.dll Rainmeter.exe SkinInstaller.exe SkinInstaller.dll) do (
+ %SIGNTOOL% ..\x32-Release\%%Z > BuildLog.txt
+ if not %ERRORLEVEL% == 0 echo ERROR %ERRORLEVEL%: Signing x32\%%Z failed & goto END
+ %SIGNTOOL% ..\x64-Release\%%Z > BuildLog.txt
+ if not %ERRORLEVEL% == 0 echo ERROR %ERRORLEVEL%: Signing x64\%%Z failed & goto END
+ )
+)
+
+:: Build installer
+echo * Building installer
+
+set INSTALLER_NAME=Rainmeter-%VERSION_SHORT%.exe
+if not "%1" == "RELEASE" set INSTALLER_NAME=Rainmeter-%VERSION_SHORT%-r%VERSION_REVISION%-beta.exe
+
+set INSTALLER_DEFINES=^
+ /DOUTFILE="%INSTALLER_NAME%"^
+ /DVERSION_FULL="%VERSION_FULL%"^
+ /DVERSION_SHORT="%VERSION_SHORT%"^
+ /DVERSION_REVISION="%VERSION_REVISION%"
+if not "%1" == "RELEASE" set INSTALLER_DEFINES=!INSTALLER_DEFINES! /DBETA
+
+"%MAKENSIS%" %INSTALLER_DEFINES% .\Installer\Installer.nsi > "BuildLog.txt"
+if not %ERRORLEVEL% == 0 echo ERROR %ERRORLEVEL%: Building installer failed & goto END
+
+:: Sign installer
+if not "%CERTFILE%" == "" (
+ echo * Signing installer
+ %SIGNTOOL% %INSTALLER_NAME% > BuildLog.txt
+ if not %ERRORLEVEL% == 0 echo ERROR %ERRORLEVEL%: Signing installer failed & goto END
+)
+
+:: If we got here, build was successful so delete BuildLog.txt
+if exist "BuildLog.txt" del "BuildLog.txt"
+
+for /F "tokens=1-4 delims=:.," %%a in ("%TIME%") do (
+ set /A "BUILD_END_TIMESTAMP=(((%%a * 60) + 1%%b %% 100)* 60 + %%c %% 100) * 100 + 1%%d %% 100"
+)
+set /A "BUILD_ELAPSED_TIME=(%BUILD_END_TIMESTAMP% - %BUILD_BEGIN_TIMESTAMP%) / 100"
+echo * Build complete. Elapsed time: %BUILD_ELAPSED_TIME% sec
+
+:END
+if exist ".\Installer\Languages.nsh" del ".\Installer\Languages.nsh"
+echo.
+pause
diff --git a/BuildTools/BuildLanguages.bat b/BuildTools/BuildLanguages.bat
new file mode 100644
index 00000000..cd8047ac
--- /dev/null
+++ b/BuildTools/BuildLanguages.bat
@@ -0,0 +1,2 @@
+@echo off
+"Build.bat" BUILDLANGUAGES
\ No newline at end of file
diff --git a/BuildTools/BuildVersion.bat b/BuildTools/BuildVersion.bat
new file mode 100644
index 00000000..fcf49acf
--- /dev/null
+++ b/BuildTools/BuildVersion.bat
@@ -0,0 +1,2 @@
+@echo off
+"Build.bat" BUILDVERSION
diff --git a/BuildTools/DllExporter/AssemblyInfo.cs b/BuildTools/DllExporter/AssemblyInfo.cs
new file mode 100644
index 00000000..c23d01a9
--- /dev/null
+++ b/BuildTools/DllExporter/AssemblyInfo.cs
@@ -0,0 +1,7 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyCopyright("© 2013 - Birunthan Mohanathas")]
+[assembly: AssemblyVersion("1.0.1.0")]
+[assembly: AssemblyProduct("Rainmeter")]
\ No newline at end of file
diff --git a/BuildTools/DllExporter/DllExporter.csproj b/BuildTools/DllExporter/DllExporter.csproj
new file mode 100644
index 00000000..7079b9f3
--- /dev/null
+++ b/BuildTools/DllExporter/DllExporter.csproj
@@ -0,0 +1,82 @@
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}
+ Exe
+ Properties
+ DllExporter
+ DllExporter
+ v4.0
+ 512
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+ $(SolutionDir)x32-$(Configuration)\Tools\
+ $(SolutionDir)x64-$(Configuration)\Tools\
+
+
+ x86
+ true
+ full
+ false
+ DEBUG;TRACE
+ prompt
+ 4
+ 1607
+
+
+ x86
+ none
+ true
+ TRACE
+ prompt
+ 4
+ 1607
+
+
+ OnOutputUpdated
+
+
+ true
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ 1607
+
+
+ TRACE
+ true
+ none
+ x64
+ prompt
+ 1607
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BuildTools/DllExporter/Program.cs b/BuildTools/DllExporter/Program.cs
new file mode 100644
index 00000000..4b56fda4
--- /dev/null
+++ b/BuildTools/DllExporter/Program.cs
@@ -0,0 +1,241 @@
+/*
+ Copyright (C) 2011 Birunthan Mohanathas
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Diagnostics;
+using Microsoft.Build.Utilities;
+using System.IO;
+
+namespace DllExporter
+{
+ class Program
+ {
+ static int Main(string[] args)
+ {
+ if (args.Length < 4)
+ {
+ Console.WriteLine("DllExporter error: Invalid arguments");
+ return 1;
+ }
+
+ string configurationName = args[0];
+ string platformTarget = args[1];
+ string targetDirectory = args[2];
+ string targetDllName = targetDirectory + args[3];
+ string targetIlName = targetDllName + ".il";
+ string targetResName = targetDllName + ".res";
+
+ bool is64 = platformTarget.ToLower().Equals("x64");
+ bool isDebug = configurationName.ToLower().Equals("debug");
+
+ string ilasmPath = FindIlasmPath(is64);
+ if (ilasmPath == null)
+ {
+ Console.WriteLine("DllExporter error: ilasm.exe not found");
+ return 1;
+ }
+
+ string ildasmPath = FindIldasmPath();
+ if (ildasmPath == null)
+ {
+ Console.WriteLine("DllExporter error: ildasm.exe not found");
+ return 1;
+ }
+
+ Directory.SetCurrentDirectory(targetDirectory);
+
+ // Disassemble
+ Process ildasmProc = new Process();
+ string ildasmArgs = string.Format(
+ "/nobar {0} /output=\"{1}\" \"{2}\"",
+ isDebug ? "/linenum" : "",
+ targetIlName,
+ targetDllName);
+
+ ildasmProc.StartInfo = new ProcessStartInfo(ildasmPath, ildasmArgs);
+ ildasmProc.StartInfo.UseShellExecute = false;
+ ildasmProc.StartInfo.CreateNoWindow = false;
+ ildasmProc.StartInfo.RedirectStandardOutput = true;
+ ildasmProc.Start();
+ ildasmProc.WaitForExit();
+
+ if (ildasmProc.ExitCode != 0)
+ {
+ Console.WriteLine("DllExporter error: Unable to disassemble!");
+ Console.WriteLine(ildasmProc.StandardOutput.ReadToEnd());
+ return ildasmProc.ExitCode;
+ }
+
+ bool hasResource = File.Exists(targetResName);
+
+ // Read disassembly and find methods marked with DllExport attribute
+ List lines = new List(File.ReadAllLines(targetIlName));
+ int attributeIndex = 0;
+ int exportCount = 0;
+ while (true)
+ {
+ attributeIndex = lines.FindIndex(attributeIndex, new Predicate(x => x.Contains(".custom instance void") && x.Contains("DllExport::.ctor()")));
+ if (attributeIndex < 8) break;
+
+ int methodIndex = lines.FindLastIndex(attributeIndex, attributeIndex, new Predicate(x => x.Contains(".method")));
+ if (methodIndex == -1)
+ {
+ Console.WriteLine("DllExporter error: Unable to parse disassembly (.method not found)!");
+ return 1;
+ }
+
+ int functionIndex = lines.FindIndex(methodIndex, new Predicate(x => x.Contains("(")));
+ if (functionIndex == -1)
+ {
+ Console.WriteLine("DllExporter error: Unable to parse disassembly (bracket not found)!");
+ return 1;
+ }
+
+ int bracketPos = lines[functionIndex].IndexOf('(');
+ int functionNamePos = lines[functionIndex].LastIndexOf(' ', bracketPos);
+ string functionName = lines[functionIndex].Substring(functionNamePos, bracketPos - functionNamePos);
+
+ // Change calling convention to cdecl
+ lines[functionIndex] = string.Format("{0} modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) {1}", lines[functionIndex].Substring(0, functionNamePos - 1), lines[functionIndex].Substring(functionNamePos));
+
+ int attributeBeginPos = lines[attributeIndex].IndexOf('.');
+ string spaces = new string(' ', attributeBeginPos);
+
+ // Replace attribute with export
+ ++exportCount;
+ lines[attributeIndex] = string.Format("{0}.export [{1}] as {2}", spaces, exportCount, functionName);
+
+ ++attributeIndex;
+ }
+
+ if (exportCount == 0)
+ {
+ Console.WriteLine("DllExporter warning: Nothing found to export.");
+ }
+
+ // Remove the DllExport class
+ int classIndex = lines.FindIndex(new Predicate(x => x.Contains(".class ") && x.EndsWith(".DllExport")));
+ if (classIndex == -1)
+ {
+ Console.WriteLine("DllExporter error: Unable to parse disassembly (DllExport class not found)!");
+ return 1;
+ }
+ else
+ {
+ int classEndIndex = lines.FindIndex(classIndex, new Predicate(x => x.Contains("} // end of class") && x.EndsWith(".DllExport")));
+ if (classEndIndex == -1)
+ {
+ Console.WriteLine("DllExporter error: Unable to parse disassembly (DllExport class end not found)!");
+ return 1;
+ }
+
+ lines.RemoveRange(classIndex, classEndIndex - classIndex + 2);
+ }
+
+ // Write everything back
+ File.WriteAllLines(targetIlName, lines.ToArray());
+
+ // Reassemble
+ Process ilasmProc = new Process();
+ string resource = hasResource ? string.Format("/resource=\"{0}\"", targetResName) : "";
+ string ilasmArgs = string.Format("/nologo /quiet /dll {0} {1} /output=\"{2}\" {3} \"{4}\"", isDebug ? "/debug /pdb" : "/optimize", is64 ? "/x64 /PE64" : "", targetDllName, resource, targetIlName);
+ ilasmProc.StartInfo = new ProcessStartInfo(ilasmPath, ilasmArgs);
+ ilasmProc.StartInfo.UseShellExecute = false;
+ ilasmProc.StartInfo.CreateNoWindow = false;
+ ilasmProc.StartInfo.RedirectStandardOutput = true;
+ ilasmProc.Start();
+ ilasmProc.WaitForExit();
+
+ if (ilasmProc.ExitCode != 0)
+ {
+ Console.WriteLine("DllExporter error: Unable to assemble!");
+ Console.WriteLine(ilasmProc.StandardOutput.ReadToEnd());
+ return ilasmProc.ExitCode;
+ }
+
+ // Cleanup
+ File.Delete(targetIlName);
+ File.Delete(targetResName);
+
+ Console.WriteLine("DllExporter: Processed {0}", args[3]);
+
+ return 0;
+ }
+
+ ///
+ /// Finds path to ilasm.exe.
+ ///
+ private static string FindIlasmPath(bool x64)
+ {
+ var arch = x64 ? DotNetFrameworkArchitecture.Bitness64 : DotNetFrameworkArchitecture.Bitness32;
+ var path = ToolLocationHelper.GetPathToDotNetFrameworkFile(
+ "ilasm.exe", TargetDotNetFrameworkVersion.Version20, arch);
+ return File.Exists(path) ? path : null;
+ }
+
+ ///
+ /// Finds path to ildasm.exe.
+ ///
+ private static string FindIldasmPath()
+ {
+ var sdkPath = Environment.ExpandEnvironmentVariables(@"%ProgramFiles(x86)%\Microsoft SDKs\Windows\");
+ if (!Directory.Exists(sdkPath))
+ {
+ sdkPath = Environment.ExpandEnvironmentVariables(@"%ProgramFiles%\Microsoft SDKs\Windows\");
+ }
+
+ if (!Directory.Exists(sdkPath))
+ {
+ throw new DirectoryNotFoundException("'Microsoft SDKs' directory not found");
+ }
+
+ // Get the version directories.
+ var sdkVersionDirectories = Directory.GetDirectories(sdkPath);
+ foreach (var sdkVersionDirectory in sdkVersionDirectories)
+ {
+ var binDirectory = Path.Combine(sdkVersionDirectory, @"bin");
+ if (!Directory.Exists(binDirectory))
+ {
+ continue;
+ }
+
+ // Check for e.g. 'Microsoft SDKs\v8.0A\bin\ildasm.exe'.
+ var ildasmPath = Path.Combine(binDirectory, @"ildasm.exe");
+ if (File.Exists(ildasmPath))
+ {
+ return ildasmPath;
+ }
+
+ // Check for e.g. 'Microsoft SDKs\v8.0A\bin\NETFX 4.0 Tools\ildasm.exe'.
+ var toolsDirectories = Directory.GetDirectories(binDirectory, "NETFX*Tools");
+ foreach (var toolDirectory in toolsDirectories)
+ {
+ ildasmPath = Path.Combine(toolDirectory, @"ildasm.exe");
+ if (File.Exists(ildasmPath))
+ {
+ return ildasmPath;
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/BuildTools/Installer/Header.bmp b/BuildTools/Installer/Header.bmp
new file mode 100644
index 00000000..9eb90fec
Binary files /dev/null and b/BuildTools/Installer/Header.bmp differ
diff --git a/BuildTools/Installer/Icon.ico b/BuildTools/Installer/Icon.ico
new file mode 100644
index 00000000..9801fed5
Binary files /dev/null and b/BuildTools/Installer/Icon.ico differ
diff --git a/BuildTools/Installer/Installer.nsi b/BuildTools/Installer/Installer.nsi
new file mode 100644
index 00000000..7eba80fc
--- /dev/null
+++ b/BuildTools/Installer/Installer.nsi
@@ -0,0 +1,959 @@
+/*
+ Copyright (C) 2012 Birunthan Mohanathas
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+!verbose 3
+!addplugindir ".\"
+!include "MUI2.nsh"
+!include "x64.nsh"
+!include "FileFunc.nsh"
+!include "WordFunc.nsh"
+!include "WinVer.nsh"
+!include "UAC.nsh"
+
+!ifndef OUTFILE
+ !define OUTFILE "Rainmeter-test.exe"
+ !define VERSION_FULL "0.0.0.0"
+ !define VERSION_SHORT "0.0"
+ !define VERSION_REVISION "000"
+!else
+ !define INCLUDEFILES
+!endif
+
+Name "Rainmeter"
+VIAddVersionKey "ProductName" "Rainmeter"
+VIAddVersionKey "FileDescription" "Rainmeter Installer"
+VIAddVersionKey "FileVersion" "${VERSION_FULL}"
+VIAddVersionKey "ProductVersion" "${VERSION_FULL}"
+VIAddVersionKey "OriginalFilename" "${OUTFILE}"
+VIAddVersionKey "LegalCopyright" "Copyright (C) 2009-2013 - All authors"
+VIProductVersion "${VERSION_FULL}"
+BrandingText " "
+SetCompressor /SOLID lzma
+RequestExecutionLevel user
+InstallDirRegKey HKLM "SOFTWARE\Rainmeter" ""
+ShowInstDetails nevershow
+AllowSkipFiles off
+XPStyle on
+OutFile "..\${OUTFILE}"
+ReserveFile "${NSISDIR}\Plugins\LangDLL.dll"
+ReserveFile "${NSISDIR}\Plugins\nsDialogs.dll"
+ReserveFile "${NSISDIR}\Plugins\System.dll"
+ReserveFile ".\UAC.dll"
+
+!define REQUIREDSPACE 5 ; Minimum required space for install (in MB)
+
+; Error levels (for silent install)
+!define ERROR_UNSUPPORTED 3
+!define ERROR_NOTADMIN 4
+!define ERROR_WRITEFAIL 5
+!define ERROR_NOVCREDIST 6
+!define ERROR_CLOSEFAIL 7
+
+; Additional Windows definitions
+!define BCM_SETSHIELD 0x0000160c
+!define PF_XMMI_INSTRUCTIONS_AVAILABLE 6
+!define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
+
+!define MUI_ICON ".\Icon.ico"
+!define MUI_UNICON ".\Icon.ico"
+!define MUI_WELCOMEFINISHPAGE_BITMAP ".\Wizard.bmp"
+!define MUI_FINISHPAGE_RUN
+!define MUI_FINISHPAGE_RUN_FUNCTION FinishRun
+!define MUI_WELCOMEPAGE ; For language strings
+
+Page custom PageWelcome PageWelcomeOnLeave
+Page custom PageOptions PageOptionsOnLeave
+!insertmacro MUI_PAGE_INSTFILES
+!insertmacro MUI_PAGE_FINISH
+
+UninstPage custom un.PageOptions un.GetOptions
+!insertmacro MUI_UNPAGE_INSTFILES
+
+; Include languages
+!macro IncludeLanguage LANGUAGE CUSTOMLANGUAGE
+ !insertmacro MUI_LANGUAGE ${LANGUAGE}
+ !insertmacro LANGFILE_INCLUDE "..\..\Language\${CUSTOMLANGUAGE}.nsh"
+!macroend
+!define IncludeLanguage "!insertmacro IncludeLanguage"
+!include "Languages.nsh"
+
+Var NonDefaultLanguage
+Var AutoStartup
+Var Install64Bit
+Var InstallPortable
+Var un.DeleteAll
+
+; Install
+; --------------------------------------
+Function .onInit
+ ${If} ${RunningX64}
+ ${EnableX64FSRedirection}
+ ${EndIf}
+
+ ${IfNot} ${UAC_IsInnerInstance}
+ ${If} ${IsWin2000}
+ ${OrIf} ${IsWinXP}
+ ${AndIf} ${AtMostServicePack} 2
+ ${OrIf} ${IsWin2003}
+ ${AndIf} ${AtMostServicePack} 0
+ ${IfNot} ${Silent}
+ MessageBox MB_OK|MB_ICONSTOP "Rainmeter requires Windows XP SP3 or later."
+ ${EndIf}
+ SetErrorLevel ${ERROR_UNSUPPORTED}
+ Quit
+ ${EndIf}
+
+ System::Call 'kernel32::IsProcessorFeaturePresent(i${PF_XMMI_INSTRUCTIONS_AVAILABLE})i.r0'
+ ${If} $0 = 0
+ ${IfNot} ${Silent}
+ MessageBox MB_OK|MB_ICONSTOP "Rainmeter requires a Pentium III or later processor."
+ ${EndIf}
+ SetErrorLevel ${ERROR_UNSUPPORTED}
+ Quit
+ ${EndIf}
+
+ ReadRegStr $0 HKLM "SOFTWARE\Rainmeter" "Language"
+ ReadRegDWORD $NonDefaultLanguage HKLM "SOFTWARE\Rainmeter" "NonDefault"
+
+ ${IfNot} ${Silent}
+ ${If} $0 == ""
+ ${OrIf} $0 <> $LANGUAGE
+ ${AndIf} $NonDefaultLanguage != 1
+ ; New install or better match
+ LangDLL::LangDialog "$(^SetupCaption)" "Please select the installer language.$\n$(SELECTLANGUAGE)" AC ${LANGDLL_PARAMS} ""
+ Pop $0
+ ${If} $0 == "cancel"
+ Abort
+ ${EndIf}
+
+ ${If} $0 <> $LANGUAGE
+ ; User selected non-default language
+ StrCpy $NonDefaultLanguage 1
+ ${EndIf}
+ ${EndIf}
+
+ StrCpy $LANGUAGE $0
+ ${Else}
+ ${If} $0 != ""
+ StrCpy $LANGUAGE $0
+ ${EndIf}
+
+ ${GetParameters} $R1
+
+ ClearErrors
+ ${GetOptions} $R1 "/LANGUAGE=" $0
+ ${IfNot} ${Errors}
+ ${If} $LANGUAGE != $0
+ StrCpy $NonDefaultLanguage 1
+ ${EndIf}
+
+ StrCpy $LANGUAGE $0
+ ${EndIf}
+
+ ${GetOptions} $R1 "/STARTUP=" $0
+ ${If} $0 = 1
+ StrCpy $AutoStartup 1
+ ${EndIf}
+
+ ${GetOptions} $R1 "/PORTABLE=" $0
+ ${If} $0 = 1
+ StrCpy $InstallPortable 1
+ ${Else}
+ ${IfNot} ${UAC_IsAdmin}
+ SetErrorLevel ${ERROR_NOTADMIN}
+ Quit
+ ${EndIf}
+ ${EndIf}
+
+ ${GetOptions} $R1 "/VERSION=" $0
+ ${If} $0 = 64
+ StrCpy $Install64Bit 1
+
+ ${If} $INSTDIR == ""
+ StrCpy $INSTDIR "$PROGRAMFILES64\Rainmeter"
+ ${EndIf}
+ ${Else}
+ ${If} $INSTDIR == ""
+ StrCpy $INSTDIR "$PROGRAMFILES\Rainmeter"
+ ${EndIf}
+ ${EndIf}
+
+ ClearErrors
+ CreateDirectory "$INSTDIR"
+ WriteINIStr "$INSTDIR\writetest~.rm" "1" "1" "1"
+ Delete "$INSTDIR\writetest~.rm"
+
+ ${If} ${Errors}
+ RMDir "$INSTDIR"
+ SetErrorLevel ${ERROR_WRITEFAIL}
+ Quit
+ ${EndIf}
+ ${EndIf}
+
+ ; If the language was set to a non-existent language, reset it back to English.
+ ${WordFind} ",${LANGUAGE_IDS}" ",$LANGUAGE," "E+1{" $0
+ ${If} ${Errors}
+ StrCpy $LANGUAGE "1033"
+ ${EndIf}
+ ${Else}
+ ; Exchange settings with user instance
+ !insertmacro UAC_AsUser_Call Function ExchangeSettings ${UAC_SYNCREGISTERS}
+ StrCpy $AutoStartup $1
+ StrCpy $Install64Bit $2
+ StrCpy $NonDefaultLanguage $3
+ StrCpy $LANGUAGE $4
+ StrCpy $INSTDIR $5
+ ${EndIf}
+FunctionEnd
+
+Function ExchangeSettings
+ StrCpy $1 $AutoStartup
+ StrCpy $2 $Install64Bit
+ StrCpy $3 $NonDefaultLanguage
+ StrCpy $4 $LANGUAGE
+ StrCpy $5 $INSTDIR
+ HideWindow
+FunctionEnd
+
+Function PageWelcome
+ ${If} ${UAC_IsInnerInstance}
+ ${If} ${UAC_IsAdmin}
+ ; Skip page
+ Abort
+ ${Else}
+ MessageBox MB_OK|MB_ICONSTOP "$(ADMINERROR) (Inner)"
+ Quit
+ ${EndIf}
+ ${EndIf}
+
+ !insertmacro MUI_HEADER_TEXT "$(INSTALLOPTIONS)" "$(^ComponentsSubText1)"
+ nsDialogs::Create 1044
+ Pop $0
+ nsDialogs::SetRTL $(^RTL)
+ SetCtlColors $0 "" "${MUI_BGCOLOR}"
+
+ ${NSD_CreateBitmap} 0u 0u 109u 193u ""
+ Pop $0
+ ${NSD_SetImage} $0 "$PLUGINSDIR\modern-wizard.bmp" $R0
+
+ ${NSD_CreateLabel} 120u 10u 195u 38u "$(MUI_TEXT_WELCOME_INFO_TITLE)"
+ Pop $0
+ SetCtlColors $0 "" "${MUI_BGCOLOR}"
+ CreateFont $1 "$(^Font)" "12" "700"
+ SendMessage $0 ${WM_SETFONT} $1 0
+
+ ${NSD_CreateLabel} 120u 55u 195u 12u "$(^ComponentsSubText1)"
+ Pop $0
+ SetCtlColors $0 "" "${MUI_BGCOLOR}"
+
+ ${NSD_CreateRadioButton} 120u 70u 205u 12u "$(STANDARDINST)"
+ Pop $R1
+ SetCtlColors $R1 "" "${MUI_BGCOLOR}"
+ ${NSD_AddStyle} $R1 ${WS_GROUP}
+ SendMessage $R1 ${WM_SETFONT} $mui.Header.Text.Font 0
+
+ ${NSD_CreateLabel} 132u 82u 185u 24u "$(STANDARDINSTDESC)"
+ Pop $0
+ SetCtlColors $0 "" "${MUI_BGCOLOR}"
+
+ ${NSD_CreateRadioButton} 120u 106u 310u 12u "$(PORTABLEINST)"
+ Pop $R2
+ SetCtlColors $R2 "" "${MUI_BGCOLOR}"
+ ${NSD_AddStyle} $R2 ${WS_TABSTOP}
+ SendMessage $R2 ${WM_SETFONT} $mui.Header.Text.Font 0
+
+ ${NSD_CreateLabel} 132u 118u 185u 52u "$(PORTABLEINSTDESC)"
+ Pop $0
+ SetCtlColors $0 "" "${MUI_BGCOLOR}"
+
+ ${If} $InstallPortable = 1
+ ${NSD_Check} $R2
+ ${Else}
+ ${NSD_Check} $R1
+ ${EndIf}
+
+ Call muiPageLoadFullWindow
+
+ nsDialogs::Show
+ ${NSD_FreeImage} $R0
+FunctionEnd
+
+Function PageWelcomeOnLeave
+ ${NSD_GetState} $R2 $InstallPortable
+ Call muiPageUnloadFullWindow
+FunctionEnd
+
+Function PageOptions
+ ${If} ${UAC_IsInnerInstance}
+ ${AndIf} ${UAC_IsAdmin}
+ ; Skip page
+ Abort
+ ${EndIf}
+
+ !insertmacro MUI_HEADER_TEXT "$(INSTALLOPTIONS)" "$(INSTALLOPTIONSDESC)"
+ nsDialogs::Create 1018
+ nsDialogs::SetRTL $(^RTL)
+
+ ${NSD_CreateGroupBox} 0 0u -1u 36u "$(^DirSubText)"
+
+ ${NSD_CreateDirRequest} 6u 14u 232u 14u ""
+ Pop $R0
+ ${NSD_OnChange} $R0 PageOptionsDirectoryOnChange
+
+ ${NSD_CreateBrowseButton} 242u 14u 50u 14u "$(^BrowseBtn)"
+ Pop $R1
+ ${NSD_OnClick} $R1 PageOptionsBrowseOnClick
+
+ StrCpy $1 0
+
+ StrCpy $R2 0
+ ${If} ${RunningX64}
+ ${If} $InstallPortable = 1
+ ${OrIf} $INSTDIR == ""
+ ${NSD_CreateCheckBox} 6u 54u 285u 12u "$(INSTALL64BIT)"
+ Pop $R2
+ StrCpy $1 30u
+ ${EndIf}
+ ${EndIf}
+
+ ${If} $InstallPortable <> 1
+ ${If} $1 = 0
+ StrCpy $0 54u
+ StrCpy $1 30u
+ ${Else}
+ StrCpy $0 66u
+ StrCpy $1 42u
+ ${EndIf}
+
+ ${NSD_CreateCheckbox} 6u $0 285u 12u "$(AUTOSTARTUP)"
+ Pop $R3
+
+ ${If} $INSTDIR == ""
+ ${NSD_Check} $R3
+ ${Else}
+ SetShellVarContext all
+ ${If} ${FileExists} "$SMSTARTUP\Rainmeter.lnk"
+ ${NSD_Check} $R3
+ ${EndIf}
+
+ SetShellVarContext current
+ ${If} ${FileExists} "$SMSTARTUP\Rainmeter.lnk"
+ ${NSD_Check} $R3
+ ${EndIf}
+ ${EndIf}
+ ${Else}
+ StrCpy $R3 0
+ ${EndIf}
+
+ ${If} $1 <> 0
+ ${NSD_CreateGroupBox} 0 42u -1u $1 "$(ADDITIONALOPTIONS)"
+ ${EndIf}
+
+ ; Set default directory
+ ${If} $InstallPortable = 1
+ ${GetRoot} "$WINDIR" $0
+ ${NSD_SetText} $R0 "$0\Rainmeter"
+ ${Else}
+ ; Disable Directory editbox and Browse button if already installed
+ SendMessage $R0 ${EM_SETREADONLY} 1 0
+
+ ${If} $INSTDIR != ""
+ EnableWindow $R1 0
+ ${NSD_SetText} $R0 "$INSTDIR"
+ ${Else}
+ ; Fresh install
+ ${If} ${RunningX64}
+ ${NSD_SetText} $R0 "$PROGRAMFILES64\Rainmeter"
+ ${NSD_Check} $R2
+ ${Else}
+ ${NSD_SetText} $R0 "$PROGRAMFILES\Rainmeter"
+ ${EndIf}
+ ${EndIf}
+ ${EndIf}
+
+ ; Show UAC shield on Install button if requiredd
+ GetDlgItem $0 $HWNDPARENT 1
+ ${If} $InstallPortable = 1
+ SendMessage $0 ${BCM_SETSHIELD} 0 0
+ ${Else}
+ SendMessage $0 ${BCM_SETSHIELD} 0 1
+
+ ; Hide Back button
+ GetDlgItem $0 $HWNDPARENT 3
+ ShowWindow $0 ${SW_HIDE}
+ ${EndIf}
+
+ nsDialogs::Show
+FunctionEnd
+
+Function PageOptionsDirectoryOnChange
+ ${NSD_GetText} $R0 $0
+
+ ; Disable Install button if not enough space
+ GetDlgItem $1 $HWNDPARENT 1
+ ${GetRoot} $0 $2
+ ${DriveSpace} "$2\" "/D=F /S=M" $3
+ ${If} $3 < ${REQUIREDSPACE}
+ EnableWindow $1 0
+ ${Else}
+ EnableWindow $1 1
+ ${EndIf}
+
+ StrCpy $Install64Bit 0
+ ${If} ${RunningX64}
+ ${If} ${FileExists} "$0\Rainmeter.exe"
+ MoreInfo::GetProductVersion "$0\Rainmeter.exe"
+ Pop $0
+ StrCpy $0 $0 2 -7
+ ${If} $0 == 64
+ StrCpy $Install64Bit 1
+ ${EndIf}
+
+ ${If} $R2 != 0
+ ${NSD_SetState} $R2 $Install64Bit
+ EnableWindow $R2 0
+ ${EndIf}
+ ${Else}
+ ${If} $R2 != 0
+ EnableWindow $R2 1
+ ${EndIf}
+ ${EndIf}
+ ${EndIf}
+FunctionEnd
+
+Function PageOptionsBrowseOnClick
+ ${NSD_GetText} $R0 $0
+ nsDialogs::SelectFolderDialog "$(^DirBrowseText)" $0
+ Pop $1
+ ${If} $1 != error
+ ${NSD_SetText} $R0 $1
+ ${EndIf}
+FunctionEnd
+
+Function PageOptionsOnLeave
+ ; Verify that selected folder is writable
+ ${NSD_GetText} $R0 $0
+ ${If} $InstallPortable = 1
+ ClearErrors
+ CreateDirectory "$0"
+ WriteINIStr "$0\writetest~.rm" "1" "1" "1"
+ Delete "$0\writetest~.rm"
+
+ ${If} ${Errors}
+ RMDir "$0"
+ MessageBox MB_OK|MB_ICONEXCLAMATION "$(WRITEERROR)"
+ Abort
+ ${EndIf}
+
+ RMDir "$0"
+ ${EndIf}
+
+ StrCpy $INSTDIR $0
+
+ GetDlgItem $0 $HWNDPARENT 1
+ EnableWindow $0 0
+
+ ${If} $R2 != 0
+ ${NSD_GetState} $R2 $Install64Bit
+ ${EndIf}
+
+ ${If} $R3 != 0
+ ${NSD_GetState} $R3 $AutoStartup
+ ${EndIf}
+
+ ${If} $InstallPortable <> 1
+ ${IfNot} ${UAC_IsAdmin}
+ ; UAC_IsAdmin seems to return incorrect result sometimes. Recheck with UserInfo::GetAccountType to be sure.
+ UserInfo::GetAccountType
+ Pop $0
+ ${If} $0 != "Admin"
+UAC_TryAgain:
+ !insertmacro UAC_RunElevated
+ ${Switch} $0
+ ${Case} 0
+ ${IfThen} $1 = 1 ${|} Quit ${|}
+ ${IfThen} $3 <> 0 ${|} ${Break} ${|}
+ ${If} $1 = 3
+ MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(ADMINERROR)" /SD IDNO IDOK UAC_TryAgain IDNO 0
+ ${EndIf}
+ ${Case} 1223
+ Quit
+ ${Case} 1062
+ MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(LOGONERROR)"
+ Quit
+ ${Default}
+ MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(UACERROR) ($0)"
+ Quit
+ ${EndSwitch}
+ ${EndIf}
+ ${EndIf}
+ ${EndIf}
+FunctionEnd
+
+!macro InstallFiles DIR ARCH
+ SetOutPath "$INSTDIR"
+ File "..\..\${DIR}-Release\Rainmeter.exe"
+ File "..\..\${DIR}-Release\Rainmeter.dll"
+ File "..\..\${DIR}-Release\SkinInstaller.exe"
+ File "..\..\${DIR}-Release\SkinInstaller.dll"
+
+ SetOutPath "$INSTDIR\Plugins"
+ File /x *Example*.dll "..\..\${DIR}-Release\Plugins\*.dll"
+
+ SetOutPath "$INSTDIR\Runtime"
+ File "$%VS120COMNTOOLS%..\..\VC\redist\${ARCH}\Microsoft.VC120.CRT\msvcp120.dll"
+ File "$%VS120COMNTOOLS%..\..\VC\redist\${ARCH}\Microsoft.VC120.CRT\msvcr120.dll"
+!macroend
+
+!macro RemoveStartMenuShortcuts STARTMENUPATH
+ Delete "${STARTMENUPATH}\Rainmeter.lnk"
+ Delete "${STARTMENUPATH}\Rainmeter Help.lnk"
+ Delete "${STARTMENUPATH}\Rainmeter Help.URL"
+ Delete "${STARTMENUPATH}\Remove Rainmeter.lnk"
+ Delete "${STARTMENUPATH}\RainThemes.lnk"
+ Delete "${STARTMENUPATH}\RainThemes Help.lnk"
+ Delete "${STARTMENUPATH}\RainBrowser.lnk"
+ Delete "${STARTMENUPATH}\RainBackup.lnk"
+ Delete "${STARTMENUPATH}\Rainstaller.lnk"
+ Delete "${STARTMENUPATH}\Skin Installer.lnk"
+ Delete "${STARTMENUPATH}\Rainstaller Help.lnk"
+ RMDir "${STARTMENUPATH}"
+!macroend
+
+Section
+ SetOutPath "$PLUGINSDIR"
+ SetShellVarContext current
+
+ Var /GLOBAL InstArc
+ ${If} $Install64Bit = 1
+ StrCpy $InstArc "x64"
+ ${Else}
+ StrCpy $InstArc "x86"
+ ${EndIf}
+
+ ${If} $InstallPortable <> 1
+ ${AndIfNot} ${AtLeastWinVista}
+ ; Download and install .NET if required
+ ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727" "Install"
+ ${If} $0 <> 1
+ ${If} $Install64Bit <> 1
+ NSISdl::download /TIMEOUT=30000 "http://download.microsoft.com/download/5/6/7/567758a3-759e-473e-bf8f-52154438565a/dotnetfx.exe" "$PLUGINSDIR\dotnetfx.exe"
+ ${Else}
+ NSISdl::download /TIMEOUT=30000 "http://download.microsoft.com/download/a/3/f/a3f1bf98-18f3-4036-9b68-8e6de530ce0a/NetFx64.exe" "$PLUGINSDIR\dotnetfx.exe"
+ ${EndIf}
+ Pop $0
+
+ ${If} $0 == "success"
+ ExecWait '"$PLUGINSDIR\dotnetfx.exe" /q:a /c:"install /q"' $0
+ Delete "$PLUGINSDIR\dotnetfx.exe"
+
+ ${If} $0 = 3010
+ SetRebootFlag true
+ ${ElseIf} $0 <> 0
+ MessageBox MB_OK|MB_ICONSTOP "$(DOTNETINSTERROR)"
+ Quit
+ ${EndIf}
+ ${ElseIf} $0 == "cancel"
+ Quit
+ ${Else}
+ MessageBox MB_OK|MB_ICONSTOP "$(DOTNETINSTERROR)"
+ Quit
+ ${EndIf}
+ ${EndIf}
+ ${EndIf}
+
+ SetOutPath "$INSTDIR"
+
+ ; Close Rainmeter (and wait up to five seconds)
+ ${ForEach} $0 10 0 - 1
+ FindWindow $1 "DummyRainWClass" "Rainmeter control window"
+ ClearErrors
+ Delete "$INSTDIR\Rainmeter.exe"
+ ${If} $1 = 0
+ ${AndIfNot} ${Errors}
+ ${Break}
+ ${EndIf}
+
+ SendMessage $1 ${WM_CLOSE} 0 0
+
+ ${If} $0 = 0
+ ${If} ${Silent}
+ SetErrorLevel ${ERROR_CLOSEFAIL}
+ Quit
+ ${Else}
+ MessageBox MB_RETRYCANCEL|MB_ICONSTOP "$(RAINMETERCLOSEERROR)" IDRETRY +2
+ Quit
+ ${EndIf}
+ ${EndIf}
+
+ Sleep 500
+ ${Next}
+
+ ; Move Rainmeter.ini to %APPDATA% if needed
+ ${IfNot} ${Silent}
+ ${AndIf} ${FileExists} "$INSTDIR\Rainmeter.ini"
+ ${If} $InstallPortable <> 1
+ ${If} $Install64Bit = 1
+ ${AndIf} "$INSTDIR" == "$PROGRAMFILES64\Rainmeter"
+ ${OrIf} "$INSTDIR" == "$PROGRAMFILES\Rainmeter"
+ MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(SETTINGSFILEERROR)" IDNO SkipIniMove
+ StrCpy $0 1
+ !insertmacro UAC_AsUser_Call Function CopyIniToAppData ${UAC_SYNCREGISTERS}
+ ${If} $0 = 1
+ ; Copy succeeded
+ Delete "$INSTDIR\Rainmeter.ini"
+ ${Else}
+ MessageBox MB_OK|MB_ICONSTOP "$(SETTINGSMOVEERROR)"
+ ${EndIf}
+SkipIniMove:
+ ${EndIf}
+ ${Else}
+ ReadINIStr $0 "$INSTDIR\Rainmeter.ini" "Rainmeter" "SkinPath"
+ ${If} $0 == "$INSTDIR\Skins\"
+ DeleteINIStr "$INSTDIR\Rainmeter.ini" "Rainmeter" "SkinPath"
+ ${EndIf}
+ ${EndIf}
+ ${EndIf}
+
+ SetOutPath "$INSTDIR"
+
+ ; Cleanup old stuff
+ Delete "$INSTDIR\Rainmeter.chm"
+ Delete "$INSTDIR\Default.ini"
+ Delete "$INSTDIR\Launcher.exe"
+ Delete "$INSTDIR\Defaults\Plugins\FileView.dll"
+ RMDir /r "$INSTDIR\Addons\Rainstaller"
+ RMDir /r "$INSTDIR\Addons\RainBackup"
+
+ ${If} $InstallPortable <> 1
+ CreateDirectory "$INSTDIR\Defaults"
+ Rename "$INSTDIR\Skins" "$INSTDIR\Defaults\Skins"
+
+ Rename "$INSTDIR\Themes" "$INSTDIR\Defaults\Layouts"
+ Rename "$INSTDIR\Defaults\Themes" "$INSTDIR\Defaults\Layouts"
+ ${Locate} "$INSTDIR\Defaults\Layouts" "/L=F /M=Rainmeter.thm /G=1" "RenameToRainmeterIni"
+
+ ${If} ${FileExists} "$INSTDIR\Addons\Backup"
+ ${OrIf} ${FileExists} "$INSTDIR\Plugins\Backup"
+ CreateDirectory "$INSTDIR\Defaults\Backup"
+ Rename "$INSTDIR\Addons\Backup" "$INSTDIR\Defaults\Backup\Addons"
+ Rename "$INSTDIR\Plugins\Backup" "$INSTDIR\Defaults\Backup\Plugins"
+ ${EndIf}
+
+ Rename "$INSTDIR\Addons" "$INSTDIR\Defaults\Addons"
+ ${Locate} "$INSTDIR\Plugins" "/L=F /M=*.dll /G=0" "MoveNonDefaultPlugins"
+ ${EndIf}
+
+!ifdef INCLUDEFILES
+ File "..\..\Application\Rainmeter.exe.config"
+
+ ${If} $instArc == "x86"
+ !insertmacro InstallFiles "x32" "x86"
+ ${Else}
+ !insertmacro InstallFiles "x64" "x64"
+ ${EndIf}
+
+ RMDir /r "$INSTDIR\Languages"
+ SetOutPath "$INSTDIR\Languages"
+ File "..\..\x32-Release\Languages\*.*"
+
+ SetOutPath "$INSTDIR\Defaults\Skins"
+ RMDir /r "$INSTDIR\Skins\illustro"
+ Delete "$INSTDIR\Skins\*.txt"
+ File /r "..\Skins\*.*"
+
+ SetOutPath "$INSTDIR\Defaults\Layouts"
+ File /r "..\Layouts\*.*"
+!endif
+
+ SetOutPath "$INSTDIR"
+
+ ${If} $InstallPortable <> 1
+ ReadRegStr $0 HKLM "SOFTWARE\Rainmeter" ""
+ WriteRegStr HKLM "SOFTWARE\Rainmeter" "" "$INSTDIR"
+ WriteRegStr HKLM "SOFTWARE\Rainmeter" "Language" "$LANGUAGE"
+ WriteRegDWORD HKLM "SOFTWARE\Rainmeter" "NonDefault" $NonDefaultLanguage
+
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "DisplayName" "Rainmeter"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "DisplayIcon" "$INSTDIR\Rainmeter.exe,0"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "URLInfoAbout" "http://rainmeter.net"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "UninstallString" "$INSTDIR\uninst.exe"
+
+!ifdef BETA
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "DisplayVersion" "${VERSION_SHORT} beta r${VERSION_REVISION}"
+!else
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "DisplayVersion" "${VERSION_SHORT} r${VERSION_REVISION}"
+!endif
+
+ ; Create .rmskin association
+ WriteRegStr HKCR ".rmskin" "" "Rainmeter.SkinInstaller"
+ DeleteRegKey HKCR "Rainmeter skin" ; Old key
+ WriteRegStr HKCR "Rainmeter.SkinInstaller" "" "Rainmeter Skin Installer"
+ WriteRegStr HKCR "Rainmeter.SkinInstaller\shell" "" "open"
+ WriteRegStr HKCR "Rainmeter.SkinInstaller\DefaultIcon" "" "$INSTDIR\SkinInstaller.exe,0"
+ WriteRegStr HKCR "Rainmeter.SkinInstaller\shell\open\command" "" '"$INSTDIR\SkinInstaller.exe" %1'
+ WriteRegStr HKCR "Rainmeter.SkinInstaller\shell\edit" "" "Install Rainmeter skin"
+ WriteRegStr HKCR "Rainmeter.SkinInstaller\shell\edit\command" "" '"$INSTDIR\SkinInstaller.exe" %1'
+
+ ; If .inc isn't associated, use the .ini association for it.
+ ReadRegStr $1 HKCR ".inc" ""
+ ${If} $1 == ""
+ ReadRegStr $1 HKCR ".ini" ""
+ ${If} $1 != ""
+ WriteRegStr HKCR ".inc" "" "$1"
+ ${EndIf}
+ ${EndIf}
+
+ ; Refresh shell icons if new install
+ ${If} $0 == ""
+ ${RefreshShellIcons}
+ ${EndIf}
+
+ ; Remove all start menu shortcuts
+ SetShellVarContext all
+ Call RemoveStartMenuShortcuts
+
+ StrCpy $0 "$SMPROGRAMS\Rainmeter.lnk"
+ ${If} ${FileExists} "$SMPROGRAMS\Rainmeter"
+ StrCpy $0 "$SMPROGRAMS\Rainmeter\Rainmeter.lnk"
+ ${EndIf}
+ CreateShortcut "$0" "$INSTDIR\Rainmeter.exe" "" "$INSTDIR\Rainmeter.exe" 0
+
+ ${If} $AutoStartup = 1
+ ${If} ${FileExists} "$SMSTARTUP\Rainmeter.lnk"
+ ; Remove user shortcut to prevent duplicate with all users shortcut
+ !insertmacro UAC_AsUser_Call Function RemoveUserStartupShortcut ${UAC_SYNCREGISTERS}
+ ${Else}
+ !insertmacro UAC_AsUser_Call Function CreateUserStartupShortcut ${UAC_SYNCREGISTERS}
+ ${EndIf}
+ ${EndIf}
+
+ SetShellVarContext current
+ Call RemoveStartMenuShortcuts
+
+ !insertmacro UAC_AsUser_Call Function RemoveStartMenuShortcuts ${UAC_SYNCREGISTERS}
+
+ WriteUninstaller "$INSTDIR\uninst.exe"
+ ${Else}
+ ${IfNot} ${FileExists} "Rainmeter.ini"
+ CopyFiles /SILENT "$INSTDIR\Defaults\Layouts\illustro default\Rainmeter.ini" "$INSTDIR\Rainmeter.ini"
+ ${EndIf}
+
+ WriteINIStr "$INSTDIR\Rainmeter.ini" "Rainmeter" "Language" "$LANGUAGE"
+ ${EndIf}
+SectionEnd
+
+Function CopyIniToAppData
+ ClearErrors
+ CreateDirectory "$APPDATA\Rainmeter"
+ CopyFiles /SILENT "$INSTDIR\Rainmeter.ini" "$APPDATA\Rainmeter\Rainmeter.ini"
+ ${If} ${Errors}
+ StrCpy $0 0
+ ${EndIf}
+FunctionEnd
+
+Function RenameToRainmeterIni
+ ${If} ${FileExists} "$R8\Rainmeter.ini"
+ Delete "$R8\Rainmeter.thm"
+ ${Else}
+ Rename "$R9" "$R8\Rainmeter.ini"
+ ${EndIf}
+
+ Push $0
+FunctionEnd
+
+Function MoveNonDefaultPlugins
+ ${If} $R7 != "AdvancedCPU.dll"
+ ${AndIf} $R7 != "CoreTemp.dll"
+ ${AndIf} $R7 != "FileView.dll"
+ ${AndIf} $R7 != "FolderInfo.dll"
+ ${AndIf} $R7 != "InputText.dll"
+ ${AndIf} $R7 != "iTunesPlugin.dll"
+ ${AndIf} $R7 != "MediaKey.dll"
+ ${AndIf} $R7 != "NowPlaying.dll"
+ ${AndIf} $R7 != "PerfMon.dll"
+ ${AndIf} $R7 != "PingPlugin.dll"
+ ${AndIf} $R7 != "PowerPlugin.dll"
+ ${AndIf} $R7 != "Process.dll"
+ ${AndIf} $R7 != "QuotePlugin.dll"
+ ${AndIf} $R7 != "RecycleManager.dll"
+ ${AndIf} $R7 != "ResMon.dll"
+ ${AndIf} $R7 != "SpeedFanPlugin.dll"
+ ${AndIf} $R7 != "SysInfo.dll"
+ ${AndIf} $R7 != "VirtualDesktops.dll"
+ ${AndIf} $R7 != "WebParser.dll"
+ ${AndIf} $R7 != "WifiStatus.dll"
+ ${AndIf} $R7 != "Win7AudioPlugin.dll"
+ ${AndIf} $R7 != "WindowMessagePlugin.dll"
+ CreateDirectory "$INSTDIR\Defaults\Plugins"
+ Delete "$INSTDIR\Defaults\Plugins\$R7"
+ Rename "$R9" "$INSTDIR\Defaults\Plugins\$R7"
+ ${EndIf}
+
+ Push $0
+FunctionEnd
+
+Function RemoveStartMenuShortcuts
+ !insertmacro RemoveStartMenuShortcuts "$SMPROGRAMS\Rainmeter"
+FunctionEnd
+
+Function CreateUserStartupShortcut
+ SetShellVarContext current
+ CreateShortcut "$SMSTARTUP\Rainmeter.lnk" "$INSTDIR\Rainmeter.exe" "" "$INSTDIR\Rainmeter.exe" 0
+FunctionEnd
+
+Function RemoveUserStartupShortcut
+ SetShellVarContext current
+ Delete "$SMSTARTUP\Rainmeter.lnk"
+FunctionEnd
+
+Function FinishRun
+ !insertmacro UAC_AsUser_ExecShell "" "$INSTDIR\Rainmeter.exe" "" "" ""
+FunctionEnd
+
+
+; Uninstall
+; --------------------------------------
+Function un.onInit
+UAC_TryAgain:
+ ; Request administrative rights
+ !insertmacro UAC_RunElevated
+ ${Switch} $0
+ ${Case} 0
+ ${IfThen} $1 = 1 ${|} Quit ${|}
+ ${IfThen} $3 <> 0 ${|} ${Break} ${|}
+ ${If} $1 = 3
+ MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(ADMINERROR)" /SD IDNO IDOK UAC_TryAgain IDNO 0
+ ${EndIf}
+ ${Case} 1223
+ Quit
+ ${Case} 1062
+ MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(LOGONERROR)"
+ Quit
+ ${Default}
+ MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(UACERROR) ($0)"
+ Quit
+ ${EndSwitch}
+
+ ReadRegStr $0 HKLM "SOFTWARE\Rainmeter" "Language"
+ ${If} $0 != ""
+ StrCpy $LANGUAGE $0
+ ${EndIf}
+FunctionEnd
+
+Function un.PageOptions
+ !insertmacro MUI_HEADER_TEXT "$(UNSTALLOPTIONS)" "$(UNSTALLOPTIONSDESC)"
+ nsDialogs::Create 1018
+ nsDialogs::SetRTL $(^RTL)
+
+ ${NSD_CreateCheckbox} 0 0u 95% 12u "$(UNSTALLRAINMETER)"
+ Pop $0
+ EnableWindow $0 0
+ ${NSD_Check} $0
+
+ ${NSD_CreateCheckbox} 0 15u 70% 12u "$(UNSTALLSETTINGS)"
+ Pop $R0
+
+ ${NSD_CreateLabel} 16 26u 95% 12u "$(UNSTALLSETTINGSDESC)"
+
+ nsDialogs::Show
+FunctionEnd
+
+Function un.GetOptions
+ ${NSD_GetState} $R0 $un.DeleteAll
+FunctionEnd
+
+Section Uninstall
+ ; Close Rainmeter (and wait up to five seconds)
+ ${ForEach} $0 10 0 - 1
+ FindWindow $1 "DummyRainWClass" "Rainmeter control window"
+ ClearErrors
+ Delete "$INSTDIR\Rainmeter.exe"
+ ${If} $1 = 0
+ ${AndIfNot} ${Errors}
+ ${Break}
+ ${EndIf}
+
+ SendMessage $1 ${WM_CLOSE} 0 0
+
+ ${If} $0 = 0
+ ${If} ${Silent}
+ SetErrorLevel ${ERROR_CLOSEFAIL}
+ Quit
+ ${Else}
+ MessageBox MB_RETRYCANCEL|MB_ICONSTOP "$(RAINMETERCLOSEERROR)" IDRETRY +2
+ Quit
+ ${EndIf}
+ ${EndIf}
+
+ Sleep 500
+ ${Next}
+
+ ; Old stuff
+ RMDir /r "$INSTDIR\Addons"
+ RMDir /r "$INSTDIR\Fonts"
+
+ RMDir /r "$INSTDIR\Defaults"
+ RMDir /r "$INSTDIR\Languages"
+ RMDir /r "$INSTDIR\Plugins"
+ RMDir /r "$INSTDIR\Runtime"
+ RMDir /r "$INSTDIR\Skins"
+ Delete "$INSTDIR\Rainmeter.dll"
+ Delete "$INSTDIR\Rainmeter.exe"
+ Delete "$INSTDIR\Rainmeter.exe.config"
+ Delete "$INSTDIR\SkinInstaller.exe"
+ Delete "$INSTDIR\SkinInstaller.dll"
+ Delete "$INSTDIR\uninst.exe"
+
+ RMDir "$INSTDIR"
+
+ SetShellVarContext all
+ RMDir /r "$APPDATA\Rainstaller"
+
+ SetShellVarContext current
+ Call un.RemoveShortcuts
+ ${If} $un.DeleteAll = 1
+ RMDir /r "$APPDATA\Rainmeter"
+ RMDir /r "$DOCUMENTS\Rainmeter\Skins"
+ RMDir "$DOCUMENTS\Rainmeter"
+ RMDir /r "$1\Rainmeter"
+ ${EndIf}
+
+ !insertmacro UAC_AsUser_Call Function un.RemoveShortcuts ${UAC_SYNCREGISTERS}
+ ${If} $un.DeleteAll = 1
+ RMDir /r "$APPDATA\Rainmeter"
+ RMDir /r "$DOCUMENTS\Rainmeter\Skins"
+ RMDir "$DOCUMENTS\Rainmeter"
+ ${EndIf}
+
+ SetShellVarContext all
+ Call un.RemoveShortcuts
+ Delete "$SMPROGRAMS\Rainmeter.lnk"
+
+ DeleteRegKey HKLM "SOFTWARE\Rainmeter"
+ DeleteRegKey HKCR ".rmskin"
+ DeleteRegKey HKCR "Rainmeter.SkinInstaller"
+ DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter"
+ ${RefreshShellIcons}
+SectionEnd
+
+Function un.RemoveShortcuts
+ !insertmacro RemoveStartMenuShortcuts "$SMPROGRAMS\Rainmeter"
+ Delete "$SMSTARTUP\Rainmeter.lnk"
+ Delete "$DESKTOP\Rainmeter.lnk"
+FunctionEnd
diff --git a/BuildTools/Installer/MD5.dll b/BuildTools/Installer/MD5.dll
new file mode 100644
index 00000000..bde153f7
Binary files /dev/null and b/BuildTools/Installer/MD5.dll differ
diff --git a/BuildTools/Installer/MoreInfo.dll b/BuildTools/Installer/MoreInfo.dll
new file mode 100644
index 00000000..274d9819
Binary files /dev/null and b/BuildTools/Installer/MoreInfo.dll differ
diff --git a/BuildTools/Installer/UAC.dll b/BuildTools/Installer/UAC.dll
new file mode 100644
index 00000000..ccaa050e
Binary files /dev/null and b/BuildTools/Installer/UAC.dll differ
diff --git a/BuildTools/Installer/UAC.nsh b/BuildTools/Installer/UAC.nsh
new file mode 100644
index 00000000..3f2c11cc
--- /dev/null
+++ b/BuildTools/Installer/UAC.nsh
@@ -0,0 +1,200 @@
+!ifndef UAC_HDR__INC
+!verbose push
+!verbose 3
+!ifndef UAC_VERBOSE
+ !define UAC_VERBOSE 3
+!endif
+!verbose ${UAC_VERBOSE}
+
+!define UAC_HDR__INC 0x00020204 ;MMmmbbrr
+
+!include LogicLib.nsh
+
+!macro _UAC_definemath def val1 op val2
+!define /math _UAC_definemath "${val1}" ${op} ${val2}
+!ifdef ${def}
+ !undef ${def}
+!endif
+!define ${def} "${_UAC_definemath}"
+!undef _UAC_definemath
+!macroend
+
+!macro _UAC_ParseDefineFlags_orin parse outflags
+!searchparse /noerrors ${${parse}} "" _UAC_ParseDefineFlags_orin_f1 "|" _UAC_ParseDefineFlags_orin_f2
+!define _UAC_ParseDefineFlags_orin_this ${_UAC_ParseDefineFlags_orin_f1}
+!undef ${parse}
+!define ${parse} ${_UAC_ParseDefineFlags_orin_f2}
+!define _UAC_ParseDefineFlags_orin_saveout ${${outflags}}
+!undef ${outflags}
+!define /math ${outflags} "${_UAC_ParseDefineFlags_orin_saveout}" | "${_UAC_ParseDefineFlags_orin_this}"
+!undef _UAC_ParseDefineFlags_orin_saveout
+!undef _UAC_ParseDefineFlags_orin_this
+!ifdef _UAC_ParseDefineFlags_orin_f1
+ !undef _UAC_ParseDefineFlags_orin_f1
+ !undef _UAC_ParseDefineFlags_orin_f2
+!endif
+!macroend
+!macro _UAC_ParseDefineFlags_Begin _outdef _in
+!define _UAC_PDF${_outdef}_parse "${_in}"
+!define _UAC_PDF${_outdef}_flags ""
+!define _UAC_PDF${_outdef}_r 0
+!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x1
+!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x2
+!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x4
+!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x8
+!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x10
+!macroend
+!macro _UAC_ParseDefineFlags_End _outdef
+!define ${_outdef} ${_UAC_PDF${_outdef}_r}
+!undef _UAC_PDF${_outdef}_r
+!undef _UAC_PDF${_outdef}_flags
+!undef _UAC_PDF${_outdef}_parse
+!macroend
+!macro _UAC_ParseDefineFlags_IncludeFlag _outdef flag
+!if ${_UAC_PDF${_outdef}_flags} & ${flag}
+ !insertmacro _UAC_definemath _UAC_PDF${_outdef}_r ${_UAC_PDF${_outdef}_r} | ${flag}
+!endif
+!macroend
+!macro _UAC_ParseDefineFlagsToInt _outdef _in
+!insertmacro _UAC_ParseDefineFlags_Begin _UAC_ParseDefineFlagsToInt_tmp "${_in}"
+!define ${_outdef} ${_UAC_PDF_UAC_ParseDefineFlagsToInt_tmp_flags}
+!insertmacro _UAC_ParseDefineFlags_End _UAC_ParseDefineFlagsToInt_tmp
+!undef _UAC_ParseDefineFlagsToInt_tmp
+!macroend
+
+!macro _UAC_IncL
+!insertmacro _UAC_definemath __UAC_L "${__UAC_L}" + 1
+!macroend
+
+
+!macro _UAC_MakeLL_Cmp cmpop cmp pluginparams
+!insertmacro _LOGICLIB_TEMP
+UAC::_ ${pluginparams}
+pop $_LOGICLIB_TEMP
+!insertmacro ${cmpop} $_LOGICLIB_TEMP ${cmp} `${_t}` `${_f}`
+!macroend
+
+
+!macro UAC_RunElevated
+UAC::_ 0
+!macroend
+!macro UAC_PageElevation_RunElevated
+UAC::_ 0
+!macroend
+/*!macro UAC_OnInitElevation_RunElevated
+UAC::_ 0
+!macroend
+!macro UAC_OnInitElevation_OnGuiInit
+!macroend*/
+
+
+!macro UAC_IsAdmin
+UAC::_ 2
+!macroend
+!define UAC_IsAdmin `"" UAC_IsAdmin ""`
+!macro _UAC_IsAdmin _a _b _t _f
+!insertmacro _UAC_MakeLL_Cmp _!= 0 2s
+!macroend
+
+
+
+!macro UAC_IsInnerInstance
+UAC::_ 3
+!macroend
+!define UAC_IsInnerInstance `"" UAC_IsInnerInstance ""`
+!macro _UAC_IsInnerInstance _a _b _t _f
+!insertmacro _UAC_MakeLL_Cmp _!= 0 3s
+!macroend
+
+!macro UAC_Notify_OnGuiInit
+UAC::_ 4
+!macroend
+!macro UAC_PageElevation_OnGuiInit
+!insertmacro UAC_Notify_OnGuiInit
+!macroend
+!macro UAC_PageElevation_OnInit
+UAC::_ 5
+${IfThen} ${Errors} ${|} Quit ${|}
+!macroend
+
+
+!define UAC_SYNCREGISTERS 0x1
+#!define UAC_SYNCSTACK 0x2
+!define UAC_SYNCOUTDIR 0x4
+!define UAC_SYNCINSTDIR 0x8
+#!define UAC_CLEARERRFLAG 0x10
+!macro UAC_AsUser_Call type name flags
+push $0
+Get${type}Address $0 ${name}
+!verbose push
+!verbose ${UAC_VERBOSE}
+!insertmacro _UAC_ParseDefineFlagsToInt _UAC_AsUser_Call__flags ${flags}
+!verbose pop
+StrCpy $0 "1$0:${_UAC_AsUser_Call__flags}"
+!undef _UAC_AsUser_Call__flags
+Exch $0
+UAC::_
+!macroend
+
+!macro _UAC_AsUser_GenOp outvar op opparam1 opparam2
+!define _UAC_AUGOGR_ID _UAC_AUGOGR_OP${outvar}${op}${opparam1}${opparam2}
+!ifndef ${_UAC_AUGOGR_ID} ;Has this exact action been done before?
+ !if ${outvar} == $0
+ !define ${_UAC_AUGOGR_ID} $1
+ !else
+ !define ${_UAC_AUGOGR_ID} $0
+ !endif
+ !if "${opparam1}" == ""
+ !define _UAC_AUGOGR_OPP1 ${${_UAC_AUGOGR_ID}}
+ !define _UAC_AUGOGR_OPP2 ${opparam2}
+ !else
+ !define _UAC_AUGOGR_OPP1 ${opparam1}
+ !define _UAC_AUGOGR_OPP2 ${${_UAC_AUGOGR_ID}}
+ !endif
+ goto ${_UAC_AUGOGR_ID}_C
+ ${_UAC_AUGOGR_ID}_F:
+ ${op} ${_UAC_AUGOGR_OPP1} ${_UAC_AUGOGR_OPP2}
+ return
+ ${_UAC_AUGOGR_ID}_C:
+ !undef _UAC_AUGOGR_OPP1
+ !undef _UAC_AUGOGR_OPP2
+!endif
+push ${${_UAC_AUGOGR_ID}}
+!insertmacro UAC_AsUser_Call Label ${_UAC_AUGOGR_ID}_F ${UAC_SYNCREGISTERS}
+StrCpy ${outvar} ${${_UAC_AUGOGR_ID}}
+pop ${${_UAC_AUGOGR_ID}}
+!undef _UAC_AUGOGR_ID
+!macroend
+
+!macro UAC_AsUser_GetSection datatype secidx outvar
+!insertmacro _UAC_AsUser_GenOp ${outvar} SectionGet${datatype} ${secidx} ""
+!macroend
+
+!macro UAC_AsUser_GetGlobalVar var
+!insertmacro _UAC_AsUser_GenOp ${var} StrCpy "" ${var}
+!macroend
+!macro UAC_AsUser_GetGlobal outvar srcvar
+!insertmacro _UAC_AsUser_GenOp ${outvar} StrCpy "" ${srcvar}
+!macroend
+
+
+!macro UAC_AsUser_ExecShell verb command params workdir show
+!insertmacro _UAC_IncL
+goto _UAC_L_E_${__UAC_L}
+_UAC_L_F_${__UAC_L}:
+ExecShell "${verb}" "${command}" ${params} ${show}
+return
+_UAC_L_E_${__UAC_L}:
+!if "${workdir}" != ""
+ push $outdir
+ SetOutPath "${workdir}"
+!endif
+!insertmacro UAC_AsUser_Call Label _UAC_L_F_${__UAC_L} ${UAC_SYNCREGISTERS}|${UAC_SYNCOUTDIR}|${UAC_SYNCINSTDIR} #|${UAC_CLEARERRFLAG}
+!if "${workdir}" != ""
+ pop $outdir
+ SetOutPath $outdir
+!endif
+!macroend
+
+!verbose pop
+!endif /* UAC_HDR__INC */
\ No newline at end of file
diff --git a/BuildTools/Installer/Wizard.bmp b/BuildTools/Installer/Wizard.bmp
new file mode 100644
index 00000000..c9c7eddf
Binary files /dev/null and b/BuildTools/Installer/Wizard.bmp differ
diff --git a/BuildTools/Layouts/illustro default/Rainmeter.ini b/BuildTools/Layouts/illustro default/Rainmeter.ini
new file mode 100644
index 00000000..b362333b
--- /dev/null
+++ b/BuildTools/Layouts/illustro default/Rainmeter.ini
@@ -0,0 +1,23 @@
+[Rainmeter]
+
+[illustro\Clock]
+Active=1
+WindowX=(#SCREENAREAWIDTH#-200)
+WindowY=0
+
+[illustro\Disk]
+Active=2
+WindowX=(#SCREENAREAWIDTH#-200)
+WindowY=176
+
+[illustro\System]
+Active=1
+WindowX=(#SCREENAREAWIDTH#-200)
+WindowY=68
+
+[illustro\Welcome]
+Active=1
+WindowX=50.000000%
+WindowY=50.000000%
+AnchorX=50.000000%
+AnchorY=50.000000%
\ No newline at end of file
diff --git a/BuildTools/Skins/illustro/@Resources/Background.png b/BuildTools/Skins/illustro/@Resources/Background.png
new file mode 100644
index 00000000..1aa0d7d0
Binary files /dev/null and b/BuildTools/Skins/illustro/@Resources/Background.png differ
diff --git a/BuildTools/Skins/illustro/Clock/Clock.ini b/BuildTools/Skins/illustro/Clock/Clock.ini
new file mode 100644
index 00000000..3bcb981d
--- /dev/null
+++ b/BuildTools/Skins/illustro/Clock/Clock.ini
@@ -0,0 +1,138 @@
+; Lines starting ; (semicolons) are commented out.
+; That is, they do not affect the code and are here for demonstration purposes only.
+; ----------------------------------
+
+[Rainmeter]
+; This section contains general settings that can be used to change how Rainmeter behaves.
+Author=poiru
+AppVersion=2003000
+Update=1000
+Background=#@#Background.png
+; #@# is equal to Rainmeter\Skins\illustro\@Resources
+BackgroundMode=3
+BackgroundMargins=0,34,0,14
+
+[Metadata]
+; Contains basic information of the skin.
+Description=Displays the current date and time.
+License=Creative Commons BY-NC-SA 3.0
+Version=1.0.0
+
+[Variables]
+; Variables declared here can be used later on between two # characters (e.g. #MyVariable#).
+fontName=Trebuchet MS
+textSize=8
+colorBar=235,170,0,255
+colorText=255,255,255,205
+
+; ----------------------------------
+; MEASURES return some kind of value
+; ----------------------------------
+
+[measureTime]
+; This measure returns the time in a 24-hour format (i.e. HH:MM).
+Measure=Time
+Format=%H:%M
+; For a 12-hour clock, change the Format option above to: %I:%M %p
+; Refer to the Rainmeter manual for other format codes.
+
+[measureDate]
+; Returns the date as DD.MM.YYYY
+Measure=Time
+Format=%d.%m.%Y
+
+[measureDay]
+; Returns the current day
+Measure=Time
+Format=%A
+
+; ----------------------------------
+; STYLES are used to "centralize" options
+; ----------------------------------
+
+[styleTitle]
+StringAlign=CENTER
+StringCase=UPPER
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,50
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=10
+AntiAlias=1
+ClipString=1
+
+[styleLeftText]
+StringAlign=LEFT
+; Meters using styleLeftText will be left-aligned.
+StringCase=NONE
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,20
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=#textSize#
+AntiAlias=1
+ClipString=1
+
+[styleRightText]
+StringAlign=RIGHT
+StringCase=NONE
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,20
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=#textSize#
+AntiAlias=1
+ClipString=1
+
+[styleSeperator]
+SolidColor=255,255,255,15
+
+; ----------------------------------
+; METERS display images, text, bars, etc.
+; ----------------------------------
+
+[meterTitle]
+Meter=STRING
+MeterStyle=styleTitle
+; Using MeterStyle=styleTitle will basically "copy" the
+; contents of the [styleTitle] section here during runtime.
+MeasureName=measureTime
+X=100
+Y=12
+W=190
+H=18
+Text="%1"
+; %1 stands for the value of MeasureName (measureTime in this case).
+
+[meterDay]
+Meter=STRING
+MeterStyle=styleLeftText
+MeasureName=measureDay
+X=10
+Y=40
+W=190
+H=14
+Text="%1"
+
+[meterDate]
+Meter=STRING
+MeterStyle=styleRightText
+MeasureName=measureDate
+X=200
+Y=0r
+; r stands for relative. In this case, the Y postition of meterValueCPU is 0 pixels
+; below the Y value of the previous meter (i.e it's the same as in meterLabelCPU).
+W=190
+H=14
+Text="%1"
+
+[meterSeperator]
+Meter=IMAGE
+MeterStyle=styleSeperator
+X=10
+Y=52
+W=190
+H=1
\ No newline at end of file
diff --git a/BuildTools/Skins/illustro/Disk/1 Disk.ini b/BuildTools/Skins/illustro/Disk/1 Disk.ini
new file mode 100644
index 00000000..669723bd
--- /dev/null
+++ b/BuildTools/Skins/illustro/Disk/1 Disk.ini
@@ -0,0 +1,149 @@
+; Lines starting ; (semicolons) are commented out.
+; That is, they do not affect the code and are here for demonstration purposes only.
+; ----------------------------------
+
+; NOTE! If you want to add more disks, take a look at 'Disks 2.ini'.
+
+[Rainmeter]
+; This section contains general settings that can be used to change how Rainmeter behaves.
+Author=poiru
+AppVersion=2003000
+Update=1000
+Background=#@#Background.png
+; #@# is equal to Rainmeter\Skins\illustro\@Resources
+BackgroundMode=3
+BackgroundMargins=0,34,0,14
+
+[Metadata]
+; Contains basic information of the skin.
+Description=Displays disk usage.
+License=Creative Commons BY-NC-SA 3.0
+Version=1.0.0
+
+[Variables]
+; Variables declared here can be used later on between two # characters (e.g. #MyVariable#).
+fontName=Trebuchet MS
+textSize=8
+colorBar=235,170,0,255
+colorText=255,255,255,205
+disk1=C:
+
+; ----------------------------------
+; MEASURES return some kind of value
+; ----------------------------------
+
+[measureTotalDisk1]
+; This measure returns the total disk space
+Measure=FreeDiskSpace
+Drive=#disk1#
+Total=1
+UpdateDivider=120
+
+[measureUsedDisk1]
+; Returns inverted value of free disk space (i.e. used disk space)
+Measure=FreeDiskSpace
+Drive=#disk1#
+InvertMeasure=1
+UpdateDivider=120
+
+; ----------------------------------
+; STYLES are used to "centralize" options
+; ----------------------------------
+
+[styleTitle]
+StringAlign=CENTER
+StringCase=UPPER
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,50
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=10
+AntiAlias=1
+ClipString=1
+
+[styleLeftText]
+StringAlign=LEFT
+; Meters using styleLeftText will be left-aligned.
+StringCase=NONE
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,20
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=#textSize#
+AntiAlias=1
+ClipString=1
+
+[styleRightText]
+StringAlign=RIGHT
+StringCase=NONE
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,20
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=#textSize#
+AntiAlias=1
+ClipString=1
+
+[styleBar]
+BarColor=#colorBar#
+BarOrientation=HORIZONTAL
+SolidColor=255,255,255,15
+
+; ----------------------------------
+; METERS display images, text, bars, etc.
+; ----------------------------------
+
+[meterTitle]
+Meter=STRING
+MeterStyle=styleTitle
+; Using MeterStyle=styleTitle will basically "copy" the
+; contents of the [styleTitle] section here during runtime.
+X=100
+Y=12
+W=190
+H=18
+Text="Disks"
+; Even though the text is set to Disks, Rainmeter will display
+; it as DISKS, because styleTitle contains StringCase=UPPER.
+
+[meterLabelDisk1]
+Meter=STRING
+MeterStyle=styleLeftText
+X=10
+Y=40
+W=190
+H=14
+Text="#disk1#\"
+
+[meterValueDisk1]
+Meter=STRING
+MeterStyle=styleRightText
+MeasureName=measureUsedDisk1
+MeasureName2=measureTotalDisk1
+X=200
+Y=0r
+; r stands for relative. In this case, the Y postition of meterValueCPU is 0 pixels
+; below the Y value of the previous meter (i.e it's the same as in meterLabelCPU).
+W=190
+H=14
+Text="%1B/%2B used"
+; %1 stands for the value of MeasureName (measureUsedDisk1 in this case).
+; %2 stands for the value of MeasureName2.
+NumOfDecimals=1
+AutoScale=1
+; Because disk measures return the free/used space in bytes, we must use AutoScale=1 to
+; automatically scale the value into a more readable figure.
+LeftMouseUpAction=!Execute ["#disk1#\"]
+; Open #disk1# on click
+
+[meterBarDisk1]
+Meter=BAR
+MeterStyle=styleBar
+MeasureName=measureUsedDisk1
+X=10
+Y=52
+W=190
+H=1
\ No newline at end of file
diff --git a/BuildTools/Skins/illustro/Disk/2 Disks.ini b/BuildTools/Skins/illustro/Disk/2 Disks.ini
new file mode 100644
index 00000000..e255501a
--- /dev/null
+++ b/BuildTools/Skins/illustro/Disk/2 Disks.ini
@@ -0,0 +1,209 @@
+; Lines starting ; (semicolons) are commented out.
+; That is, they do not affect the code and are here for demonstration purposes only.
+; ----------------------------------
+
+; HOWTO: Adding more disks
+; ----------------------------------
+; Adding more disks is a pretty straightforward process. Follow the following steps to turn
+; this 2 disks skin into a 3 disks skin. You can then extend it even further as you wish.
+;
+; 1) Create a new variable called disk3=X: directly below disk2=D: in the [Variables] section
+; 2) Create a copy of the [measureTotalDisk2] and [measureUsedDisk2] sections
+; 3) Rename the copied sections to [measureTotalDisk3] and [measureUsedDisk3], respectively.
+; Also change Drive=#disk2# to Drive=#disk3#
+; 4) Create a copy of the [meterLabelDisk2], [meterValueDisk2], and [meterBarDisk2].
+; Rename all Disk2's in the copied sections to Disk3.
+; 5) Now we need to change the Y= values to adjust height. Change Y= under [meterLabelDisk3]
+; to Y=80 (calculated by adding 20 to the Y= value of previous meterLabel).
+; Then change Y= under [meterBarDisk3] to Y=92 (calculated by adding 20 to the Y= value of previous meterBar).
+; 6) Save the file as '3 Disks.ini'. Now right-click on the Rainmeter tray icon and select
+; 'Refresh All'. Now go activate the '3 Disks.ini' skin and enjoy! :)
+
+[Rainmeter]
+; This section contains general settings that can be used to change how Rainmeter behaves.
+Author=poiru
+AppVersion=2003000
+Update=1000
+Background=#@#Background.png
+; #@# is equal to Rainmeter\Skins\illustro\@Resources
+BackgroundMode=3
+BackgroundMargins=0,34,0,14
+
+[Metadata]
+; Contains basic information of the skin.
+Description=Displays disk usage.
+License=Creative Commons BY-NC-SA 3.0
+Version=1.0.0
+
+[Variables]
+; Variables declared here can be used later on between two # characters (e.g. #MyVariable#).
+fontName=Trebuchet MS
+textSize=8
+colorBar=235,170,0,255
+colorText=255,255,255,205
+disk1=C:
+disk2=D:
+
+; ----------------------------------
+; MEASURES return some kind of value
+; ----------------------------------
+
+[measureTotalDisk1]
+; This measure returns the total disk space
+Measure=FreeDiskSpace
+Drive=#disk1#
+Total=1
+UpdateDivider=120
+
+[measureUsedDisk1]
+; Returns inverted value of free disk space (i.e. used disk space)
+Measure=FreeDiskSpace
+Drive=#disk1#
+InvertMeasure=1
+UpdateDivider=120
+
+[measureTotalDisk2]
+Measure=FreeDiskSpace
+Drive=#disk2#
+Total=1
+UpdateDivider=120
+
+[measureUsedDisk2]
+Measure=FreeDiskSpace
+Drive=#disk2#
+InvertMeasure=1
+UpdateDivider=120
+
+; ----------------------------------
+; STYLES are used to "centralize" options
+; ----------------------------------
+
+[styleTitle]
+StringAlign=CENTER
+StringCase=UPPER
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,50
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=10
+AntiAlias=1
+ClipString=1
+
+[styleLeftText]
+StringAlign=LEFT
+; Meters using styleLeftText will be left-aligned.
+StringCase=NONE
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,20
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=#textSize#
+AntiAlias=1
+ClipString=1
+
+[styleRightText]
+StringAlign=RIGHT
+StringCase=NONE
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,20
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=#textSize#
+AntiAlias=1
+ClipString=1
+
+[styleBar]
+BarColor=#colorBar#
+BarOrientation=HORIZONTAL
+SolidColor=255,255,255,15
+
+; ----------------------------------
+; METERS display images, text, bars, etc.
+; ----------------------------------
+
+[meterTitle]
+Meter=STRING
+MeterStyle=styleTitle
+; Using MeterStyle=styleTitle will basically "copy" the
+; contents of the [styleTitle] section here during runtime.
+X=100
+Y=12
+W=190
+H=18
+Text="Disk"
+; Even though the text is set to Disk, Rainmeter will display
+; it as DISK, because styleTitle contains StringCase=UPPER.
+
+[meterLabelDisk1]
+Meter=STRING
+MeterStyle=styleLeftText
+X=10
+Y=40
+W=190
+H=14
+Text="#disk1#\"
+
+[meterValueDisk1]
+Meter=STRING
+MeterStyle=styleRightText
+MeasureName=measureUsedDisk1
+MeasureName2=measureTotalDisk1
+X=200
+Y=0r
+; r stands for relative. In this case, the Y postition of meterValueCPU is 0 pixels
+; below the Y value of the previous meter (i.e it's the same as in meterLabelCPU).
+W=190
+H=14
+Text="%1B/%2B used"
+; %1 stands for the value of MeasureName (measureUsedDisk1 in this case).
+; %2 stands for the value of MeasureName2.
+NumOfDecimals=1
+AutoScale=1
+; Because disk measures return the free/used space in bytes, we must use AutoScale=1 to
+; automatically scale the value into a more readable figure.
+LeftMouseUpAction=!Execute ["#disk1#\"]
+; Open #disk1# on click
+
+[meterBarDisk1]
+Meter=BAR
+MeterStyle=styleBar
+MeasureName=measureUsedDisk1
+X=10
+Y=52
+W=190
+H=1
+
+[meterLabelDisk2]
+Meter=STRING
+MeterStyle=styleLeftText
+X=10
+Y=60
+W=190
+H=14
+Text="#disk2#\"
+LeftMouseUpAction=!Execute ["#disk2#\"]
+
+[meterValueDisk2]
+Meter=STRING
+MeterStyle=styleRightText
+MeasureName=measureUsedDisk2
+MeasureName2=measureTotalDisk2
+X=200
+Y=0r
+W=190
+H=14
+Text="%1B/%2B used"
+NumOfDecimals=1
+AutoScale=1
+
+[meterBarDisk2]
+Meter=BAR
+MeterStyle=styleBar
+MeasureName=measureUsedDisk2
+X=10
+Y=72
+W=190
+H=1
\ No newline at end of file
diff --git a/BuildTools/Skins/illustro/Google/Google.ini b/BuildTools/Skins/illustro/Google/Google.ini
new file mode 100644
index 00000000..07b32b6c
--- /dev/null
+++ b/BuildTools/Skins/illustro/Google/Google.ini
@@ -0,0 +1,119 @@
+; Lines starting ; (semicolons) are commented out.
+; That is, they do not affect the code and are here for demonstration purposes only.
+; ----------------------------------
+
+[Rainmeter]
+; This section contains general settings that can be used to change how Rainmeter behaves.
+Author=poiru
+AppVersion=2003000
+Update=1000
+Background=#@#Background.png
+; #@# is equal to Rainmeter\Skins\illustro\@Resources
+BackgroundMode=3
+BackgroundMargins=0,34,0,14
+
+[Metadata]
+; Contains basic information of the skin.
+Description=Allows searching through Google.
+License=Creative Commons BY-NC-SA 3.0
+Version=1.0.0
+
+[Variables]
+; Variables declared here can be used later on between two # characters (e.g. #MyVariable#).
+fontName=Trebuchet MS
+textSize=8
+colorBar=235,170,0,255
+colorText=255,255,255,205
+
+; ----------------------------------
+; MEASURES return some kind of value
+; ----------------------------------
+
+[measureInput]
+; The InputText.dll plugin has special powers: it allows user input.
+; However, it's not the easiest way to start learning Rainmeter. Get a
+; hold of the basics, and then check out the manual entry for InputText.
+Measure=Plugin
+Plugin=InputText.dll
+SolidColor=20,20,20,255
+StringAlign=LEFT
+StringCase=NONE
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,20
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=#textSize#
+X=10
+Y=38
+W=188
+H=17
+FocusDismiss=1
+DefaultValue=""
+Command1=!Execute ["http://www.google.com/search?q=$UserInput$"]
+UpdateDivider=86400
+
+; ----------------------------------
+; STYLES are used to "centralize" options
+; ----------------------------------
+
+[styleTitle]
+StringAlign=CENTER
+StringCase=UPPER
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,50
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=10
+AntiAlias=1
+ClipString=1
+
+[styleLeftText]
+StringAlign=LEFT
+; Meters using styleLeftText will be left-aligned.
+StringCase=NONE
+StringStyle=BOLD
+StringEffect=SHADOW
+FontEffectColor=0,0,0,20
+FontColor=#colorText#
+FontFace=#fontName#
+FontSize=#textSize#
+AntiAlias=1
+ClipString=1
+
+[styleSeperator]
+SolidColor=255,255,255,15
+
+; ----------------------------------
+; METERS display images, text, bars, etc.
+; ----------------------------------
+
+[meterTitle]
+Meter=STRING
+MeterStyle=styleTitle
+; Using MeterStyle=styleTitle will basically "copy" the
+; contents of the [styleTitle] section here during runtime.
+X=100
+Y=12
+W=190
+H=18
+Text="Google"
+
+[meterSearch]
+Meter=STRING
+MeterStyle=styleLeftText
+X=10
+Y=40
+W=190
+H=14
+Text="Search..."
+LeftMouseUpAction=!PluginBang "measureInput ExecuteBatch 1"
+
+[meterSeperator]
+Meter=IMAGE
+MeterStyle=styleSeperator
+X=10
+Y=52
+W=190
+H=1
\ No newline at end of file
diff --git a/BuildTools/Skins/illustro/Network/Network.ini b/BuildTools/Skins/illustro/Network/Network.ini
new file mode 100644
index 00000000..b72007bf
--- /dev/null
+++ b/BuildTools/Skins/illustro/Network/Network.ini
@@ -0,0 +1,215 @@
+; Lines starting ; (semicolons) are commented out.
+; That is, they do not affect the code and are here for demonstration purposes only.
+; ----------------------------------
+
+[Rainmeter]
+; This section contains general settings that can be used to change how Rainmeter behaves.
+Author=poiru
+AppVersion=2003000
+Update=1000
+Background=#@#Background.png
+; #@# is equal to Rainmeter\Skins\illustro\@Resources
+BackgroundMode=3
+BackgroundMargins=0,34,0,14
+
+[Metadata]
+; Contains basic information of the skin.
+Description=Shows your IP address and network activity.
+License=Creative Commons BY-NC-SA 3.0
+Version=1.0.0
+
+[Variables]
+; Variables declared here can be used later on between two # characters (e.g. #MyVariable#).
+fontName=Trebuchet MS
+textSize=8
+colorBar=235,170,0,255
+colorText=255,255,255,205
+maxDownload=10485760
+MaxUpload=10485760
+; Set maxDownload and maxUpload to your maximum download and upload speed in bits.
+; To convert kilobits, megabits, kilobytes, and megabytes into bits, go to www.google.com
+; and search for something like "10 megabytes in bits".
+
+; ----------------------------------
+; MEASURES return some kind of value
+; ----------------------------------
+
+[measureIP]
+; This measure returns your IP. WebParser measures are relatively complicated. If you're a beginner with
+; Rainmeter, take a look at some of the other illustro skins before modifying this one.
+Measure=Plugin
+Plugin=WebParser.dll
+Url=http://checkip.dyndns.org
+UpdateRate=14400
+RegExp="(?siU)Address: (.*)