From d074ba5974d0ba0a1656f6379a18146bbd7d9342 Mon Sep 17 00:00:00 2001 From: Sel Date: Thu, 20 Aug 2020 01:14:14 -0400 Subject: [PATCH] Atomic Commit --- .gitignore | 4 + DotNetChecker.nsh | 141 ++++++++++++++++++++++++++++++++ FileAssociation.nsh | 190 ++++++++++++++++++++++++++++++++++++++++++++ ffxiv2.ico | Bin 0 -> 15086 bytes textools.nsi | 160 +++++++++++++++++++++++++++++++++++++ 5 files changed, 495 insertions(+) create mode 100644 .gitignore create mode 100644 DotNetChecker.nsh create mode 100644 FileAssociation.nsh create mode 100644 ffxiv2.ico create mode 100644 textools.nsi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b73951 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +FFXIV_TexTools*.zip +Install_TexTools.exe +FFXIV_Textools/* +20*_redist*.exe \ No newline at end of file diff --git a/DotNetChecker.nsh b/DotNetChecker.nsh new file mode 100644 index 0000000..34ef1a6 --- /dev/null +++ b/DotNetChecker.nsh @@ -0,0 +1,141 @@ +!macro CheckNetFramework FrameworkVersion + Var /GLOBAL dotNetUrl${FrameworkVersion} + Var /GLOBAL dotNetReadableVersion${FrameworkVersion} + + !ifndef DOTNET472_URL + !define DOTNET472_URL "https://go.microsoft.com/fwlink/?LinkId=863265" + !define DOTNET471_URL "https://go.microsoft.com/fwlink/?LinkId=852104" + !define DOTNET47_URL "https://go.microsoft.com/fwlink/?LinkId=825302" + !define DOTNET462_URL "https://go.microsoft.com/fwlink/?LinkId=780600" + !define DOTNET461_URL "https://go.microsoft.com/fwlink/?LinkId=671743" + !define DOTNET46_URL "https://go.microsoft.com/fwlink/?LinkId=528232" + !define DOTNET452_URL "https://go.microsoft.com/fwlink/?LinkId=397708" + !define DOTNET451_URL "https://go.microsoft.com/fwlink/?LinkId=322116" + !define DOTNET45_URL "https://go.microsoft.com/fwlink/?LinkId=225702" + !define DOTNET40Full_URL "https://www.microsoft.com/downloads/info.aspx?na=41&srcfamilyid=0a391abd-25c1-4fc0-919f-b21f31ab88b7&srcdisplaylang=en&u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f9%2f5%2fA%2f95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE%2fdotNetFx40_Full_x86_x64.exe" + !define DOTNET40Client_URL "https://www.microsoft.com/downloads/info.aspx?na=41&srcfamilyid=e5ad0459-cbcc-4b4f-97b6-fb17111cf544&srcdisplaylang=en&u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f5%2f6%2f2%2f562A10F9-C9F4-4313-A044-9C94E0A8FAC8%2fdotNetFx40_Client_x86_x64.exe" + !define DOTNET35_URL "https://download.microsoft.com/download/2/0/e/20e90413-712f-438c-988e-fdaa79a8ac3d/dotnetfx35.exe" + !define DOTNET30_URL "https://download.microsoft.com/download/2/0/e/20e90413-712f-438c-988e-fdaa79a8ac3d/dotnetfx35.exe" + !define DOTNET20_URL "https://www.microsoft.com/downloads/info.aspx?na=41&srcfamilyid=0856eacb-4362-4b0d-8edd-aab15c5e04f5&srcdisplaylang=en&u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f5%2f6%2f7%2f567758a3-759e-473e-bf8f-52154438565a%2fdotnetfx.exe" + !define DOTNET11_URL "https://www.microsoft.com/downloads/info.aspx?na=41&srcfamilyid=262d25e3-f589-4842-8157-034d1e7cf3a3&srcdisplaylang=en&u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2fa%2fa%2fc%2faac39226-8825-44ce-90e3-bf8203e74006%2fdotnetfx.exe" + !define DOTNET10_URL "https://www.microsoft.com/downloads/info.aspx?na=41&srcfamilyid=262d25e3-f589-4842-8157-034d1e7cf3a3&srcdisplaylang=en&u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2fa%2fa%2fc%2faac39226-8825-44ce-90e3-bf8203e74006%2fdotnetfx.exe" + !endif + + ${If} ${FrameworkVersion} == "472" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET472_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.7.2" + ${ElseIf} ${FrameworkVersion} == "471" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET471_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.7.1" + ${ElseIf} ${FrameworkVersion} == "47" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET47_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.7" + ${ElseIf} ${FrameworkVersion} == "462" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET462_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.6.2" + ${ElseIf} ${FrameworkVersion} == "461" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET461_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.6.1" + ${ElseIf} ${FrameworkVersion} == "46" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET46_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.6" + ${ElseIf} ${FrameworkVersion} == "452" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET452_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.52" + ${ElseIf} ${FrameworkVersion} == "451" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET451_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.51" + ${ElseIf} ${FrameworkVersion} == "45" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET45_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.5" + ${ElseIf} ${FrameworkVersion} == "40Full" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET40Full_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.0 Full" + ${ElseIf} ${FrameworkVersion} == "40Client" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET40Client_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "4.0 Client" + ${ElseIf} ${FrameworkVersion} == "35" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET35_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "3.5" + ${ElseIf} ${FrameworkVersion} == "30" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET30_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "3.0" + ${ElseIf} ${FrameworkVersion} == "20" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET20_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "2.0" + ${ElseIf} ${FrameworkVersion} == "11" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET11_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "1.1" + ${ElseIf} ${FrameworkVersion} == "10" + StrCpy $dotNetUrl${FrameworkVersion} ${DOTNET10_URL} + StrCpy $dotNetReadableVersion${FrameworkVersion} "1.0" + ${EndIf} + + DetailPrint "Checking .NET Framework version..." + + Push $0 + Push $1 + Push $2 + Push $3 + Push $4 + Push $5 + Push $6 + Push $7 + + DotNetChecker::IsDotNet${FrameworkVersion}Installed + Pop $0 + + ${If} $0 == "false" + ${OrIf} $0 == "f" ; if script is compiled in ANSI mode then we get only an "f" https://github.com/ReVolly/NsisDotNetChecker/issues/4 + DetailPrint ".NET Framework $dotNetReadableVersion${FrameworkVersion} not found, download is required for program to run." + Goto NoDotNET${FrameworkVersion} + ${Else} + DetailPrint ".NET Framework $dotNetReadableVersion${FrameworkVersion} found, no need to install." + Goto NewDotNET${FrameworkVersion} + ${EndIf} + +NoDotNET${FrameworkVersion}: + MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \ + ".NET Framework not installed. Required version: $dotNetReadableVersion${FrameworkVersion}.$\nDownload .NET Framework $dotNetReadableVersion${FrameworkVersion} from microsoft.com?" \ + /SD IDYES IDYES DownloadDotNET${FrameworkVersion} IDNO NewDotNET${FrameworkVersion} + goto GiveUpDotNET${FrameworkVersion} ;IDCANCEL + +DownloadDotNET${FrameworkVersion}: + DetailPrint "Beginning download of .NET Framework $dotNetReadableVersion${FrameworkVersion}." + NSISDL::download $dotNetUrl${FrameworkVersion} "$TEMP\dotnetfx.exe" + DetailPrint "Completed download." + + Pop $0 + ${If} $0 == "cancel" + MessageBox MB_YESNO|MB_ICONEXCLAMATION \ + "Download canceled. Continue Installation?" \ + IDYES NewDotNET${FrameworkVersion} IDNO GiveUpDotNET${FrameworkVersion} + ${ElseIf} $0 != "success" + MessageBox MB_YESNO|MB_ICONEXCLAMATION \ + "Download failed:$\n$0$\n$\nContinue Installation?" \ + IDYES NewDotNET${FrameworkVersion} IDNO GiveUpDotNET${FrameworkVersion} + ${EndIf} + + DetailPrint "Pausing installation while downloaded .NET Framework installer runs." + ExecWait '$TEMP\dotnetfx.exe /q /c:"install /q"' + + DetailPrint "Completed .NET Framework install/update. Removing .NET Framework installer." + Delete "$TEMP\dotnetfx.exe" + DetailPrint ".NET Framework installer removed." + goto NewDotNet${FrameworkVersion} + +GiveUpDotNET${FrameworkVersion}: + Abort "Installation canceled by user." + +NewDotNET${FrameworkVersion}: + DetailPrint "Proceeding with remainder of installation." + Pop $7 + Pop $6 + Pop $5 + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Pop $0 + +!macroend diff --git a/FileAssociation.nsh b/FileAssociation.nsh new file mode 100644 index 0000000..b8c1e5e --- /dev/null +++ b/FileAssociation.nsh @@ -0,0 +1,190 @@ +/* +_____________________________________________________________________________ + + File Association +_____________________________________________________________________________ + + Based on code taken from http://nsis.sourceforge.net/File_Association + + Usage in script: + 1. !include "FileAssociation.nsh" + 2. [Section|Function] + ${FileAssociationFunction} "Param1" "Param2" "..." $var + [SectionEnd|FunctionEnd] + + FileAssociationFunction=[RegisterExtension|UnRegisterExtension] + +_____________________________________________________________________________ + + ${RegisterExtension} "[executable]" "[extension]" "[description]" + +"[executable]" ; executable which opens the file format + ; +"[extension]" ; extension, which represents the file format to open + ; +"[description]" ; description for the extension. This will be display in Windows Explorer. + ; + + + ${UnRegisterExtension} "[extension]" "[description]" + +"[extension]" ; extension, which represents the file format to open + ; +"[description]" ; description for the extension. This will be display in Windows Explorer. + ; + +_____________________________________________________________________________ + + Macros +_____________________________________________________________________________ + + Change log window verbosity (default: 3=no script) + + Example: + !include "FileAssociation.nsh" + !insertmacro RegisterExtension + ${FileAssociation_VERBOSE} 4 # all verbosity + !insertmacro UnRegisterExtension + ${FileAssociation_VERBOSE} 3 # no script +*/ + + +!ifndef FileAssociation_INCLUDED +!define FileAssociation_INCLUDED + +!include Util.nsh + +!verbose push +!verbose 3 +!ifndef _FileAssociation_VERBOSE + !define _FileAssociation_VERBOSE 3 +!endif +!verbose ${_FileAssociation_VERBOSE} +!define FileAssociation_VERBOSE `!insertmacro FileAssociation_VERBOSE` +!verbose pop + +!macro FileAssociation_VERBOSE _VERBOSE + !verbose push + !verbose 3 + !undef _FileAssociation_VERBOSE + !define _FileAssociation_VERBOSE ${_VERBOSE} + !verbose pop +!macroend + + + +!macro RegisterExtensionCall _EXECUTABLE _EXTENSION _DESCRIPTION + !verbose push + !verbose ${_FileAssociation_VERBOSE} + Push `${_DESCRIPTION}` + Push `${_EXTENSION}` + Push `${_EXECUTABLE}` + ${CallArtificialFunction} RegisterExtension_ + !verbose pop +!macroend + +!macro UnRegisterExtensionCall _EXTENSION _DESCRIPTION + !verbose push + !verbose ${_FileAssociation_VERBOSE} + Push `${_EXTENSION}` + Push `${_DESCRIPTION}` + ${CallArtificialFunction} UnRegisterExtension_ + !verbose pop +!macroend + + + +!define RegisterExtension `!insertmacro RegisterExtensionCall` +!define un.RegisterExtension `!insertmacro RegisterExtensionCall` + +!macro RegisterExtension +!macroend + +!macro un.RegisterExtension +!macroend + +!macro RegisterExtension_ + !verbose push + !verbose ${_FileAssociation_VERBOSE} + + Exch $R2 ;exe + Exch + Exch $R1 ;ext + Exch + Exch 2 + Exch $R0 ;desc + Exch 2 + Push $0 + Push $1 + + ReadRegStr $1 HKCR $R1 "" ; read current file association + StrCmp "$1" "" NoBackup ; is it empty + StrCmp "$1" "$R0" NoBackup ; is it our own + WriteRegStr HKCR $R1 "backup_val" "$1" ; backup current value +NoBackup: + WriteRegStr HKCR $R1 "" "$R0" ; set our file association + + ReadRegStr $0 HKCR $R0 "" + StrCmp $0 "" 0 Skip + WriteRegStr HKCR "$R0" "" "$R0" + WriteRegStr HKCR "$R0\shell" "" "open" + WriteRegStr HKCR "$R0\DefaultIcon" "" "$R2,0" +Skip: + WriteRegStr HKCR "$R0\shell\open\command" "" '"$R2" "%1"' + WriteRegStr HKCR "$R0\shell\edit" "" "Edit $R0" + WriteRegStr HKCR "$R0\shell\edit\command" "" '"$R2" "%1"' + + Pop $1 + Pop $0 + Pop $R2 + Pop $R1 + Pop $R0 + + !verbose pop +!macroend + + + +!define UnRegisterExtension `!insertmacro UnRegisterExtensionCall` +!define un.UnRegisterExtension `!insertmacro UnRegisterExtensionCall` + +!macro UnRegisterExtension +!macroend + +!macro un.UnRegisterExtension +!macroend + +!macro UnRegisterExtension_ + !verbose push + !verbose ${_FileAssociation_VERBOSE} + + Exch $R1 ;desc + Exch + Exch $R0 ;ext + Exch + Push $0 + Push $1 + + ReadRegStr $1 HKCR $R0 "" + StrCmp $1 $R1 0 NoOwn ; only do this if we own it + ReadRegStr $1 HKCR $R0 "backup_val" + StrCmp $1 "" 0 Restore ; if backup="" then delete the whole key + DeleteRegKey HKCR $R0 + Goto NoOwn + +Restore: + WriteRegStr HKCR $R0 "" $1 + DeleteRegValue HKCR $R0 "backup_val" + DeleteRegKey HKCR $R1 ;Delete key with association name settings + +NoOwn: + + Pop $1 + Pop $0 + Pop $R1 + Pop $R0 + + !verbose pop +!macroend + +!endif # !FileAssociation_INCLUDED \ No newline at end of file diff --git a/ffxiv2.ico b/ffxiv2.ico new file mode 100644 index 0000000000000000000000000000000000000000..e1c8474bfada0b0f33bbfeb6d4e0118489261285 GIT binary patch literal 15086 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