Remove old Git bug (< 1.8.1) partial work-around

[Code]

{This code section is included into the main script and keeps the
important environment functions separate from it. There should be no need
to change this.}

function ExpandEnvironmentStrings(Src: String; Dst: String; Size: DWord): DWord;
  external 'ExpandEnvironmentStringsW@kernel32.dll stdcall delayload';

function SendMessageTimeout(Hwnd, Msg, WParam: LongInt; LParam: String; Flags, Timeout: LongInt; lpdwResult: DWord): DWord;
  external 'SendMessageTimeoutW@user32.dll stdcall delayload';

function EnvAdd(Hive: Integer; Name, Value: String; Display: Boolean): Integer; forward;
function EnvRemove(Hive: Integer; Name, Value: String; Display: Boolean): Integer; forward;
function AddPathSeparator(Path: String): String; forward;
function AddToPath(Hive: Integer; Value: String): Integer; forward;
function RemoveFromPath(Hive: Integer; Value: String): Integer; forward;
function WriteRegistryPath(Hive: Integer; const Key, Path: String): Integer; forward;
function GetRawPath(Hive: Integer; var Value: String): Boolean; forward;
function SplitPath(Value: String): TArrayOfString; forward;
function GetPathKeyForHive(Hive: Integer): String; forward;
function GetHiveName(Hive: Integer): String; forward;
function GetHiveFriendlyName(Hive: Integer): String; forward;
function IsPathEnv(Name: String): Boolean; forward;
function NormalizePath(const Value: String): String; forward;
function GetSafePathList(Hive: Integer): TSafeList; forward;
procedure SetSafePathList(const RawPath: String; var SafeList: TSafeList); forward;
function DirectoryInPath(var Directory: String; SafeList: TSafeList): Boolean; forward;
function SearchPath(SafeList: TSafeList; const Cmd: String): String; forward;
function SearchPathEx(SafeList: TSafeList; const Cmd: String; var Index: Integer): String; forward;
procedure DbgEnv(Action, Hive: Integer; Name, Value: String; Display: Boolean); forward;
procedure DbgPath(Action, Hive: Integer; Value: String); forward;
procedure DbgError(Name: String); forward;
procedure NotifyEnvironmentChange; forward;

const
  ENV_CHANGED = 0;
  ENV_NONE = 1;
  ENV_FAILED = 2;
  ENV_ADD = 100;
  ENV_REMOVE = 101;

  ENV_KEY_PATH = 'PATH';

function EnvAdd(Hive: Integer; Name, Value: String; Display: Boolean): Integer;
var
  Key: String;
  Existing: String;
  Res: Boolean;

begin

  if IsPathEnv(Name) then
  begin
    Result := AddToPath(Hive, Value);
    Exit;
  end;

  Key := GetPathKeyForHive(Hive);

  if RegQueryStringValue(Hive, Key, Name, Existing) then
  begin

    if CompareText(Existing, Value) = 0 then
    begin
      Result := ENV_NONE;
      Exit;
    end;
  end;

  DbgEnv(ENV_ADD, Hive, Name, Value, Display);
  Existing := Value;

  {See if we are expandable}
  if StringChangeEx(Existing, '%', '', True) = 2 then
    Res := RegWriteExpandStringValue(Hive, Key, Name, Value)
  else
    Res := RegWriteStringValue(Hive, Key, Name, Value);

  if Res then
    Result := ENV_CHANGED
  else
  begin
    Result := ENV_FAILED;
    DbgError(Name);
  end;

end;

function EnvRemove(Hive: Integer; Name, Value: String; Display: Boolean): Integer;
var
  Key: String;

begin

  if IsPathEnv(Name) then
  begin
    Result := RemoveFromPath(Hive, Value);
    Exit;
  end;

  Key := GetPathKeyForHive(Hive);

  if not RegValueExists(Hive, Key, Name) then
  begin
    Result := ENV_NONE;
    Exit;
  end;

  DbgEnv(ENV_REMOVE, Hive, Name, Value, Display);

  if RegDeleteValue(Hive, Key, Name) then
    Result := ENV_CHANGED
  else
  begin
    Result := ENV_FAILED;
    DbgError(Name);
  end;

end;

function AddPathSeparator(Path: String): String;
begin

  if (Path <> '') and (Path[Length(Path)] <> ';') then
    Result := Path + ';'
  else
    Result := Path;

end;

function AddToPath(Hive: Integer; Value: String): Integer;
var
  SafeDirectory: String;
  SafeList: TSafeList;
  Key: String;
  Path: String;

begin

  {NormalizePath UNC expands the path and removes any trailing backslash}
  SafeDirectory := NormalizePath(Value);

  {We exit if NormalizePath failed and/or we have no value}
  if SafeDirectory = '' then
  begin
    Result := ENV_FAILED;
    Exit;
  end;

  {Get a list of normalized path entries}
  SafeList := GetSafePathList(Hive);

  {See if our directory is already in the path}
  if DirectoryInPath(SafeDirectory, SafeList) then
  begin
    Result := ENV_NONE;
    Exit;
  end;

  {Get the current path values from registry}
  Key := GetPathKeyForHive(Hive);
  Path := '';
  RegQueryStringValue(Hive, Key, ENV_KEY_PATH, Path);

  DbgPath(ENV_ADD, Hive, SafeDirectory);

  {Add our new value to the end of the path}
  Path := AddPathSeparator(Path) + SafeDirectory;

  Result := WriteRegistryPath(Hive, Key, Path);

end;

function RemoveFromPath(Hive: Integer; Value: String): Integer;
var
  SafeDirectory: String;
  RawList: TArrayOfString;
  Key: String;
  CurrentPath: String;
  NewPath: String;
  I: Integer;
  SafePath: String;
  FoundEntry: Boolean;

begin

  {NormalizePath UNC expands the path and removes any trailing backslash}
  SafeDirectory := NormalizePath(Value);

  {We exit if NormalizePath failed}
  if SafeDirectory = '' then
  begin
    Result := ENV_FAILED;
    Exit;
  end;

  {Paranoid check to make sure we are not removing a system path - should not happen}
  if Pos(AnsiLowercase(GetSystemDir()), AnsiLowercase(SafeDirectory)) = 1 then
  begin
    Result := ENV_FAILED;
    Exit;
  end;

  {Get the current path values from registry. If we fail, we have not got any}
  Key := GetPathKeyForHive(Hive);
  CurrentPath := '';

  if not GetRawPath(Hive, CurrentPath) then
  begin
    Result := ENV_NONE;
    Exit;
  end;

  DbgPath(ENV_REMOVE, Hive, SafeDirectory);

  {Split current path into a list of raw entries}
  RawList := SplitPath(CurrentPath);
  NewPath := '';
  FoundEntry := False;

  for I := 0 to GetArrayLength(RawList) - 1 do
  begin

    {Normalize each raw entry - will be blank if we cannot expand it}
    SafePath := NormalizePath(RawList[I]);

    {Add each raw entry if normalize failed or if it does not match the directory we are removing}
    if (SafePath = '') or (CompareText(SafePath, SafeDirectory) <> 0) then
      NewPath := AddPathSeparator(NewPath) + RawList[I]
    else
      FoundEntry := True;

  end;

  {See if we found the entry we want to remove}
  if not FoundEntry then
    Result := ENV_NONE
  else
    Result := WriteRegistryPath(Hive, Key, NewPath);

end;

function WriteRegistryPath(Hive: Integer; const Key, Path: String): Integer;
var
  Res: Boolean;

begin

  if Path <> '' then
    Res := RegWriteExpandStringValue(Hive, Key, ENV_KEY_PATH, Path)
  else
  begin
    {We can delete the PATH key if we have an empty User PATH}
    if Hive = HKCU then
      Res := RegDeleteValue(Hive, Key, ENV_KEY_PATH)
    else
      Res := RegWriteExpandStringValue(Hive, Key, ENV_KEY_PATH, Path);
  end;

  if Res then
    Result := ENV_CHANGED
  else
  begin
    Result := ENV_FAILED;
    DbgError(ENV_KEY_PATH);
  end;

end;

function GetRawPath(Hive: Integer; var Value: String): Boolean;
var
  Key: String;

begin

  Value := '';
  Key := GetPathKeyForHive(Hive);
  Result := RegQueryStringValue(Hive, Key, ENV_KEY_PATH, Value);

end;

function SplitPath(Value: String): TArrayOfString;
var
  Index: Integer;
  Count: Integer;
  Next: Integer;

begin

  Count := 0;
  Next := 0;

  repeat

    Index := Pos(';', Value);

    if Next = Count then
    begin
      Count := Count + 20;
      SetArrayLength(Result, Count);
    end;

    if Index > 0 then
    begin
      Result[Next] := Copy(Value, 1, Index - 1);
      Value := Copy(Value, Index + 1, Length(Value));
    end
    else
    begin
      Result[Next] := Value;
      Value := '';
    end;

    Inc(Next);

  until Length(Value) = 0;

  if Next < Count then
    SetArrayLength(Result, Next);

end;

function GetPathKeyForHive(Hive: Integer): String;
begin

  if Hive = HKLM then
    Result := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
  else
    Result := 'Environment';

end;

function GetHiveName(Hive: Integer): String;
begin

  if Hive = HKLM then
    Result := 'HKLM'
  else
    Result := 'HKCU';

end;

function GetHiveFriendlyName(Hive: Integer): String;
begin

  if Hive = HKLM then
    Result := 'System'
  else
    Result := 'User';

end;

{Returns true if the subkey name is for the PATH value}
function IsPathEnv(Name: String): Boolean;
begin
  Result := CompareText(ENV_KEY_PATH, Name) = 0;
end;

function NormalizePath(const Value: String): String;
var
  Path: String;
  ResSize: DWord;
  Expanded: String;

begin

  Result := '';
  Path := Trim(Value);
  StringChangeEx(Path, '/', '\', True);

  {See if we have any %variables%}
  if Pos('%', Path) <> 0 then
  begin

    Expanded := '';
    ResSize := ExpandEnvironmentStrings(Path, Expanded, 0);

    if ResSize = 0 then
      Exit;

    SetLength(Expanded, ResSize);

    if ExpandEnvironmentStrings(Path, Expanded, ResSize) <> ResSize then
      Exit;

    Path := TrimRight(Expanded);

    {Check that expanded Path does not contain path-separators}
    if Pos(';', Path) <> 0 then
      Exit;

  end;

  {Check that we are a suitable path to expand (^[A-Z]:.*), or a UNC name (^\\.*) - not a complete check}
  if (Length(Path) >= 3) and (Path[2] = ':') and (Uppercase(Path[1]) >= 'A') and (Uppercase(Path[1]) <= 'Z') then
  begin
    Path := ExpandUNCFileName(Path);

    {Inno versions < 6 returned garbage with paths > 259 characters, which could cause a crash}
    if Pos(#0, Path) <> 0 then
      Exit;

  end
  else if (Length(Path) < 3) or (Pos('\\', Path) <> 1) then
    Exit;

  Result := RemoveBackslashUnlessRoot(Path);

end;

function GetSafePathList(Hive: Integer): TSafeList;
var
  Path: String;

begin

  if not GetRawPath(Hive, Path) then
    Exit;

  SetSafePathList(Path, Result);

end;

procedure SetSafePathList(const RawPath: String; var SafeList: TSafeList);
var
  RawList: TArrayOfString;
  Next: Integer;
  I: Integer;
  SafePath: String;

begin

  RawList := SplitPath(RawPath);
  SetArrayLength(SafeList, GetArrayLength(RawList));
  Next := 0;

  for I := 0 to GetArrayLength(RawList) - 1 do
  begin

    SafePath := NormalizePath(RawList[I]);

    if SafePath <> '' then
    begin
      SafeList[Next] := SafePath;
      Inc(Next);
    end;

  end;

  SetArrayLength(SafeList, Next);

end;

function DirectoryInPath(var Directory: String; SafeList: TSafeList): Boolean;
var
  I: Integer;

begin

  Result := False;

  Directory := NormalizePath(Directory);

  if Directory = '' then
    Exit;

  for I := 0 to GetArrayLength(SafeList) - 1 do
  begin

    if CompareText(SafeList[I], Directory) = 0 then
    begin
      Result := True;
      Exit;
    end;

  end;

end;

function SearchPath(SafeList: TSafeList; const Cmd: String): String;
var
  Index: Integer;

begin

  Result := SearchPathEx(SafeList, Cmd, Index);

end;

function SearchPathEx(SafeList: TSafeList; const Cmd: String; var Index: Integer): String;
var
  I: Integer;
  Path: String;
  Filename: String;

begin

  Result := '';
  Index := -1;

  for I := 0 to GetArrayLength(SafeList) - 1 do
  begin

    Path := SafeList[I];
    Filename := AddBackslash(Path) + Cmd;

    if FileExists(Filename) then
    begin
      Result := Filename;
      Index := I;
      Exit;
    end;

  end;

end;

procedure DbgEnv(Action, Hive: Integer; Name, Value: String; Display: Boolean);
var
  Path: String;
  Prefix: String;

begin

  Path := Format('%s\%s', [GetHiveName(Hive), GetPathKeyForHive(Hive)]);
  Name := Format('%s%s%s', [#39, Name, #39]);

  if Display then
    Value := Format(' with value %s%s%s', [#39, Value, #39])
  else
    Value := '';

  if Action = ENV_ADD then
    Prefix := Format('Adding %s%s to', [Name, Value])
  else
    Prefix := Format('Removing %s%s from', [Name, Value]);

  Debug(Format('%s [%s]', [Prefix, Path]));

end;

procedure DbgError(Name: String);
begin
  Debug(Format('Failed to update %s value', [Name]));
end;

procedure DbgPath(Action, Hive: Integer; Value: String);
var
  Path: String;
  Prefix: String;

begin

  Path := Format('%s\%s\%s', [GetHiveName(Hive), GetPathKeyForHive(Hive), ENV_KEY_PATH]);

  if Action = ENV_ADD then
    Prefix := Format('Adding %s%s%s to', [#39, Value, #39])
  else
    Prefix := Format('Removing %s%s%s from', [#39, Value, #39]);

  Debug(Format('%s [%s]', [Prefix, Path]));

end;

procedure NotifyEnvironmentChange;
var
  Res: DWORD;

begin

  {WM_SETTINGCHANGE = $1A; SMTO_ABORTIFHUNG = $2;}
  SendMessageTimeout(HWND_BROADCAST, $1A, 0, 'Environment', $2, 2000, Res);

end;

[Code]

{This code section is included into the main script and keeps the
important environment functions separate from it. There should be no need
to change this.}

function ExpandEnvironmentStrings(Src: String; Dst: String; Size: DWord): DWord;
  external 'ExpandEnvironmentStringsW@kernel32.dll stdcall delayload';

function SendMessageTimeout(Hwnd, Msg, WParam: LongInt; LParam: String; Flags, Timeout: LongInt; lpdwResult: DWord): DWord;
  external 'SendMessageTimeoutW@user32.dll stdcall delayload';

function EnvAdd(Hive: Integer; Name, Value: String; Display: Boolean): Integer; forward;
function EnvRemove(Hive: Integer; Name, Value: String; Display: Boolean): Integer; forward;
function AddPathSeparator(Path: String): String; forward;
function AddToPath(Hive: Integer; Value: String): Integer; forward;
function RemoveFromPath(Hive: Integer; Value: String): Integer; forward;
function WriteRegistryPath(Hive: Integer; const Key, Path: String): Integer; forward;
function GetRawPath(Hive: Integer; var Value: String): Boolean; forward;
function SplitPath(Value: String): TArrayOfString; forward;
function GetPathKeyForHive(Hive: Integer): String; forward;
function GetHiveName(Hive: Integer): String; forward;
function GetHiveFriendlyName(Hive: Integer): String; forward;
function IsPathEnv(Name: String): Boolean; forward;
function NormalizePath(const Value: String): String; forward;
function GetSafePathList(Hive: Integer): TSafeList; forward;
procedure SetSafePathList(const RawPath: String; var SafeList: TSafeList); forward;
function DirectoryInPath(var Directory: String; SafeList: TSafeList): Boolean; forward;
function SearchPath(SafeList: TSafeList; const Cmd: String): String; forward;
function SearchPathEx(SafeList: TSafeList; const Cmd: String; var Index: Integer): String; forward;
procedure DbgEnv(Action, Hive: Integer; Name, Value: String; Display: Boolean); forward;
procedure DbgPath(Action, Hive: Integer; Value: String); forward;
procedure DbgError(Name: String); forward;
procedure NotifyEnvironmentChange; forward;
function NeedsTrailingSeparator: Boolean; forward;

const
  ENV_CHANGED = 0;
  ENV_NONE = 1;
  ENV_FAILED = 2;
  ENV_ADD = 100;
  ENV_REMOVE = 101;

  ENV_KEY_PATH = 'PATH';

function EnvAdd(Hive: Integer; Name, Value: String; Display: Boolean): Integer;
var
  Key: String;
  Existing: String;
  Res: Boolean;

begin

  if IsPathEnv(Name) then
  begin
    Result := AddToPath(Hive, Value);
    Exit;
  end;

  Key := GetPathKeyForHive(Hive);

  if RegQueryStringValue(Hive, Key, Name, Existing) then
  begin

    if CompareText(Existing, Value) = 0 then
    begin
      Result := ENV_NONE;
      Exit;
    end;
  end;

  DbgEnv(ENV_ADD, Hive, Name, Value, Display);
  Existing := Value;

  {See if we are expandable}
  if StringChangeEx(Existing, '%', '', True) = 2 then
    Res := RegWriteExpandStringValue(Hive, Key, Name, Value)
  else
    Res := RegWriteStringValue(Hive, Key, Name, Value);

  if Res then
    Result := ENV_CHANGED
  else
  begin
    Result := ENV_FAILED;
    DbgError(Name);
  end;

end;

function EnvRemove(Hive: Integer; Name, Value: String; Display: Boolean): Integer;
var
  Key: String;

begin

  if IsPathEnv(Name) then
  begin
    Result := RemoveFromPath(Hive, Value);
    Exit;
  end;

  Key := GetPathKeyForHive(Hive);

  if not RegValueExists(Hive, Key, Name) then
  begin
    Result := ENV_NONE;
    Exit;
  end;

  DbgEnv(ENV_REMOVE, Hive, Name, Value, Display);

  if RegDeleteValue(Hive, Key, Name) then
    Result := ENV_CHANGED
  else
  begin
    Result := ENV_FAILED;
    DbgError(Name);
  end;

end;

function AddPathSeparator(Path: String): String;
begin

  if (Path <> '') and (Path[Length(Path)] <> ';') then
    Result := Path + ';'
  else
    Result := Path;

end;

function AddToPath(Hive: Integer; Value: String): Integer;
var
  SafeDirectory: String;
  SafeList: TSafeList;
  Key: String;
  Path: String;

begin

  {NormalizePath UNC expands the path and removes any trailing backslash}
  SafeDirectory := NormalizePath(Value);

  {We exit if NormalizePath failed and/or we have no value}
  if SafeDirectory = '' then
  begin
    Result := ENV_FAILED;
    Exit;
  end;

  {Get a list of normalized path entries}
  SafeList := GetSafePathList(Hive);

  {See if our directory is already in the path}
  if DirectoryInPath(SafeDirectory, SafeList) then
  begin
    Result := ENV_NONE;
    Exit;
  end;

  {Get the current path values from registry}
  Key := GetPathKeyForHive(Hive);
  Path := '';
  RegQueryStringValue(Hive, Key, ENV_KEY_PATH, Path);

  DbgPath(ENV_ADD, Hive, SafeDirectory);

  {Add our new value to the end of the path}
  Path := AddPathSeparator(Path) + SafeDirectory;

  Result := WriteRegistryPath(Hive, Key, Path);

end;

function RemoveFromPath(Hive: Integer; Value: String): Integer;
var
  SafeDirectory: String;
  RawList: TArrayOfString;
  Key: String;
  CurrentPath: String;
  NewPath: String;
  I: Integer;
  SafePath: String;
  FoundEntry: Boolean;

begin

  {NormalizePath UNC expands the path and removes any trailing backslash}
  SafeDirectory := NormalizePath(Value);

  {We exit if NormalizePath failed}
  if SafeDirectory = '' then
  begin
    Result := ENV_FAILED;
    Exit;
  end;

  {Paranoid check to make sure we are not removing a system path - should not happen}
  if Pos(AnsiLowercase(GetSystemDir()), AnsiLowercase(SafeDirectory)) = 1 then
  begin
    Result := ENV_FAILED;
    Exit;
  end;

  {Get the current path values from registry. If we fail, we have not got any}
  Key := GetPathKeyForHive(Hive);
  CurrentPath := '';

  if not GetRawPath(Hive, CurrentPath) then
  begin
    Result := ENV_NONE;
    Exit;
  end;

  DbgPath(ENV_REMOVE, Hive, SafeDirectory);

  {Split current path into a list of raw entries}
  RawList := SplitPath(CurrentPath);
  NewPath := '';
  FoundEntry := False;

  for I := 0 to GetArrayLength(RawList) - 1 do
  begin

    {Normalize each raw entry - will be blank if we cannot expand it}
    SafePath := NormalizePath(RawList[I]);

    {Add each raw entry if normalize failed or if it does not match the directory we are removing}
    if (SafePath = '') or (CompareText(SafePath, SafeDirectory) <> 0) then
      NewPath := AddPathSeparator(NewPath) + RawList[I]
    else
      FoundEntry := True;

  end;

  {See if we found the entry we want to remove}
  if not FoundEntry then
    Result := ENV_NONE
  else
    Result := WriteRegistryPath(Hive, Key, NewPath);

end;

function WriteRegistryPath(Hive: Integer; const Key, Path: String): Integer;
var
  Res: Boolean;

begin

  if Path = '' then
  begin
    {We can delete the PATH key if we have an empty User PATH}
    if Hive = HKCU then
      Res := RegDeleteValue(Hive, Key, ENV_KEY_PATH)
    else
      Res := RegWriteExpandStringValue(Hive, Key, ENV_KEY_PATH, Path);
  end
  else
  begin

    {Add a trailing separator if required}
    if NeedsTrailingSeparator then
      Path := AddPathSeparator(Path);

    Res := RegWriteExpandStringValue(Hive, Key, ENV_KEY_PATH, Path);

  end;

  if Res then
    Result := ENV_CHANGED
  else
  begin
    Result := ENV_FAILED;
    DbgError(ENV_KEY_PATH);
  end;

end;

function GetRawPath(Hive: Integer; var Value: String): Boolean;
var
  Key: String;

begin

  Value := '';
  Key := GetPathKeyForHive(Hive);
  Result := RegQueryStringValue(Hive, Key, ENV_KEY_PATH, Value);

end;

function SplitPath(Value: String): TArrayOfString;
var
  Index: Integer;
  Count: Integer;
  Next: Integer;

begin

  Count := 0;
  Next := 0;

  repeat

    Index := Pos(';', Value);

    if Next = Count then
    begin
      Count := Count + 20;
      SetArrayLength(Result, Count);
    end;

    if Index > 0 then
    begin
      Result[Next] := Copy(Value, 1, Index - 1);
      Value := Copy(Value, Index + 1, Length(Value));
    end
    else
    begin
      Result[Next] := Value;
      Value := '';
    end;

    Inc(Next);

  until Length(Value) = 0;

  if Next < Count then
    SetArrayLength(Result, Next);

end;

function GetPathKeyForHive(Hive: Integer): String;
begin

  if Hive = HKLM then
    Result := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
  else
    Result := 'Environment';

end;

function GetHiveName(Hive: Integer): String;
begin

  if Hive = HKLM then
    Result := 'HKLM'
  else
    Result := 'HKCU';

end;

function GetHiveFriendlyName(Hive: Integer): String;
begin

  if Hive = HKLM then
    Result := 'System'
  else
    Result := 'User';

end;

{Returns true if the subkey name is for the PATH value}
function IsPathEnv(Name: String): Boolean;
begin
  Result := CompareText(ENV_KEY_PATH, Name) = 0;
end;

function NormalizePath(const Value: String): String;
var
  Path: String;
  ResSize: DWord;
  Expanded: String;

begin

  Result := '';
  Path := Trim(Value);
  StringChangeEx(Path, '/', '\', True);

  {See if we have any %variables%}
  if Pos('%', Path) <> 0 then
  begin

    Expanded := '';
    ResSize := ExpandEnvironmentStrings(Path, Expanded, 0);

    if ResSize = 0 then
      Exit;

    SetLength(Expanded, ResSize);

    if ExpandEnvironmentStrings(Path, Expanded, ResSize) <> ResSize then
      Exit;

    Path := TrimRight(Expanded);

    {Check that expanded Path does not contain path-separators}
    if Pos(';', Path) <> 0 then
      Exit;

  end;

  {Check that we are a suitable path to expand (^[A-Z]:.*), or a UNC name (^\\.*) - not a complete check}
  if (Length(Path) >= 3) and (Path[2] = ':') and (Uppercase(Path[1]) >= 'A') and (Uppercase(Path[1]) <= 'Z') then
  begin
    Path := ExpandUNCFileName(Path);

    {Inno versions < 6 returned garbage with paths > 259 characters, which could cause a crash}
    if Pos(#0, Path) <> 0 then
      Exit;

  end
  else if (Length(Path) < 3) or (Pos('\\', Path) <> 1) then
    Exit;

  Result := RemoveBackslashUnlessRoot(Path);

end;

function GetSafePathList(Hive: Integer): TSafeList;
var
  Path: String;

begin

  if not GetRawPath(Hive, Path) then
    Exit;

  SetSafePathList(Path, Result);

end;

procedure SetSafePathList(const RawPath: String; var SafeList: TSafeList);
var
  RawList: TArrayOfString;
  Next: Integer;
  I: Integer;
  SafePath: String;

begin

  RawList := SplitPath(RawPath);
  SetArrayLength(SafeList, GetArrayLength(RawList));
  Next := 0;

  for I := 0 to GetArrayLength(RawList) - 1 do
  begin

    SafePath := NormalizePath(RawList[I]);

    if SafePath <> '' then
    begin
      SafeList[Next] := SafePath;
      Inc(Next);
    end;

  end;

  SetArrayLength(SafeList, Next);

end;

function DirectoryInPath(var Directory: String; SafeList: TSafeList): Boolean;
var
  I: Integer;

begin

  Result := False;

  Directory := NormalizePath(Directory);

  if Directory = '' then
    Exit;

  for I := 0 to GetArrayLength(SafeList) - 1 do
  begin

    if CompareText(SafeList[I], Directory) = 0 then
    begin
      Result := True;
      Exit;
    end;

  end;

end;

function SearchPath(SafeList: TSafeList; const Cmd: String): String;
var
  Index: Integer;

begin

  Result := SearchPathEx(SafeList, Cmd, Index);

end;

function SearchPathEx(SafeList: TSafeList; const Cmd: String; var Index: Integer): String;
var
  I: Integer;
  Path: String;
  Filename: String;

begin

  Result := '';
  Index := -1;

  for I := 0 to GetArrayLength(SafeList) - 1 do
  begin

    Path := SafeList[I];
    Filename := AddBackslash(Path) + Cmd;

    if FileExists(Filename) then
    begin
      Result := Filename;
      Index := I;
      Exit;
    end;

  end;

end;

procedure DbgEnv(Action, Hive: Integer; Name, Value: String; Display: Boolean);
var
  Path: String;
  Prefix: String;

begin

  Path := Format('%s\%s', [GetHiveName(Hive), GetPathKeyForHive(Hive)]);
  Name := Format('%s%s%s', [#39, Name, #39]);

  if Display then
    Value := Format(' with value %s%s%s', [#39, Value, #39])
  else
    Value := '';

  if Action = ENV_ADD then
    Prefix := Format('Adding %s%s to', [Name, Value])
  else
    Prefix := Format('Removing %s%s from', [Name, Value]);

  Debug(Format('%s [%s]', [Prefix, Path]));

end;

procedure DbgError(Name: String);
begin
  Debug(Format('Failed to update %s value', [Name]));
end;

procedure DbgPath(Action, Hive: Integer; Value: String);
var
  Path: String;
  Prefix: String;

begin

  Path := Format('%s\%s\%s', [GetHiveName(Hive), GetPathKeyForHive(Hive), ENV_KEY_PATH]);

  if Action = ENV_ADD then
    Prefix := Format('Adding %s%s%s to', [#39, Value, #39])
  else
    Prefix := Format('Removing %s%s%s from', [#39, Value, #39]);

  Debug(Format('%s [%s]', [Prefix, Path]));

end;

procedure NotifyEnvironmentChange;
var
  Res: DWORD;

begin

  {WM_SETTINGCHANGE = $1A; SMTO_ABORTIFHUNG = $2;}
  SendMessageTimeout(HWND_BROADCAST, $1A, 0, 'Environment', $2, 2000, Res);

end;

{Git for Windows had a bug on versions lower than 1.8.1.0 that only
affects users with cygwin in their path. The code to strip the cygwin
references adds a null-byte to the PATH which means that Posix paths
are inherited by non-msys child processes rather than Windows ones,
and the last path entry becomes unresovable. We can cure the latter
by adding a trailing separator to the path.}
function NeedsTrailingSeparator: Boolean;
var
  Hive: Integer;
  SafeList: TSafeList;
  Cmd: String;
  GitExe: String;
  Version: String;

begin

  Result := False;
  Cmd := 'git.exe';

  Hive := HKLM;
  SafeList := GetSafePathList(Hive);
  GitExe := SearchPath(SafeList, Cmd);

  if GitExe = '' then
  begin
    Hive := HKCU;
    SafeList := GetSafePathList(Hive);
    GitExe := SearchPath(SafeList, Cmd);
  end;

  if GitExe = '' then
    Exit;

  if StringChangeEx(GitExe, 'cmd', 'bin', True) = 0 then
    Exit;

  if FileExists(GitExe) then
  begin

    Result := True;

    if GetVersionNumbersString(GitExe, Version) then
      Result := CompareStr(Version, '1.8.1.0') < 0;

  end;

end;


Update for current Cygwin version (2.876)

; Project file for Inno Setup to create a KadNode installer

[Setup]
AppName=KadNode
AppVersion="1.0.0"
AppPublisher="Moritz Warning"
AppPublisherURL="https://github.com/mwarning/KadNode"
DefaultDirName={pf}\KadNode
DefaultGroupName=KadNode
PrivilegesRequired=admin
AllowNoIcons=yes
LicenseFile=..\LICENSE
OutputDir=..\build
OutputBaseFilename=kadnode_1.0.0_i386
Compression=lzma
SolidCompression=yes

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Files]
Source: "C:\cygwin64\bin\cygwin1.dll"; DestDir: "{app}"
Source: "C:\cygwin64\usr\local\bin\cygsodium-18.dll"; DestDir: "{app}"
Source: "C:\cygwin64\bin\cyggcc_s-1.dll"; DestDir: "{app}"
Source: "..\build\kadnode.exe"; DestDir: "{app}"
Source: "..\build\kadnode-ctl.exe"; DestDir: "{app}"
Source: "..\windows\dns_setup.bat"; DestDir: "{app}"
Source: "..\windows\dns_reset.bat"; DestDir: "{app}"
Source: "..\windows\kadnode_start.bat"; DestDir: "{app}"
Source: "..\windows\kadnode_stop.bat"; DestDir: "{app}"
Source: "..\windows\config.txt"; DestDir: "{app}"
Source: "..\README.md"; DestDir: "{app}"; DestName: "readme.txt"; AfterInstall: ConvertLineEndings
Source: "..\LICENSE"; DestDir: "{app}"; DestName: "license.txt"; AfterInstall: ConvertLineEndings
Source: "..\misc\peers.txt"; DestDir: "{app}"; AfterInstall: ConvertLineEndings
Source: "..\debian\changelog"; DestDir: "{app}"; DestName: "changelog.txt"; AfterInstall: ConvertLineEndings

[Icons]
Name: "{group}\Configuration"; Filename: "{app}\config.txt"
Name: "{group}\ReadMe"; Filename: "{app}\readme.txt"
Name: "{group}\Start KadNode"; Filename: "{app}\kadnode_start.bat"
Name: "{group}\Stop KadNode"; Filename: "{app}\kadnode_stop.bat"
Name: "{group}\{cm:UninstallProgram,KadNode}"; Filename: "{uninstallexe}"

[Run]
Filename: "{app}\readme.txt"; Flags: shellexec skipifdoesntexist postinstall skipifsilent
Filename: "{sys}\sc.exe"; Parameters: "create KadNode DisplayName= KadNode type= own start= auto error= normal binPath= ""\""{app}\kadnode.exe\"" --service-start --config \""{app}\config.txt\"" --peerfile \""{app}\peers.txt\"" --dns-port 53"""; Flags: runascurrentuser runhidden
Filename: "{sys}\sc.exe"; Parameters: "description KadNode ""KadNode is a decentralized DNS service. It intercepts and resolves DNS requests for a specific top level domain like \"".p2p\"". The mapping from a domain to an IP address is done by means of a Distributed Hash Table (DHT)."""; Flags: runascurrentuser runhidden
Filename: "{sys}\sc.exe"; Parameters: "start KadNode"; Description: {cm:LaunchMsg}; Flags: nowait postinstall skipifsilent runascurrentuser runhidden

[CustomMessages]
LaunchMsg=Start KadNode now

[UninstallRun]
Filename: "{sys}\sc.exe"; Parameters: "stop KadNode"; Flags: runhidden
Filename: "{sys}\timeout.exe"; Parameters: "/T 4"; Flags: runhidden
Filename: "{sys}\sc.exe"; Parameters: "delete KadNode"; Flags: runhidden

[Messages]
WelcomeLabel2=This will install [name/ver] on your computer.%n%nKadNode is a dezentralized DNS system based on a distributed hash table.%n%nBe aware that this package is in an alpha stage and will change your DNS settings.

[Code]
const
  LF = #10;
  CR = #13;
  CRLF = CR + LF;

procedure ConvertLineEndings();
var
  FilePath : String;
  FileContents : String;
begin
  FilePath := ExpandConstant(CurrentFileName)
  LoadStringFromFile(FilePath, FileContents);
  StringChangeEx(FileContents, LF, CRLF, False);
  SaveStringToFile(FilePath, FileContents, False);
end;

; Project file for Inno Setup to create a KadNode installer

[Setup]
AppName=KadNode
AppVersion="1.0.0"
AppPublisher="Moritz Warning"
AppPublisherURL="https://github.com/mwarning/KadNode"
DefaultDirName={pf}\KadNode
DefaultGroupName=KadNode
PrivilegesRequired=admin
AllowNoIcons=yes
LicenseFile=..\LICENSE
OutputDir=..\build
OutputBaseFilename=kadnode_1.0.0_i386
Compression=lzma
SolidCompression=yes

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Files]
Source: "C:\cygwin64\bin\cygwin1.dll"; DestDir: "{app}"
Source: "C:\cygwin64\usr\local\bin\cygsodium-13.dll"; DestDir: "{app}"
Source: "..\build\kadnode.exe"; DestDir: "{app}"
Source: "..\build\kadnode-ctl.exe"; DestDir: "{app}"
Source: "..\windows\dns_setup.bat"; DestDir: "{app}"
Source: "..\windows\dns_reset.bat"; DestDir: "{app}"
Source: "..\windows\kadnode_start.bat"; DestDir: "{app}"
Source: "..\windows\kadnode_stop.bat"; DestDir: "{app}"
Source: "..\windows\config.txt"; DestDir: "{app}"
Source: "..\README.md"; DestDir: "{app}"; DestName: "readme.txt"; AfterInstall: ConvertLineEndings
Source: "..\LICENSE"; DestDir: "{app}"; DestName: "license.txt"; AfterInstall: ConvertLineEndings
Source: "..\misc\peers.txt"; DestDir: "{app}"; AfterInstall: ConvertLineEndings
Source: "..\debian\changelog"; DestDir: "{app}"; DestName: "changelog.txt"; AfterInstall: ConvertLineEndings

[Icons]
Name: "{group}\Configuration"; Filename: "{app}\config.txt"
Name: "{group}\ReadMe"; Filename: "{app}\readme.txt"
Name: "{group}\Start KadNode"; Filename: "{app}\kadnode_start.bat"
Name: "{group}\Stop KadNode"; Filename: "{app}\kadnode_stop.bat"
Name: "{group}\{cm:UninstallProgram,KadNode}"; Filename: "{uninstallexe}"

[Run]
Filename: "{app}\readme.txt"; Flags: shellexec skipifdoesntexist postinstall skipifsilent
Filename: "{sys}\sc.exe"; Parameters: "create KadNode DisplayName= KadNode type= own start= auto error= normal binPath= ""\""{app}\kadnode.exe\"" --service-start --config \""{app}\config.txt\"" --peerfile \""{app}\peers.txt\"" --dns-port 53"""; Flags: runascurrentuser runhidden
Filename: "{sys}\sc.exe"; Parameters: "description KadNode ""KadNode is a decentralized DNS service. It intercepts and resolves DNS requests for a specific top level domain like \"".p2p\"". The mapping from a domain to an IP address is done by means of a Distributed Hash Table (DHT)."""; Flags: runascurrentuser runhidden
Filename: "{sys}\sc.exe"; Parameters: "start KadNode"; Description: {cm:LaunchMsg}; Flags: nowait postinstall skipifsilent runascurrentuser runhidden

[CustomMessages]
LaunchMsg=Start KadNode now

[UninstallRun]
Filename: "{sys}\sc.exe"; Parameters: "stop KadNode"; Flags: runhidden
Filename: "{sys}\timeout.exe"; Parameters: "/T 4"; Flags: runhidden
Filename: "{sys}\sc.exe"; Parameters: "delete KadNode"; Flags: runhidden

[Messages]
WelcomeLabel2=This will install [name/ver] on your computer.%n%nKadNode is a dezentralized DNS system based on a distributed hash table.%n%nBe aware that this package is in an alpha stage and will change your DNS settings.

[Code]
const
  LF = #10;
  CR = #13;
  CRLF = CR + LF;

procedure ConvertLineEndings();
var
  FilePath : String;
  FileContents : String;
begin
  FilePath := ExpandConstant(CurrentFileName)
  LoadStringFromFile(FilePath, FileContents);
  StringChangeEx(FileContents, LF, CRLF, False);
  SaveStringToFile(FilePath, FileContents, False);
end;


Version number update to 2.9.4

Version number update to 2.9.4

git-svn-id: 4a0daf30c0bbd291b3bc5fe8f058bf11ee523347@599 7d282ba1-3ae6-0310-8f9b-c9008a0864d2

#define ver "2.9.4-b599";

[Setup]
AppName=Tigase Server
AppVersion={#ver}
AppVerName=Tigase XMPP Server {#ver}
AppPublisher=tigase.org
AppPublisherURL=http://www.tigase.org/
AppSupportURL=http://www.tigase.org/
AppUpdatesURL=http://www.tigase.org/
DefaultDirName={pf}\Tigase
DefaultGroupName=Tigase Server
AllowNoIcons=true
LicenseFile=Licence.txt
OutputDir=..\packages
OutputBaseFilename=tigase-server-{#ver}
Compression=lzma
SolidCompression=true
UninstallDisplayIcon={app}\Tigase.ico
VersionInfoCopyright=Artur Hefczyc

[Languages]
Name: english; MessagesFile: compiler:Default.isl
Name: basque; MessagesFile: compiler:Languages\Basque.isl
Name: brazilianportuguese; MessagesFile: compiler:Languages\BrazilianPortuguese.isl
Name: catalan; MessagesFile: compiler:Languages\Catalan.isl
Name: czech; MessagesFile: compiler:Languages\Czech.isl
Name: danish; MessagesFile: compiler:Languages\Danish.isl
Name: dutch; MessagesFile: compiler:Languages\Dutch.isl
Name: finnish; MessagesFile: compiler:Languages\Finnish.isl
Name: french; MessagesFile: compiler:Languages\French.isl
Name: german; MessagesFile: compiler:Languages\German.isl
Name: hungarian; MessagesFile: compiler:Languages\Hungarian.isl
Name: italian; MessagesFile: compiler:Languages\Italian.isl
Name: norwegian; MessagesFile: compiler:Languages\Norwegian.isl
Name: polish; MessagesFile: compiler:Languages\Polish.isl
Name: portuguese; MessagesFile: compiler:Languages\Portuguese.isl
Name: russian; MessagesFile: compiler:Languages\Russian.isl
Name: slovak; MessagesFile: compiler:Languages\Slovak.isl
Name: slovenian; MessagesFile: compiler:Languages\Slovenian.isl
Name: spanish; MessagesFile: compiler:Languages\Spanish.isl

[Files]
Source: wrapper\wrapper.exe; DestDir: {app}; Flags: ignoreversion; Languages:
Source: ..\certs\*; DestDir: {app}\certs; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ..\docs-tigase-server\*; DestDir: {app}\docs; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ..\etc\*; DestDir: {app}\etc; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ..\jars\*; DestDir: {app}\jars; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ..\libs\*; DestDir: {app}\libs; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ..\database\mysql-schema.sql; DestDir: {app}\database\mysql-schema.sql; Flags: ignoreversion
Source: ..\database\postgresql-schema.sql; DestDir: {app}\database\postgresql-schema.sql; Flags: ignoreversion
Source: wrapper\wrapper.conf; DestDir: {app}; Flags: ignoreversion
Source: scripts\InstallTigaseService.bat; DestDir: {app}; Flags: ignoreversion
Source: ..\README.html; DestDir: {app}; Flags: ignoreversion
Source: scripts\Run.bat; DestDir: {app}; Flags: ignoreversion
Source: scripts\Tigase.bat; DestDir: {app}; Flags: ignoreversion
Source: scripts\UninstallTigaseService.bat; DestDir: {app}; Flags: ignoreversion
Source: Tigase.ico; DestDir: {app}; Flags: ignoreversion
Source: scripts\Uninst.bat; DestDir: {app}; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
Source: Licence.txt; DestDir: {app}; Flags: ignoreversion
Source: wrapper\wrapper.dll; DestDir: {app}\libs; Flags: ignoreversion
Source: wrapper\wrapper.jar; DestDir: {app}\libs; Flags: ignoreversion

[Dirs]
Name: {app}\logs

[Icons]
Name: {group}\Start Tigase Server; Filename: {app}\Run.bat; WorkingDir: {app}; IconFilename: {app}\Tigase.ico
Name: {group}\Install Tigase Service; Filename: {app}\InstallTigaseService.bat
Name: {group}\Uninstall Tigase Service; Filename: {app}\UninstallTigaseService.bat
Name: {group}\{cm:ProgramOnTheWeb,Tigase}; Filename: http://www.tigase.org/

[UninstallRun]
Filename: {app}\Uninst.bat

#define ver "2.9.3-b548";

[Setup]
AppName=Tigase Server
AppVersion={#ver}
AppVerName=Tigase XMPP Server {#ver}
AppPublisher=tigase.org
AppPublisherURL=http://www.tigase.org/
AppSupportURL=http://www.tigase.org/
AppUpdatesURL=http://www.tigase.org/
DefaultDirName={pf}\Tigase
DefaultGroupName=Tigase Server
AllowNoIcons=true
LicenseFile=Licence.txt
OutputDir=..\packages
OutputBaseFilename=tigase-server-{#ver}
Compression=lzma
SolidCompression=true
UninstallDisplayIcon={app}\Tigase.ico
VersionInfoCopyright=Artur Hefczyc

[Languages]
Name: english; MessagesFile: compiler:Default.isl
Name: basque; MessagesFile: compiler:Languages\Basque.isl
Name: brazilianportuguese; MessagesFile: compiler:Languages\BrazilianPortuguese.isl
Name: catalan; MessagesFile: compiler:Languages\Catalan.isl
Name: czech; MessagesFile: compiler:Languages\Czech.isl
Name: danish; MessagesFile: compiler:Languages\Danish.isl
Name: dutch; MessagesFile: compiler:Languages\Dutch.isl
Name: finnish; MessagesFile: compiler:Languages\Finnish.isl
Name: french; MessagesFile: compiler:Languages\French.isl
Name: german; MessagesFile: compiler:Languages\German.isl
Name: hungarian; MessagesFile: compiler:Languages\Hungarian.isl
Name: italian; MessagesFile: compiler:Languages\Italian.isl
Name: norwegian; MessagesFile: compiler:Languages\Norwegian.isl
Name: polish; MessagesFile: compiler:Languages\Polish.isl
Name: portuguese; MessagesFile: compiler:Languages\Portuguese.isl
Name: russian; MessagesFile: compiler:Languages\Russian.isl
Name: slovak; MessagesFile: compiler:Languages\Slovak.isl
Name: slovenian; MessagesFile: compiler:Languages\Slovenian.isl
Name: spanish; MessagesFile: compiler:Languages\Spanish.isl

[Files]
Source: wrapper\wrapper.exe; DestDir: {app}; Flags: ignoreversion; Languages:
Source: ..\certs\*; DestDir: {app}\certs; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ..\docs-tigase-server\*; DestDir: {app}\docs; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ..\etc\*; DestDir: {app}\etc; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ..\jars\*; DestDir: {app}\jars; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ..\libs\*; DestDir: {app}\libs; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ..\database\mysql-schema.sql; DestDir: {app}\database\mysql-schema.sql; Flags: ignoreversion
Source: ..\database\postgresql-schema.sql; DestDir: {app}\database\postgresql-schema.sql; Flags: ignoreversion
Source: wrapper\wrapper.conf; DestDir: {app}; Flags: ignoreversion
Source: scripts\InstallTigaseService.bat; DestDir: {app}; Flags: ignoreversion
Source: ..\README.html; DestDir: {app}; Flags: ignoreversion
Source: scripts\Run.bat; DestDir: {app}; Flags: ignoreversion
Source: scripts\Tigase.bat; DestDir: {app}; Flags: ignoreversion
Source: scripts\UninstallTigaseService.bat; DestDir: {app}; Flags: ignoreversion
Source: Tigase.ico; DestDir: {app}; Flags: ignoreversion
Source: scripts\Uninst.bat; DestDir: {app}; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
Source: Licence.txt; DestDir: {app}; Flags: ignoreversion
Source: wrapper\wrapper.dll; DestDir: {app}\libs; Flags: ignoreversion
Source: wrapper\wrapper.jar; DestDir: {app}\libs; Flags: ignoreversion

[Dirs]
Name: {app}\logs

[Icons]
Name: {group}\Start Tigase Server; Filename: {app}\Run.bat; WorkingDir: {app}; IconFilename: {app}\Tigase.ico
Name: {group}\Install Tigase Service; Filename: {app}\InstallTigaseService.bat
Name: {group}\Uninstall Tigase Service; Filename: {app}\UninstallTigaseService.bat
Name: {group}\{cm:ProgramOnTheWeb,Tigase}; Filename: http://www.tigase.org/

[UninstallRun]
Filename: {app}\Uninst.bat


Add NHentai to default sources

Add NHentai to default sources

#define MyAppName "Grabber"
#define MyAppPublisher "Bionus"
#define MyAppURL "https://github.com/Bionus/imgbrd-grabber"
#define MyAppExeName "Grabber.exe"
#define BuildDir "..\build"

#ifndef QtDir
# define QtDir "C:\Qt\Qt5.10.1\5.10.1\msvc2015\bin"
#endif
#define QtPlugins QtDir + "\..\plugins"
#define QtLib QtDir + "\..\lib"

#ifndef OpenSSLDir
# define OpenSSLDir "C:\bin\OpenSSL-Win32-1.0.2k"
#endif

#ifndef MySQLDir
# define MySQLDir "C:\Program Files (x86)\MySQL\MySQL Server 5.7"
#endif

#ifndef MyAppVersion
# define MyAppVersion "7.0.1"
#endif

#ifndef QtApngDll
# define QtApngDll QtPlugins + "\imageformats\qapng.dll"
#endif

#define PlatformNamePrefix ""
#ifdef PlatformName
# define PlatformNamePrefix "_" + PlatformName
#endif

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{8C007AE6-3F7D-41CC-AB7C-75C08C276EC8}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
LicenseFile=Apache license 2.0.txt
OutputDir=.
OutputBaseFilename=Grabber_{#MyAppVersion}{#PlatformNamePrefix}
SetupIconFile=resources\images\icon.ico
UninstallDisplayName="{#MyAppName} {#MyAppVersion}"
UninstallDisplayIcon={app}\icon.ico
WizardSmallImageFile=resources\images\icon.bmp
Compression=lzma
SolidCompression=yes
ChangesAssociations=yes
DisableDirPage=no
PrivilegesRequired=admin
ArchitecturesAllowed=x86 x64 ia64
ArchitecturesInstallIn64BitMode=x64 ia64

; downloading and installing dependencies will only work if the memo/ready page is enabled (default and current behaviour)
DisableReadyPage=no
DisableReadyMemo=no

[CustomMessages]
en.IGL=Imageboard-Grabber Links
fr.IGL=Liens Imageboard-Grabber
DependenciesDir=MyProgramDependencies
WindowsServicePack=Windows %1 Service Pack %2

[Registry]
Root: HKCR; Subkey: ".igl"; ValueType: string; ValueName: ""; ValueData: "Imageboard-Grabber"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "Imageboard-Grabber"; ValueType: string; ValueName: ""; ValueData: "{cm:IGL}"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Imageboard-Grabber\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKCR; Subkey: "Imageboard-Grabber\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""

; Languages
#include "scripts\lang\english.iss"
#include "scripts\lang\german.iss"
#include "scripts\lang\french.iss"
#include "scripts\lang\italian.iss"
#include "scripts\lang\dutch.iss"

#ifdef UNICODE
#include "scripts\lang\chinese.iss"
#include "scripts\lang\polish.iss"
#include "scripts\lang\russian.iss"
#include "scripts\lang\japanese.iss"
#endif

#include "scripts\products.iss"
#include "scripts\products\stringversion.iss"
#include "scripts\products\winversion.iss"
#include "scripts\products\fileversion.iss"
#include "scripts\products\msiproduct.iss"
#include "scripts\products\vcredist2013.iss"
#include "scripts\products\vcredist2015.iss"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1

[Files]
Source: "resources\images\icon.ico";            DestDir: "{app}"; Flags: ignoreversion
Source: "..\release\CDR.exe";                   DestDir: "{app}"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\CrashReporter.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#BuildDir}\cli\Grabber-cli.exe";      DestDir: "{app}"; Flags: ignoreversion; DestName: "Grabber.com"
Source: "{#BuildDir}\gui\Grabber.exe";          DestDir: "{app}"; Flags: ignoreversion;
Source: "..\release\words.txt";                 DestDir: "{app}";
Source: "{#OpenSSLDir}\libeay32.dll";           DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\libEGL.dll";                  DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\libGLESv2.dll";               DestDir: "{app}"; Flags: ignoreversion
Source: "{#MySQLDir}\lib\libmysql.dll";         DestDir: "{app}"; Flags: ignoreversion
Source: "{#OpenSSLDir}\libssl32.dll";           DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtLib}\qscintilla2_qt5.dll";         DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Concurrent.dll";           DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Core.dll";                 DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Gui.dll";                  DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Multimedia.dll";           DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Network.dll";              DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5OpenGL.dll";               DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5PrintSupport.dll";         DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Qml.dll";                  DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Sql.dll";                  DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Widgets.dll";              DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Xml.dll";                  DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5WinExtras.dll";            DestDir: "{app}"; Flags: ignoreversion
Source: "{#OpenSSLDir}\ssleay32.dll";           DestDir: "{app}"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\languages\ChineseSimplified.qm"; DestDir: "{app}\crashreporter"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\languages\English.qm";  DestDir: "{app}\crashreporter"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\languages\French.qm";   DestDir: "{app}\crashreporter"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\languages\Russian.qm";  DestDir: "{app}\crashreporter"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\languages\Spanish.qm";  DestDir: "{app}\crashreporter"; Flags: ignoreversion
Source: "{#QtApngDll}";                         DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qdds.dll";   DestDir: "{app}\imageformats"; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#QtPlugins}\imageformats\qgif.dll";   DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qicns.dll";  DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qico.dll";   DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qjpeg.dll";  DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qsvg.dll";   DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qtga.dll";   DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qtiff.dll";  DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qwbmp.dll";  DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qwebp.dll";  DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#BuildDir}\languages\ChineseSimplified.qm"; DestDir: "{app}\languages"; Flags: ignoreversion
Source: "{#BuildDir}\languages\English.qm";     DestDir: "{app}\languages"; Flags: ignoreversion
Source: "{#BuildDir}\languages\French.qm";      DestDir: "{app}\languages"; Flags: ignoreversion
Source: "{#BuildDir}\languages\Russian.qm";     DestDir: "{app}\languages"; Flags: ignoreversion
Source: "{#BuildDir}\languages\Spanish.qm";     DestDir: "{app}\languages"; Flags: ignoreversion
Source: "..\release\languages\languages.ini";   DestDir: "{app}\languages"; Flags: ignoreversion
Source: "{#QtDir}\..\translations\qtbase_en.qm";   DestDir: "{app}\languages\qt"; DestName: "English.qm"; Flags: ignoreversion
Source: "{#QtDir}\..\translations\qtbase_fr.qm";   DestDir: "{app}\languages\qt"; DestName: "French.qm";  Flags: ignoreversion
Source: "{#QtDir}\..\translations\qtbase_ru.qm";   DestDir: "{app}\languages\qt"; DestName: "Russian.qm"; Flags: ignoreversion
Source: "{#QtPlugins}\platforms\qminimal.dll";     DestDir: "{app}\platforms"; Flags: ignoreversion
Source: "{#QtPlugins}\platforms\qoffscreen.dll";   DestDir: "{app}\platforms"; Flags: ignoreversion
Source: "{#QtPlugins}\platforms\qwindows.dll";     DestDir: "{app}\platforms"; Flags: ignoreversion
Source: "{#QtPlugins}\sqldrivers\qsqlite.dll";     DestDir: "{app}\sqldrivers"; Flags: ignoreversion
Source: "{#QtPlugins}\sqldrivers\qsqlmysql.dll";   DestDir: "{app}\sqldrivers"; Flags: ignoreversion
Source: "{#QtPlugins}\sqldrivers\qsqlodbc.dll";    DestDir: "{app}\sqldrivers"; Flags: ignoreversion
Source: "{#QtPlugins}\sqldrivers\qsqlpsql.dll";    DestDir: "{app}\sqldrivers"; Flags: ignoreversion
Source: "{#QtPlugins}\styles\qwindowsvistastyle.dll";   DestDir: "{app}\styles"; Flags: ignoreversion
Source: "..\release\sites\helper.js";                   DestDir: "{localappdata}\Bionus\Grabber\sites"; Flags: ignoreversion
Source: "..\release\sites\Anime pictures\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Anime pictures"; Flags: ignoreversion
Source: "..\release\sites\Anime pictures\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Anime pictures"; Flags: ignoreversion
Source: "..\release\sites\Anime pictures\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Anime pictures"; Flags: onlyifdoesntexist
Source: "..\release\sites\Anime pictures\anime-pictures.net\defaults.ini";  DestDir: "{localappdata}\Bionus\Grabber\sites\Anime pictures\anime-pictures.net"; Flags: ignoreversion
Source: "..\release\sites\Anime pictures\anime-pictures.net\tag-types.txt"; DestDir: "{localappdata}\Bionus\Grabber\sites\Anime pictures\anime-pictures.net"; Flags: onlyifdoesntexist
Source: "..\release\sites\Booru-on-rails\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Booru-on-rails"; Flags: ignoreversion
Source: "..\release\sites\Booru-on-rails\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Booru-on-rails"; Flags: ignoreversion
Source: "..\release\sites\Booru-on-rails\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Booru-on-rails"; Flags: onlyifdoesntexist
Source: "..\release\sites\Booru-on-rails\derpibooru.org\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\Booru-on-rails\derpibooru.org"; Flags: ignoreversion
Source: "..\release\sites\Danbooru\icon.png";           DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru"; Flags: ignoreversion
Source: "..\release\sites\Danbooru\model.js";           DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru"; Flags: ignoreversion
Source: "..\release\sites\Danbooru\sites.txt";          DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru"; Flags: onlyifdoesntexist
Source: "..\release\sites\Danbooru\behoimi.org\defaults.ini";              DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru\behoimi.org"; Flags: ignoreversion
Source: "..\release\sites\Danbooru\behoimi.org\tag-types.txt";             DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru\behoimi.org"; Flags: onlyifdoesntexist
Source: "..\release\sites\Danbooru\e621.net\defaults.ini";                 DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru\e621.net"; Flags: ignoreversion
Source: "..\release\sites\Danbooru\e621.net\tag-types.txt";                DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru\e621.net"; Flags: onlyifdoesntexist
Source: "..\release\sites\Sankaku\icon.png";            DestDir: "{localappdata}\Bionus\Grabber\sites\Sankaku"; Flags: ignoreversion
Source: "..\release\sites\Sankaku\model.js";            DestDir: "{localappdata}\Bionus\Grabber\sites\Sankaku"; Flags: ignoreversion
Source: "..\release\sites\Sankaku\sites.txt";           DestDir: "{localappdata}\Bionus\Grabber\sites\Sankaku"; Flags: onlyifdoesntexist
Source: "..\release\sites\Sankaku\chan.sankakucomplex.com\defaults.ini";  DestDir: "{localappdata}\Bionus\Grabber\sites\Sankaku\chan.sankakucomplex.com"; Flags: ignoreversion
Source: "..\release\sites\Sankaku\idol.sankakucomplex.com\defaults.ini";  DestDir: "{localappdata}\Bionus\Grabber\sites\Sankaku\idol.sankakucomplex.com"; Flags: ignoreversion
Source: "..\release\sites\Danbooru (2.0)\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru (2.0)"; Flags: ignoreversion
Source: "..\release\sites\Danbooru (2.0)\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru (2.0)"; Flags: ignoreversion
Source: "..\release\sites\Danbooru (2.0)\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru (2.0)"; Flags: onlyifdoesntexist
Source: "..\release\sites\Danbooru (2.0)\danbooru.donmai.us\defaults.ini";              DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru (2.0)\danbooru.donmai.us"; Flags: ignoreversion
Source: "..\release\sites\Danbooru (2.0)\danbooru.donmai.us\tag-types.txt";             DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru (2.0)\danbooru.donmai.us"; Flags: onlyifdoesntexist
Source: "..\release\sites\E-Hentai\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\E-Hentai"; Flags: ignoreversion
Source: "..\release\sites\E-Hentai\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\E-Hentai"; Flags: ignoreversion
Source: "..\release\sites\E-Hentai\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\E-Hentai"; Flags: onlyifdoesntexist
Source: "..\release\sites\E-Hentai\e-hentai.org\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\E-Hentai\e-hentai.org"; Flags: ignoreversion
Source: "..\release\sites\E-Hentai\exhentai.org\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\E-Hentai\exhentai.org"; Flags: ignoreversion
Source: "..\release\sites\FurAffinity\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\FurAffinity"; Flags: ignoreversion
Source: "..\release\sites\FurAffinity\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\FurAffinity"; Flags: ignoreversion
Source: "..\release\sites\FurAffinity\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\FurAffinity"; Flags: onlyifdoesntexist
Source: "..\release\sites\FurAffinity\www.furaffinity.net\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\FurAffinity\www.furaffinity.net"; Flags: ignoreversion
Source: "..\release\sites\Gelbooru (0.1)\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.1)"; Flags: ignoreversion
Source: "..\release\sites\Gelbooru (0.1)\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.1)"; Flags: ignoreversion
Source: "..\release\sites\Gelbooru (0.1)\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.1)"; Flags: onlyifdoesntexist
Source: "..\release\sites\Gelbooru (0.2)\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.2)"; Flags: ignoreversion
Source: "..\release\sites\Gelbooru (0.2)\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.2)"; Flags: ignoreversion
Source: "..\release\sites\Gelbooru (0.2)\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.2)"; Flags: onlyifdoesntexist
Source: "..\release\sites\Gelbooru (0.2)\gelbooru.com\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.2)\gelbooru.com"; Flags: ignoreversion
Source: "..\release\sites\Moebooru\icon.png";  DestDir: "{localappdata}\Bionus\Grabber\sites\Moebooru"; Flags: ignoreversion
Source: "..\release\sites\Moebooru\model.js";  DestDir: "{localappdata}\Bionus\Grabber\sites\Moebooru"; Flags: ignoreversion
Source: "..\release\sites\Moebooru\sites.txt"; DestDir: "{localappdata}\Bionus\Grabber\sites\Moebooru"; Flags: onlyifdoesntexist
Source: "..\release\sites\NHentai\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\NHentai"; Flags: ignoreversion
Source: "..\release\sites\NHentai\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\NHentai"; Flags: ignoreversion
Source: "..\release\sites\NHentai\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\NHentai"; Flags: onlyifdoesntexist
Source: "..\release\sites\NHentai\nhentai.net\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\NHentai\nhentai.net"; Flags: ignoreversion
Source: "..\release\sites\Pixiv\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Pixiv"; Flags: ignoreversion
Source: "..\release\sites\Pixiv\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Pixiv"; Flags: ignoreversion
Source: "..\release\sites\Pixiv\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Pixiv"; Flags: onlyifdoesntexist
Source: "..\release\sites\Pixiv\www.pixiv.net\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\Pixiv\www.pixiv.net"; Flags: ignoreversion
Source: "..\release\sites\Shimmie\icon.png";   DestDir: "{localappdata}\Bionus\Grabber\sites\Shimmie"; Flags: ignoreversion
Source: "..\release\sites\Shimmie\model.js";   DestDir: "{localappdata}\Bionus\Grabber\sites\Shimmie"; Flags: ignoreversion
Source: "..\release\sites\Shimmie\sites.txt";  DestDir: "{localappdata}\Bionus\Grabber\sites\Shimmie"; Flags: onlyifdoesntexist
Source: "..\release\sites\Twitter\icon.png";  DestDir: "{localappdata}\Bionus\Grabber\sites\Twitter"; Flags: ignoreversion
Source: "..\release\sites\Twitter\model.js";  DestDir: "{localappdata}\Bionus\Grabber\sites\Twitter"; Flags: ignoreversion
Source: "..\release\sites\Twitter\sites.txt"; DestDir: "{localappdata}\Bionus\Grabber\sites\Twitter"; Flags: onlyifdoesntexist
Source: "..\release\sites\Twitter\api.twitter.com\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\Twitter\api.twitter.com"; Flags: ignoreversion
Source: "..\release\sites\Zerochan\icon.png";  DestDir: "{localappdata}\Bionus\Grabber\sites\Zerochan"; Flags: ignoreversion
Source: "..\release\sites\Zerochan\model.js";  DestDir: "{localappdata}\Bionus\Grabber\sites\Zerochan"; Flags: ignoreversion
Source: "..\release\sites\Zerochan\sites.txt"; DestDir: "{localappdata}\Bionus\Grabber\sites\Zerochan"; Flags: onlyifdoesntexist
Source: "..\release\sites\Zerochan\www.zerochan.net\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\Zerochan\www.zerochan.net"; Flags: ignoreversion
Source: "..\release\themes\Default\*"; DestDir: "{localappdata}\Bionus\Grabber\themes\Default"; Flags: onlyifdoesntexist recursesubdirs
Source: "..\release\themes\QDarkStyleSheet\*"; DestDir: "{localappdata}\Bionus\Grabber\themes\QDarkStyleSheet"; Flags: onlyifdoesntexist recursesubdirs
Source: "..\release\webservices\*.ico"; DestDir: "{localappdata}\Bionus\Grabber\webservices"; Flags: onlyifdoesntexist

[InstallDelete]
Type: filesandordirs; Name: "{app}\languages\updater"
Type: filesandordirs; Name: "{app}\sites"
Type: files; Name: "{app}\Updater.exe"
Type: files; Name: "{app}\VERSION"
Type: files; Name: "{app}\MD5"
Type: files; Name: "{app}\libgcc_s_dw2-1.dll"
Type: files; Name: "{app}\QtCore4.dll"
Type: files; Name: "{app}\QtGui4.dll"
Type: files; Name: "{app}\QtNetwork4.dll"
Type: files; Name: "{app}\QtScript4.dll"
Type: files; Name: "{app}\QtSql4.dll"
Type: files; Name: "{app}\QtXml4.dll"
Type: files; Name: "{app}\imageformats\qgif4.dll"
Type: files; Name: "{app}\imageformats\qico4.dll"
Type: files; Name: "{app}\imageformats\qjpeg4.dll"
Type: files; Name: "{app}\imageformats\qmng4.dll"
Type: files; Name: "{app}\imageformats\qsvg4.dll"
Type: files; Name: "{app}\imageformats\qtga4.dll"
Type: files; Name: "{app}\imageformats\qtiff4.dll"
Type: files; Name: "{app}\sqldrivers\qsqlmysql4.dll"

[UninstallDelete]
Type: filesandordirs; Name: "{%UserProfile}\Grabber"

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; Flags: nowait postinstall skipifsilent

[Code]
function InitializeSetup(): Boolean;
begin
  initwinversion();

  SetForceX86(true);
	vcredist2013('12');
  SetForceX86(false);

  vcredist2015('14');

  Result := true;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then
  begin
    Log('Post install');
    SaveStringToFile(ExpandConstant('{localappdata}') + '\Bionus\Grabber\innosetup.ini', '[general]' + #13#10 + 'language=' + ExpandConstant('{language}') + #13#10, False);
  end;
end;

#define MyAppName "Grabber"
#define MyAppPublisher "Bionus"
#define MyAppURL "https://github.com/Bionus/imgbrd-grabber"
#define MyAppExeName "Grabber.exe"
#define BuildDir "..\build"

#ifndef QtDir
# define QtDir "C:\Qt\Qt5.10.1\5.10.1\msvc2015\bin"
#endif
#define QtPlugins QtDir + "\..\plugins"
#define QtLib QtDir + "\..\lib"

#ifndef OpenSSLDir
# define OpenSSLDir "C:\bin\OpenSSL-Win32-1.0.2k"
#endif

#ifndef MySQLDir
# define MySQLDir "C:\Program Files (x86)\MySQL\MySQL Server 5.7"
#endif

#ifndef MyAppVersion
# define MyAppVersion "7.0.1"
#endif

#ifndef QtApngDll
# define QtApngDll QtPlugins + "\imageformats\qapng.dll"
#endif

#define PlatformNamePrefix ""
#ifdef PlatformName
# define PlatformNamePrefix "_" + PlatformName
#endif

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{8C007AE6-3F7D-41CC-AB7C-75C08C276EC8}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
LicenseFile=Apache license 2.0.txt
OutputDir=.
OutputBaseFilename=Grabber_{#MyAppVersion}{#PlatformNamePrefix}
SetupIconFile=resources\images\icon.ico
UninstallDisplayName="{#MyAppName} {#MyAppVersion}"
UninstallDisplayIcon={app}\icon.ico
WizardSmallImageFile=resources\images\icon.bmp
Compression=lzma
SolidCompression=yes
ChangesAssociations=yes
DisableDirPage=no
PrivilegesRequired=admin
ArchitecturesAllowed=x86 x64 ia64
ArchitecturesInstallIn64BitMode=x64 ia64

; downloading and installing dependencies will only work if the memo/ready page is enabled (default and current behaviour)
DisableReadyPage=no
DisableReadyMemo=no

[CustomMessages]
en.IGL=Imageboard-Grabber Links
fr.IGL=Liens Imageboard-Grabber
DependenciesDir=MyProgramDependencies
WindowsServicePack=Windows %1 Service Pack %2

[Registry]
Root: HKCR; Subkey: ".igl"; ValueType: string; ValueName: ""; ValueData: "Imageboard-Grabber"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "Imageboard-Grabber"; ValueType: string; ValueName: ""; ValueData: "{cm:IGL}"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Imageboard-Grabber\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKCR; Subkey: "Imageboard-Grabber\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""

; Languages
#include "scripts\lang\english.iss"
#include "scripts\lang\german.iss"
#include "scripts\lang\french.iss"
#include "scripts\lang\italian.iss"
#include "scripts\lang\dutch.iss"

#ifdef UNICODE
#include "scripts\lang\chinese.iss"
#include "scripts\lang\polish.iss"
#include "scripts\lang\russian.iss"
#include "scripts\lang\japanese.iss"
#endif

#include "scripts\products.iss"
#include "scripts\products\stringversion.iss"
#include "scripts\products\winversion.iss"
#include "scripts\products\fileversion.iss"
#include "scripts\products\msiproduct.iss"
#include "scripts\products\vcredist2013.iss"
#include "scripts\products\vcredist2015.iss"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1

[Files]
Source: "resources\images\icon.ico";            DestDir: "{app}"; Flags: ignoreversion
Source: "..\release\CDR.exe";                   DestDir: "{app}"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\CrashReporter.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#BuildDir}\cli\Grabber-cli.exe";      DestDir: "{app}"; Flags: ignoreversion; DestName: "Grabber.com"
Source: "{#BuildDir}\gui\Grabber.exe";          DestDir: "{app}"; Flags: ignoreversion;
Source: "..\release\words.txt";                 DestDir: "{app}";
Source: "{#OpenSSLDir}\libeay32.dll";           DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\libEGL.dll";                  DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\libGLESv2.dll";               DestDir: "{app}"; Flags: ignoreversion
Source: "{#MySQLDir}\lib\libmysql.dll";         DestDir: "{app}"; Flags: ignoreversion
Source: "{#OpenSSLDir}\libssl32.dll";           DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtLib}\qscintilla2_qt5.dll";         DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Concurrent.dll";           DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Core.dll";                 DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Gui.dll";                  DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Multimedia.dll";           DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Network.dll";              DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5OpenGL.dll";               DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5PrintSupport.dll";         DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Qml.dll";                  DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Sql.dll";                  DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Widgets.dll";              DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5Xml.dll";                  DestDir: "{app}"; Flags: ignoreversion
Source: "{#QtDir}\Qt5WinExtras.dll";            DestDir: "{app}"; Flags: ignoreversion
Source: "{#OpenSSLDir}\ssleay32.dll";           DestDir: "{app}"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\languages\ChineseSimplified.qm"; DestDir: "{app}\crashreporter"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\languages\English.qm";  DestDir: "{app}\crashreporter"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\languages\French.qm";   DestDir: "{app}\crashreporter"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\languages\Russian.qm";  DestDir: "{app}\crashreporter"; Flags: ignoreversion
Source: "{#BuildDir}\CrashReporter\languages\Spanish.qm";  DestDir: "{app}\crashreporter"; Flags: ignoreversion
Source: "{#QtApngDll}";                         DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qdds.dll";   DestDir: "{app}\imageformats"; Flags: ignoreversion skipifsourcedoesntexist
Source: "{#QtPlugins}\imageformats\qgif.dll";   DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qicns.dll";  DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qico.dll";   DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qjpeg.dll";  DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qsvg.dll";   DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qtga.dll";   DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qtiff.dll";  DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qwbmp.dll";  DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#QtPlugins}\imageformats\qwebp.dll";  DestDir: "{app}\imageformats"; Flags: ignoreversion
Source: "{#BuildDir}\languages\ChineseSimplified.qm"; DestDir: "{app}\languages"; Flags: ignoreversion
Source: "{#BuildDir}\languages\English.qm";     DestDir: "{app}\languages"; Flags: ignoreversion
Source: "{#BuildDir}\languages\French.qm";      DestDir: "{app}\languages"; Flags: ignoreversion
Source: "{#BuildDir}\languages\Russian.qm";     DestDir: "{app}\languages"; Flags: ignoreversion
Source: "{#BuildDir}\languages\Spanish.qm";     DestDir: "{app}\languages"; Flags: ignoreversion
Source: "..\release\languages\languages.ini";   DestDir: "{app}\languages"; Flags: ignoreversion
Source: "{#QtDir}\..\translations\qtbase_en.qm";   DestDir: "{app}\languages\qt"; DestName: "English.qm"; Flags: ignoreversion
Source: "{#QtDir}\..\translations\qtbase_fr.qm";   DestDir: "{app}\languages\qt"; DestName: "French.qm";  Flags: ignoreversion
Source: "{#QtDir}\..\translations\qtbase_ru.qm";   DestDir: "{app}\languages\qt"; DestName: "Russian.qm"; Flags: ignoreversion
Source: "{#QtPlugins}\platforms\qminimal.dll";     DestDir: "{app}\platforms"; Flags: ignoreversion
Source: "{#QtPlugins}\platforms\qoffscreen.dll";   DestDir: "{app}\platforms"; Flags: ignoreversion
Source: "{#QtPlugins}\platforms\qwindows.dll";     DestDir: "{app}\platforms"; Flags: ignoreversion
Source: "{#QtPlugins}\sqldrivers\qsqlite.dll";     DestDir: "{app}\sqldrivers"; Flags: ignoreversion
Source: "{#QtPlugins}\sqldrivers\qsqlmysql.dll";   DestDir: "{app}\sqldrivers"; Flags: ignoreversion
Source: "{#QtPlugins}\sqldrivers\qsqlodbc.dll";    DestDir: "{app}\sqldrivers"; Flags: ignoreversion
Source: "{#QtPlugins}\sqldrivers\qsqlpsql.dll";    DestDir: "{app}\sqldrivers"; Flags: ignoreversion
Source: "{#QtPlugins}\styles\qwindowsvistastyle.dll";   DestDir: "{app}\styles"; Flags: ignoreversion
Source: "..\release\sites\helper.js";                   DestDir: "{localappdata}\Bionus\Grabber\sites"; Flags: ignoreversion
Source: "..\release\sites\Anime pictures\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Anime pictures"; Flags: ignoreversion
Source: "..\release\sites\Anime pictures\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Anime pictures"; Flags: ignoreversion
Source: "..\release\sites\Anime pictures\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Anime pictures"; Flags: onlyifdoesntexist
Source: "..\release\sites\Anime pictures\anime-pictures.net\defaults.ini";  DestDir: "{localappdata}\Bionus\Grabber\sites\Anime pictures\anime-pictures.net"; Flags: ignoreversion
Source: "..\release\sites\Anime pictures\anime-pictures.net\tag-types.txt"; DestDir: "{localappdata}\Bionus\Grabber\sites\Anime pictures\anime-pictures.net"; Flags: onlyifdoesntexist
Source: "..\release\sites\Booru-on-rails\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Booru-on-rails"; Flags: ignoreversion
Source: "..\release\sites\Booru-on-rails\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Booru-on-rails"; Flags: ignoreversion
Source: "..\release\sites\Booru-on-rails\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Booru-on-rails"; Flags: onlyifdoesntexist
Source: "..\release\sites\Booru-on-rails\derpibooru.org\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\Booru-on-rails\derpibooru.org"; Flags: ignoreversion
Source: "..\release\sites\Danbooru\icon.png";           DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru"; Flags: ignoreversion
Source: "..\release\sites\Danbooru\model.js";           DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru"; Flags: ignoreversion
Source: "..\release\sites\Danbooru\sites.txt";          DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru"; Flags: onlyifdoesntexist
Source: "..\release\sites\Danbooru\behoimi.org\defaults.ini";              DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru\behoimi.org"; Flags: ignoreversion
Source: "..\release\sites\Danbooru\behoimi.org\tag-types.txt";             DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru\behoimi.org"; Flags: onlyifdoesntexist
Source: "..\release\sites\Danbooru\e621.net\defaults.ini";                 DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru\e621.net"; Flags: ignoreversion
Source: "..\release\sites\Danbooru\e621.net\tag-types.txt";                DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru\e621.net"; Flags: onlyifdoesntexist
Source: "..\release\sites\Sankaku\icon.png";            DestDir: "{localappdata}\Bionus\Grabber\sites\Sankaku"; Flags: ignoreversion
Source: "..\release\sites\Sankaku\model.js";            DestDir: "{localappdata}\Bionus\Grabber\sites\Sankaku"; Flags: ignoreversion
Source: "..\release\sites\Sankaku\sites.txt";           DestDir: "{localappdata}\Bionus\Grabber\sites\Sankaku"; Flags: onlyifdoesntexist
Source: "..\release\sites\Sankaku\chan.sankakucomplex.com\defaults.ini";  DestDir: "{localappdata}\Bionus\Grabber\sites\Sankaku\chan.sankakucomplex.com"; Flags: ignoreversion
Source: "..\release\sites\Sankaku\idol.sankakucomplex.com\defaults.ini";  DestDir: "{localappdata}\Bionus\Grabber\sites\Sankaku\idol.sankakucomplex.com"; Flags: ignoreversion
Source: "..\release\sites\Danbooru (2.0)\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru (2.0)"; Flags: ignoreversion
Source: "..\release\sites\Danbooru (2.0)\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru (2.0)"; Flags: ignoreversion
Source: "..\release\sites\Danbooru (2.0)\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru (2.0)"; Flags: onlyifdoesntexist
Source: "..\release\sites\Danbooru (2.0)\danbooru.donmai.us\defaults.ini";              DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru (2.0)\danbooru.donmai.us"; Flags: ignoreversion
Source: "..\release\sites\Danbooru (2.0)\danbooru.donmai.us\tag-types.txt";             DestDir: "{localappdata}\Bionus\Grabber\sites\Danbooru (2.0)\danbooru.donmai.us"; Flags: onlyifdoesntexist
Source: "..\release\sites\E-Hentai\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\E-Hentai"; Flags: ignoreversion
Source: "..\release\sites\E-Hentai\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\E-Hentai"; Flags: ignoreversion
Source: "..\release\sites\E-Hentai\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\E-Hentai"; Flags: onlyifdoesntexist
Source: "..\release\sites\E-Hentai\e-hentai.org\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\E-Hentai\e-hentai.org"; Flags: ignoreversion
Source: "..\release\sites\E-Hentai\exhentai.org\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\E-Hentai\exhentai.org"; Flags: ignoreversion
Source: "..\release\sites\FurAffinity\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\FurAffinity"; Flags: ignoreversion
Source: "..\release\sites\FurAffinity\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\FurAffinity"; Flags: ignoreversion
Source: "..\release\sites\FurAffinity\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\FurAffinity"; Flags: onlyifdoesntexist
Source: "..\release\sites\FurAffinity\www.furaffinity.net\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\FurAffinity\www.furaffinity.net"; Flags: ignoreversion
Source: "..\release\sites\Gelbooru (0.1)\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.1)"; Flags: ignoreversion
Source: "..\release\sites\Gelbooru (0.1)\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.1)"; Flags: ignoreversion
Source: "..\release\sites\Gelbooru (0.1)\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.1)"; Flags: onlyifdoesntexist
Source: "..\release\sites\Gelbooru (0.2)\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.2)"; Flags: ignoreversion
Source: "..\release\sites\Gelbooru (0.2)\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.2)"; Flags: ignoreversion
Source: "..\release\sites\Gelbooru (0.2)\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.2)"; Flags: onlyifdoesntexist
Source: "..\release\sites\Gelbooru (0.2)\gelbooru.com\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\Gelbooru (0.2)\gelbooru.com"; Flags: ignoreversion
Source: "..\release\sites\Moebooru\icon.png";  DestDir: "{localappdata}\Bionus\Grabber\sites\Moebooru"; Flags: ignoreversion
Source: "..\release\sites\Moebooru\model.js";  DestDir: "{localappdata}\Bionus\Grabber\sites\Moebooru"; Flags: ignoreversion
Source: "..\release\sites\Moebooru\sites.txt"; DestDir: "{localappdata}\Bionus\Grabber\sites\Moebooru"; Flags: onlyifdoesntexist
Source: "..\release\sites\Pixiv\icon.png";     DestDir: "{localappdata}\Bionus\Grabber\sites\Pixiv"; Flags: ignoreversion
Source: "..\release\sites\Pixiv\model.js";     DestDir: "{localappdata}\Bionus\Grabber\sites\Pixiv"; Flags: ignoreversion
Source: "..\release\sites\Pixiv\sites.txt";    DestDir: "{localappdata}\Bionus\Grabber\sites\Pixiv"; Flags: onlyifdoesntexist
Source: "..\release\sites\Pixiv\www.pixiv.net\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\Pixiv\www.pixiv.net"; Flags: ignoreversion
Source: "..\release\sites\Shimmie\icon.png";   DestDir: "{localappdata}\Bionus\Grabber\sites\Shimmie"; Flags: ignoreversion
Source: "..\release\sites\Shimmie\model.js";   DestDir: "{localappdata}\Bionus\Grabber\sites\Shimmie"; Flags: ignoreversion
Source: "..\release\sites\Shimmie\sites.txt";  DestDir: "{localappdata}\Bionus\Grabber\sites\Shimmie"; Flags: onlyifdoesntexist
Source: "..\release\sites\Twitter\icon.png";  DestDir: "{localappdata}\Bionus\Grabber\sites\Twitter"; Flags: ignoreversion
Source: "..\release\sites\Twitter\model.js";  DestDir: "{localappdata}\Bionus\Grabber\sites\Twitter"; Flags: ignoreversion
Source: "..\release\sites\Twitter\sites.txt"; DestDir: "{localappdata}\Bionus\Grabber\sites\Twitter"; Flags: onlyifdoesntexist
Source: "..\release\sites\Twitter\api.twitter.com\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\Twitter\api.twitter.com"; Flags: ignoreversion
Source: "..\release\sites\Zerochan\icon.png";  DestDir: "{localappdata}\Bionus\Grabber\sites\Zerochan"; Flags: ignoreversion
Source: "..\release\sites\Zerochan\model.js";  DestDir: "{localappdata}\Bionus\Grabber\sites\Zerochan"; Flags: ignoreversion
Source: "..\release\sites\Zerochan\sites.txt"; DestDir: "{localappdata}\Bionus\Grabber\sites\Zerochan"; Flags: onlyifdoesntexist
Source: "..\release\sites\Zerochan\www.zerochan.net\defaults.ini"; DestDir: "{localappdata}\Bionus\Grabber\sites\Zerochan\www.zerochan.net"; Flags: ignoreversion
Source: "..\release\themes\Default\*"; DestDir: "{localappdata}\Bionus\Grabber\themes\Default"; Flags: onlyifdoesntexist recursesubdirs
Source: "..\release\themes\QDarkStyleSheet\*"; DestDir: "{localappdata}\Bionus\Grabber\themes\QDarkStyleSheet"; Flags: onlyifdoesntexist recursesubdirs
Source: "..\release\webservices\*.ico"; DestDir: "{localappdata}\Bionus\Grabber\webservices"; Flags: onlyifdoesntexist

[InstallDelete]
Type: filesandordirs; Name: "{app}\languages\updater"
Type: filesandordirs; Name: "{app}\sites"
Type: files; Name: "{app}\Updater.exe"
Type: files; Name: "{app}\VERSION"
Type: files; Name: "{app}\MD5"
Type: files; Name: "{app}\libgcc_s_dw2-1.dll"
Type: files; Name: "{app}\QtCore4.dll"
Type: files; Name: "{app}\QtGui4.dll"
Type: files; Name: "{app}\QtNetwork4.dll"
Type: files; Name: "{app}\QtScript4.dll"
Type: files; Name: "{app}\QtSql4.dll"
Type: files; Name: "{app}\QtXml4.dll"
Type: files; Name: "{app}\imageformats\qgif4.dll"
Type: files; Name: "{app}\imageformats\qico4.dll"
Type: files; Name: "{app}\imageformats\qjpeg4.dll"
Type: files; Name: "{app}\imageformats\qmng4.dll"
Type: files; Name: "{app}\imageformats\qsvg4.dll"
Type: files; Name: "{app}\imageformats\qtga4.dll"
Type: files; Name: "{app}\imageformats\qtiff4.dll"
Type: files; Name: "{app}\sqldrivers\qsqlmysql4.dll"

[UninstallDelete]
Type: filesandordirs; Name: "{%UserProfile}\Grabber"

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; Flags: nowait postinstall skipifsilent

[Code]
function InitializeSetup(): Boolean;
begin
  initwinversion();

  SetForceX86(true);
	vcredist2013('12');
  SetForceX86(false);

  vcredist2015('14');

  Result := true;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then
  begin
    Log('Post install');
    SaveStringToFile(ExpandConstant('{localappdata}') + '\Bionus\Grabber\innosetup.ini', '[general]' + #13#10 + 'language=' + ExpandConstant('{language}') + #13#10, False);
  end;
end;