This commit is contained in:
2022-09-30 05:39:11 +00:00
parent 41ee9463ae
commit 4687fa49bc
11418 changed files with 1312504 additions and 0 deletions

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!--suppress XmlUnusedNamespaceDeclaration -->
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities">
<!-- use single quotes to avoid double quotes escaping in the publisher value -->
<Identity Name="${identityName}"
ProcessorArchitecture="${arch}"
Publisher='${publisher}'
Version="${version}" />
<Properties>
<DisplayName>${displayName}</DisplayName>
<PublisherDisplayName>${publisherDisplayName}</PublisherDisplayName>
<Description>${description}</Description>
<Logo>${logo}</Logo>
</Properties>
<Resources>
${resourceLanguages}
</Resources>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="${minVersion}" MaxVersionTested="${maxVersionTested}" />
</Dependencies>
<Capabilities>
<rescap:Capability Name="runFullTrust"/>
</Capabilities>
<Applications>
<Application Id="${applicationId}" Executable="${executable}" EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements
BackgroundColor="${backgroundColor}"
DisplayName="${displayName}"
Square150x150Logo="${square150x150Logo}"
Square44x44Logo="${square44x44Logo}"
Description="${description}">
${lockScreen}
${defaultTile}
${splashScreen}
</uap:VisualElements>
${extensions}
</Application>
</Applications>
</Package>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<resources targetOsVersion="10.0.0" majorVersion="1">
<packaging>
<autoResourcePackage qualifier="Language"/>
<autoResourcePackage qualifier="Scale"/>
<autoResourcePackage qualifier="DXFeatureLevel"/>
</packaging>
<index root="\" startIndexAt="\">
<default>
<qualifier name="Language" value="en-US"/>
<qualifier name="Contrast" value="standard"/>
<qualifier name="Scale" value="100"/>
<qualifier name="HomeRegion" value="001"/>
<qualifier name="TargetSize" value="256"/>
<qualifier name="LayoutDirection" value="LTR"/>
<qualifier name="Theme" value="dark"/>
<qualifier name="AlternateForm" value=""/>
<qualifier name="DXFeatureLevel" value="DX9"/>
<qualifier name="Configuration" value=""/>
<qualifier name="DeviceFamily" value="Universal"/>
<qualifier name="Custom" value=""/>
</default>
<indexer-config type="folder" foldernameAsQualifier="true" filenameAsQualifier="true" qualifierDelimiter="."/>
<indexer-config type="resw" convertDotsToSlashes="true" initialPath=""/>
<indexer-config type="resjson" initialPath=""/>
<indexer-config type="PRI"/>
</index>
</resources>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- https://github.com/electron/electron-notarize#prerequisites -->
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<!-- https://github.com/electron-userland/electron-builder/issues/3940 -->
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

View File

@ -0,0 +1,20 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-13 -13 58.2 58.4">
<style>
.st0{
fill: #000;
}
.circ{
stroke: #000;
fill: white;
stroke-wdith: 1;
}
</style>
<circle class="circ" cx="16.1" cy="16.1" r="25"/>
<g> <!-- viewBox="0 0 32.2 32.4" -->
<circle class="st0" cx="5.5" cy="5.5" r="5.5"/>
<circle class="st0" cx="26.6" cy="5.5" r="5.5"/>
<circle class="st0" cx="5.5" cy="26.9" r="5.5"/>
<circle class="st0" cx="26.6" cy="26.9" r="5.5"/>
<path transform="rotate(-45.361 16.087 16.23)" class="st0" d="M1.1 15.1h30v2.3h-30z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 575 B

View File

@ -0,0 +1,10 @@
#!/bin/bash
# Link to the binary
ln -sf '/opt/${productFilename}/${executable}' '/usr/bin/${executable}'
# SUID chrome-sandbox for Electron 5+
chmod 4755 '/opt/${productFilename}/chrome-sandbox' || true
update-mime-database /usr/share/mime || true
update-desktop-database /usr/share/applications || true

View File

@ -0,0 +1,4 @@
#!/bin/bash
# Delete the link to the binary
rm -f '/usr/bin/${executable}'

View File

@ -0,0 +1,6 @@
[Desktop Entry]
Name=<%= title %>
Comment=<%= comment %>
Exec=<%= executable %>
Terminal=false
Type=Application

View File

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment>
<WixVariable Id="WixUISupportPerUser" Value="1" Overridable="yes"/>
<WixVariable Id="WixUISupportPerMachine" Value="1" Overridable="yes"/>
<PropertyRef Id="ApplicationFolderName"/>
<UI Id="WixUI_Assisted">
<Dialog Id="InstallScopeDialog" Width="370" Height="270" Title="!(loc.InstallScopeDlg_Title)" KeepModeless="yes">
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.InstallScopeDlgBannerBitmap)"/>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0"/>
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0"/>
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="20" Transparent="yes" NoPrefix="yes" Text="!(loc.InstallScopeDlgDescription)"/>
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.InstallScopeDlgTitle)"/>
<Control Id="BothScopes" Type="RadioButtonGroup" X="20" Y="55" Width="330" Height="120" Property="WixAppFolder" Hidden="yes">
<RadioButtonGroup Property="WixAppFolder">
<RadioButton Value="WixPerUserFolder" X="0" Y="0" Width="295" Height="16" Text="!(loc.InstallScopeDlgPerUser)"/>
<RadioButton Value="WixPerMachineFolder" X="0" Y="60" Width="295" Height="16" Text="!(loc.InstallScopeDlgPerMachine)"/>
</RadioButtonGroup>
<Condition Action="show">Privileged AND (!(wix.WixUISupportPerUser) AND !(wix.WixUISupportPerMachine))</Condition>
</Control>
<Control Id="PerUserDescription" Type="Text" X="33" Y="70" Width="300" Height="36" Hidden="yes" NoPrefix="yes" Text="!(loc.InstallScopeDlgPerUserDescription)">
<Condition Action="show">!(wix.WixUISupportPerUser)</Condition>
</Control>
<Control Id="NoPerUserDescription" Type="Text" X="33" Y="70" Width="300" Height="36" Hidden="yes" NoPrefix="yes" Text="!(loc.InstallScopeDlgNoPerUserDescription)">
<Condition Action="show">NOT !(wix.WixUISupportPerUser)</Condition>
</Control>
<Control Id="PerMachineDescription" Type="Text" X="33" Y="131" Width="300" Height="36" Hidden="yes" NoPrefix="yes" Text="!(loc.InstallScopeDlgPerMachineDescription)">
<Condition Action="show">Privileged</Condition>
</Control>
<Control Id="Install" Type="PushButton" ElevationShield="yes" X="212" Y="243" Width="80" Height="17" Default="yes" Text="!(loc.AdvancedWelcomeEulaDlgInstall)" Hidden="yes">
<Condition Action="show">WixAppFolder = "WixPerMachineFolder"</Condition>
<Condition Action="hide">WixAppFolder = "WixPerUserFolder"</Condition>
<!-- F*** WiX - it doesn't work. Installed per-user in any case. -->
<Publish Property="MSIINSTALLPERUSER">1</Publish>
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1</Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
<Publish Event="SpawnDialog" Value="OutOfRbDiskDlg">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)</Publish>
<Publish Event="EndDialog" Value="Return">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
<Publish Event="EnableRollback" Value="False">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
<Publish Event="SpawnDialog" Value="OutOfDiskDlg">(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")</Publish>
</Control>
<Control Id="InstallNoShield" Type="PushButton" ElevationShield="no" X="212" Y="243" Width="80" Height="17" Default="yes" Text="!(loc.AdvancedWelcomeEulaDlgInstall)" Hidden="yes">
<Condition Action="show">WixAppFolder = "WixPerUserFolder"</Condition>
<Condition Action="hide">WixAppFolder = "WixPerMachineFolder"</Condition>
<!--<Publish Property="MSIINSTALLPERUSER" Value="1" Order="0">WixAppFolder = "WixPerUserFolder"</Publish>-->
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1</Publish>
<Publish Event="EndDialog" Value="Return"><![CDATA[OutOfDiskSpace <> 1]]></Publish>
<Publish Event="SpawnDialog" Value="OutOfRbDiskDlg">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)</Publish>
<Publish Event="EndDialog" Value="Return">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
<Publish Event="EnableRollback" Value="False">OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"</Publish>
<Publish Event="SpawnDialog" Value="OutOfDiskDlg">(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")</Publish>
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
</Dialog>
<!--<Publish Dialog="InstallScopeDialog" Control="InstallNoShield" Property="MSIINSTALLPERUSER" Value="1" Order="3">WixAppFolder = "WixPerUserFolder"</Publish>-->
<!--<Publish Dialog="InstallScopeDialog" Control="Install" Property="MSIINSTALLPERUSER" Value="{}" Order="4">WixAppFolder = "WixPerMachineFolder"</Publish>-->
<TextStyle Id="WixUI_Font_Normal" FaceName="!(loc.Advanced_Font_FaceName)" Size="!(loc.Advanced_Font_Normal_Size)"/>
<TextStyle Id="WixUI_Font_Bigger" FaceName="!(loc.Advanced_Font_FaceName)" Size="!(loc.Advanced_Font_Bigger_Size)"/>
<TextStyle Id="WixUI_Font_Title" FaceName="!(loc.Advanced_Font_FaceName)" Size="!(loc.Advanced_Font_Title_Size)" Bold="yes"/>
<TextStyle Id="WixUI_Font_Emphasized" FaceName="!(loc.Advanced_Font_FaceName)" Size="!(loc.Advanced_Font_Emphasized_Size)" Bold="yes"/>
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal"/>
<DialogRef Id="BrowseDlg"/>
<DialogRef Id="DiskCostDlg"/>
<DialogRef Id="ErrorDlg"/>
<DialogRef Id="FatalError"/>
<DialogRef Id="FilesInUse"/>
<DialogRef Id="MsiRMFilesInUse"/>
<DialogRef Id="PrepareDlg"/>
<DialogRef Id="ProgressDlg"/>
<DialogRef Id="ResumeDlg"/>
<DialogRef Id="UserExit"/>
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
<Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" Value="runAfterFinish">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
<!--<Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="1">1</Publish>-->
<!--<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="2"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>-->
<!--<Publish Dialog="InstallScopeDialog" Control="Next" Property="WixAppFolder" Value="WixPerUserFolder" Order="1">!(wix.WixUISupportPerUser) AND NOT Privileged</Publish>-->
<!--<Publish Dialog="InstallScopeDialog" Control="Next" Property="MSIINSTALLPERUSER" Value="1" Order="2">!(wix.WixUISupportPerUser) AND NOT Privileged</Publish>-->
<!--<Publish Dialog="InstallScopeDialog" Control="Next" Property="MSIINSTALLPERUSER" Value="1" Order="3">WixAppFolder = "WixPerUserFolder"</Publish>-->
<!--<Publish Dialog="InstallScopeDialog" Control="Next" Property="MSIINSTALLPERUSER" Value="{}" Order="4">WixAppFolder = "WixPerMachineFolder"</Publish>-->
<!-- do not allow choosing installation dir if per-user -->
<!--<Publish Dialog="InstallScopeDialog" Control="Next" Event="NewDialog" Value="FeaturesDlg" Order="6">WixAppFolder = "WixPerUserFolder"</Publish>-->
<!--<Publish Dialog="InstallScopeDialog" Control="Next" Event="NewDialog" Value="InstallDirDlg" Order="7">WixAppFolder = "WixPerMachineFolder"</Publish>-->
<!--<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="InstallScopeDialog">!(wix.WixUISupportPerUser)</Publish>-->
<!--<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="AdvancedWelcomeEulaDlg">NOT !(wix.WixUISupportPerUser)</Publish>-->
<!--<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>-->
<!--<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>-->
<!--<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>-->
<!--<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="ExitDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>-->
<!--<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>-->
<!--<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>-->
<!--<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>-->
<!--<Publish Dialog="MaintenanceTypeDlg" Control="ChangeButton" Event="NewDialog" Value="FeaturesDlg">1</Publish>-->
<!--<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>-->
<!--<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>-->
<!--<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>-->
<!--<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>-->
<!--<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="3">Installed AND PATCH</Publish>-->
<!--<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>-->
<InstallUISequence>
<Show Dialog="InstallScopeDialog" Sequence="1">NOT Installed</Show>
</InstallUISequence>
</UI>
<Property Id="WIXUI_INSTALLDIR" Value="APPLICATIONFOLDER"/>
<UIRef Id="WixUI_Common"/>
</Fragment>
</Wix>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<!-- https://blogs.msdn.microsoft.com/gremlininthemachine/2006/12/05/msi-wix-and-unicode/ -->
<Product Id="*" Name="${productName}" UpgradeCode="${upgradeCode}" Version="${version}" Language="1033" Codepage="65001" Manufacturer="${manufacturer}">
<Package Compressed="yes" InstallerVersion="500"/>
<Condition Message="Windows 7 and above is required"><![CDATA[Installed OR VersionNT >= 601]]></Condition>
<!--
AllowSameVersionUpgrades:
When set to no (the default), installing a product with the same version and upgrade code (but different product code) is allowed and treated by MSI as two products.
When set to yes, WiX sets the msidbUpgradeAttributesVersionMaxInclusive attribute, which tells MSI to treat a product with the same version as a major upgrade.
So, AllowSameVersionUpgrades="yes" allows to build and test MSI with the same version, and previously installed app will be removed.
-->
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage='A newer version of "[ProductName]" is already installed.'/>
<MediaTemplate CompressionLevel="${compressionLevel}" EmbedCab="yes"/>
<Property Id="ApplicationFolderName" Value="${installationDirectoryWixName}"/>
<Property Id="WixAppFolder" Value="WixPerUserFolder"/>
{{ if (iconPath) { }}
<Icon Id="icon.ico" SourceFile="${iconPath}"/>
<Property Id="ARPPRODUCTICON" Value="icon.ico"/>
{{ } -}}
{{ if (isAssisted || isRunAfterFinish) { }}
<CustomAction Id="runAfterFinish" FileKey="mainExecutable" ExeCommand="" Execute="immediate" Impersonate="yes" Return="asyncNoWait"/>
{{ } -}}
<Property Id="ALLUSERS" Secure="yes" Value="2"/>
{{ if (isPerMachine) { }}
<Property Id="MSIINSTALLPERUSER" Secure="yes"/>
{{ } else { }}
<Property Id="MSIINSTALLPERUSER" Secure="yes" Value="1"/>
{{ } -}}
{{ if (isAssisted) { }}
<!-- Check "Run after finish" checkbox by default -->
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1"/>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Run ${productName}"/>
<UIRef Id="WixUI_Assisted"/>
{{ } else if (isRunAfterFinish) { }}
<!-- https://stackoverflow.com/questions/1871531/launch-after-install-with-no-ui -->
<InstallExecuteSequence>
<Custom Action="runAfterFinish" After="InstallFinalize"/>
</InstallExecuteSequence>
{{ } -}}
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="${programFilesId}">
{{ if (menuCategory) { }}
<Directory Id="COMPANYDIR" Name="${menuCategory}">
{{ } -}}
<Directory Id="APPLICATIONFOLDER" Name="${installationDirectoryWixName}"/>
{{ if (menuCategory) { }}
</Directory>
{{ } -}}
</Directory>
<!-- Desktop link -->
{{ if (isCreateDesktopShortcut) { }}
<Directory Id="DesktopFolder" Name="Desktop"/>
{{ } -}}
<!-- Start menu link -->
{{ if (isCreateStartMenuShortcut) { }}
<Directory Id="ProgramMenuFolder"/>
{{ } }}
</Directory>
<!-- Files -->
<Feature Id="ProductFeature" Absent="disallow">
<ComponentGroupRef Id="ProductComponents"/>
</Feature>
{{-dirs}}
<ComponentGroup Id="ProductComponents" Directory="APPLICATIONFOLDER">
{{-files}}
</ComponentGroup>
</Product>
</Wix>

View File

@ -0,0 +1,142 @@
!include UAC.nsh
!ifndef INSTALL_MODE_PER_ALL_USERS
!include multiUserUi.nsh
!endif
!ifndef BUILD_UNINSTALLER
!ifmacrodef customWelcomePage
!insertmacro customWelcomePage
!endif
!ifmacrodef licensePage
!insertmacro skipPageIfUpdated
!insertmacro licensePage
!endif
!ifndef INSTALL_MODE_PER_ALL_USERS
!insertmacro PAGE_INSTALL_MODE
!endif
!ifdef allowToChangeInstallationDirectory
!include StrContains.nsh
!insertmacro skipPageIfUpdated
!insertmacro MUI_PAGE_DIRECTORY
# pageDirectory leave doesn't work (it seems because $INSTDIR is set after custom leave function)
# so, we use instfiles pre
!define MUI_PAGE_CUSTOMFUNCTION_PRE instFilesPre
# sanitize the MUI_PAGE_DIRECTORY result to make sure it has a application name sub-folder
Function instFilesPre
${If} ${FileExists} "$INSTDIR\*"
${StrContains} $0 "${APP_FILENAME}" $INSTDIR
${If} $0 == ""
StrCpy $INSTDIR "$INSTDIR\${APP_FILENAME}"
${endIf}
${endIf}
FunctionEnd
!endif
# after change installation directory and before install start, you can show custom page here.
!ifmacrodef customPageAfterChangeDir
!insertmacro customPageAfterChangeDir
!endif
!insertmacro MUI_PAGE_INSTFILES
!ifmacrodef customFinishPage
!insertmacro customFinishPage
!else
!ifndef HIDE_RUN_AFTER_FINISH
Function StartApp
${if} ${isUpdated}
StrCpy $1 "--updated"
${else}
StrCpy $1 ""
${endif}
${StdUtils.ExecShellAsUser} $0 "$launchLink" "open" "$1"
FunctionEnd
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION "StartApp"
!endif
!insertmacro MUI_PAGE_FINISH
!endif
!else
!insertmacro MUI_UNPAGE_WELCOME
!ifndef INSTALL_MODE_PER_ALL_USERS
!insertmacro PAGE_INSTALL_MODE
!endif
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
!endif
!macro initMultiUser
!ifdef INSTALL_MODE_PER_ALL_USERS
!insertmacro setInstallModePerAllUsers
!else
${If} ${UAC_IsInnerInstance}
${AndIfNot} ${UAC_IsAdmin}
# special return value for outer instance so it knows we did not have admin rights
SetErrorLevel 0x666666
Quit
${endIf}
!ifndef MULTIUSER_INIT_TEXT_ADMINREQUIRED
!define MULTIUSER_INIT_TEXT_ADMINREQUIRED "$(^Caption) requires administrator privileges."
!endif
!ifndef MULTIUSER_INIT_TEXT_POWERREQUIRED
!define MULTIUSER_INIT_TEXT_POWERREQUIRED "$(^Caption) requires at least Power User privileges."
!endif
!ifndef MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE
!define MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE "Your user account does not have sufficient privileges to install $(^Name) for all users of this computer."
!endif
# checks registry for previous installation path (both for upgrading, reinstall, or uninstall)
StrCpy $hasPerMachineInstallation "0"
StrCpy $hasPerUserInstallation "0"
# set installation mode to setting from a previous installation
ReadRegStr $perMachineInstallationFolder HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation
${if} $perMachineInstallationFolder != ""
StrCpy $hasPerMachineInstallation "1"
${endif}
ReadRegStr $perUserInstallationFolder HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation
${if} $perUserInstallationFolder != ""
StrCpy $hasPerUserInstallation "1"
${endif}
${GetParameters} $R0
${GetOptions} $R0 "/allusers" $R1
${IfNot} ${Errors}
StrCpy $hasPerMachineInstallation "1"
StrCpy $hasPerUserInstallation "0"
${EndIf}
${GetOptions} $R0 "/currentuser" $R1
${IfNot} ${Errors}
StrCpy $hasPerMachineInstallation "0"
StrCpy $hasPerUserInstallation "1"
${EndIf}
${if} $hasPerUserInstallation == "1"
${andif} $hasPerMachineInstallation == "0"
!insertmacro setInstallModePerUser
${elseif} $hasPerUserInstallation == "0"
${andif} $hasPerMachineInstallation == "1"
!insertmacro setInstallModePerAllUsers
${else}
# if there is no installation, or there is both per-user and per-machine
!ifdef INSTALL_MODE_PER_ALL_USERS
!insertmacro setInstallModePerAllUsers
!else
!insertmacro setInstallModePerUser
!endif
${endif}
!endif
!macroend

View File

@ -0,0 +1,351 @@
# assisted installer messages, see messages.yml for one-click installer messages
chooseInstallationOptions:
en: Choose Installation Options
de: Installationsoption wählen
ru: Выберите опции установки
sk: Vyberte možnosti inštalácie
cs: Vyberte možnosti instalace
fr: Choisis les options d'installation
hu_HU: Telepítési opciók kiválasztása
pt_BR: Escolha uma opção de instalação
zh_CN: 安装选项
zh_TW: 安裝選項
tr_TR: Yükleme Ayarlarını Seçin
sv_SE: Välj alternativ för installation
pl_PL: Wybierz opcje instalacji
no: Velg alternativer for installering
nl_NL: Kies installatie-opties
it_IT: Scegli opzioni di installazione
fi: Valitse asennusvaihtoehdot
es: Elegir opciones de instalación
da: Vælg Installeringsmuligheder
ja: インストールオプションの選択
chooseUninstallationOptions:
en: Choose Uninstallation Options
de: Deinstallationsoption wählen
ru: Выберите опции удаления
sk: Vyberte možnosti odinštalovania
cs: Vyberte možnosti odinstalace
fr: Choisis les options de désinstallation
hu_HU: Eltávolítási opciók kiválasztása
pt_BR: Escolha uma opção de desinstalação
zh_CN: 卸载选项
zh_TW: 卸載選項
tr_TR: Kaldırma Ayarlarını Seçin
sv_SE: Välj alternativ för avinstallation
pl_PL: Wybierz opcje dezinstalacji
no: Velg alternativer for avinstallering
nl_NL: Kies verwijderings-opties
it_IT: Scegli opzioni di disinstallazione
fi: Valitse asennuksen poistovaihtoehdot
es: Elegir opciones de desinstalación
da: Vælg Afinstalleringsmuligheder
ja: アンインストールオプションの選択
whichInstallationShouldBeRemoved:
en: Which installation should be removed?
de: Welche Installation soll entfernt werden?
ru: Какую из установленных программ следует удалить?
sk: Ktorá inštalácia by mala byt odstránená?
cs: Která instalace by měla má být odstraněná?
fr: Quelle installation doit être supprimée ?
hu_HU: Melyik telepítést távolítsuk el?
pt_BR: Qual instalação deve ser removida?
zh_CN: 需要移除哪个安装?
zh_TW: 需要移除哪個安裝?
tr_TR: Hangi Yükleme Kaldırılsın?
sv_SE: Vilken installation ska tas bort?
pl_PL: Którą instalację chcesz usunąć?
no: Hvilken installasjon skal fjernes?
nl_NL: Welke installatie moet worden verwijderd?
it_IT: Quale installazione intendi rimuovere?
fi: Mikä asennus pitäisi poistaa?
es: ¿Qué tipo de instalación debe eliminarse?
da: Hvilken installering skal fjernes?
ja: どれをアンインストールしますか?
whoShouldThisApplicationBeInstalledFor:
en: Who should this application be installed for?
de: Für wen soll diese Anwendung installiert werden?
ru: Для кого следует установить это приложение?
sk: Pre koho sa ma táto aplikacia inštalovať?
cs: Pro koho se má tato aplikace instalovat?
fr: Pour qui cette application doit-elle être installée ?
hu_HU: Kinek legyen ez az alkalmazás telepítve?
pt_BR: Para quem esta aplicação deve ser instalada?
zh_CN: 为哪位用户安装该应用?
zh_TW: 為哪位用戶安裝該應用?
tr_TR: Bu Uygulama Kimler için Kurulsun?
sv_SE: Vem ska den här applikationen installeras för?
pl_PL: Dla kogo zainstalować tę aplikację?
no: Hvem skal dette programmet installeres for?
nl_NL: Voor wie moet deze applicatie worden geïnstalleerd?
it_IT: Per chi dovrebbe essere installata questa applicazione?
fi: Kenen käyttöön tämä sovellus pitäisi asentaa?
es: ¿Para quién se instalará esta aplicación?
da: Hvem skal denne applikation installeres til?
ja: どのユーザーにインストールしますか?
selectUserMode:
en: Please select whether you wish to make this software available to all users or just yourself
de: Bitte wählen Sie, ob Sie die Anwendung nur für sich oder für alle Benutzer installieren möchten.
ru: Выбери, хочешь ли ты сделать эту программу доступной для всех пользователей или только для себя
sk: Prosím vyberte či sa ma tento softvér inštalovať len pre Vás alebo pre všetkých uživateľov
cs: Prosím vyberte, zda se má tento software instalovat jen proVás nebo pro všechny uživatele
fr: "Choisis pour qui ce logiciel doit être accessible : pour tous les utilisateurs ou juste pour toi ?"
hu_HU: Válaszd ki, hogy a szoftver elérhető legyen-e minden felhasználó számára, vagy csak neked
pt_BR: Por favor, selecione se este software deve estar disponível apenas para você ou para todos usuários
zh_CN: 请选择为当前用户还是所有用户安装该软件
zh_TW: 請選擇為當前用戶還是所有用戶安裝該軟件
tr_TR: Lütfen bu yazılımı tüm kullanıcılar için mi yoksa sadece kendiniz mi kullanmak istediğinizi seçin
sv_SE: Välj om du vill göra den här mjukvaran tillgänglig för alla användare eller bara för dig
pl_PL: Wybierz, czy to oprogramowanie ma być dostępne dla wszystkich użytkowników, czy tylko dla Ciebie
no: Velg om du vil gjøre denne programvaren tilgjengelig for alle brukerne eller bare deg selv
nl_NL: Selecteer of je deze software beschikbaar wilt maken voor alle gebruikers of alleen voor jezelf.
it_IT: Seleziona se desideri rendere questo software accessibile a tutti gli utenti o solo a te
fi: Valitse, haluatko tämän ohjelmiston kaikkien käyttäjien vai pelkästään itsesi käyttöön
es: Elige si deseas que este software esté disponible para todos los usuarios o solo para ti.
da: Vælg, om du vil gøre denne software tilgængelig for andre brugere, eller kun for dig selv
ja: このソフトウェアをすべてのユーザーが使用できるようにするか、現在のユーザーのみ使用するかを選択してください
whichInstallationRemove:
en: This software is installed both per-machine (all users) and per-user.\nWhich installation you wish to remove?
de: Die Anwendung wurde für alle Benutzer und pro Benutzer installiert.\nWelche Installation möchten Sie entfernen?
ru: Эта программа установлена для всего компьютера (для всех пользователей) и для отдельного пользователя.\nКакую из установленных программ ты хочешь удалить?
sk: Tento softvér je nainštalovaný pre Vás a súčasne pre všetkých uživateľov.\nKtorú inštaláciu si želáte odstraniť?
cs: Tento software je nainstalovaný pro Vás a současně pro všechny uživatele.\nKterou instalace si přejete odstranit?
fr: Ce logiciel est installé à la fois par machine (tous les utilisateurs) et par utilisateur.\nQuelle installation veux-tu supprimer ?
hu_HU: Ez a szoftver számítógépenként (minden felhasználó) és felhasználónként is telepítve van.\nMelyik telepítést szeretnéd eltávolítani?
pt_BR: Este software é instalado por máquina (todos os usuários) e por usuário. Qual instalação você deseja remover?
zh_CN: 该软件已为所有用户和当前用户安装.\n您希望移除哪个安装?
zh_TW: 該軟件已為所有用戶和當前用戶安裝.\n您希望移除哪個安裝?
tr_TR: Bu yazılım hem makine başına (tüm kullanıcılar) hem de kullanıcı başına yüklenir.\nKaldırmak istediğiniz kurulum?
sv_SE: Den här mjukvaran är installerad både ”per dator” (alla användare) och ”per användare”.\nVilken installation vill du ta bort?
pl_PL: To oprogramowanie zostało zainstalowane zarówno dla urządzenia (wszyscy użytkownicy), jak i dla użytkownika.\nKtórą instalację chcesz usunąć?
no: Denne programvaren er installert både per-maskin (alle brukere) og per-bruker. Hvilken installasjon vil du fjerne?
nl_NL: Deze software is zowel per apparaat (alle gebruikers) als per gebruiker geïnstalleerd. Welke installatie wil je verwijderen?
it_IT: Questo software è stato installato sia per computer (tutti gli utenti) sia per utente.\nQuale installazione desideri rimuovere?
fi: Tämä ohjelmisto on asennettu sekä konekohtaisesti (kaikki käyttäjät) että käyttäjäkohtaisesti.\nMinkä asennuksen haluat poistaa?
es: Este software se ha instalado para la máquina (todos los usuarios) y para el usuario.\n¿Qué instalación quieres eliminar?
da: Denne software er installeret både pr. maskine (alle brugere) og pr. bruger./nHvilken installering ønsker du at fjerne?
ja: このソフトウェアは、マシンごと(すべてのユーザー)とユーザーごとにインストールされています。\ nどちらを削除しますか
freshInstallForAll:
en: Fresh install for all users. (will prompt for admin credentials)
de: Neuinstallation für alle Benutzer durchführen. (Administratorrechte benötigt)
ru: Новая установка для всех пользователей. (потребуются права администратора)
sk: Nová inštalácia pre všetkých uživateľov. (will prompt for admin credentials)
cs: Nová instalace pro všechny uživatele. (bude vyžadovat přihlášení administrátora)
fr: Nouvelle installation pour tous les utilisateurs. (demandera les identifiants administrateur)
hu_HU: Új telepítés minden felhasználó számára. (Az adminisztrátor hitelesítő adataira lesz szükség.)
pt_BR: Instalação limpa para todos os usuários. (irá solicitar credenciais de administrador)
zh_CN: 为所有用户进行全新安装. (需要管理员资格)
zh_TW: 為所有用戶進行全新安裝. (需要管理員資格)
tr_TR: Tüm kullanıcılar için yeni yükleme. (yönetici kimlik bilgilerini soracaktır)
sv_SE: Ny installation för alla användare. (kommer att begära adminbehörighet)
pl_PL: Nowa instalacja dla wszystkich użytkowników (potrzebne będą dane administratora).
no: Ny installasjon for alle brukere. (vil be om administratorlegitimasjon)
nl_NL: Nieuwe installatie voor alle gebruikers. (zal om beheerder-gegevens vragen)
it_IT: Re-installa per tutti gli utenti. (Richiede le credenziali di amministratore)
fi: Uusi asennus kaikille käyttäjille (pyytää ylläpitäjän käyttäjätunnuksia)
es: Instalación nueva para todos los usuarios (se pedirán los credenciales del administrador)
da: Ny installering til alle brugere. (Vil medføre administrations-legitimationsoplysninger)
ja: すべてのユーザーに新規インストール(管理者権限が必要)
freshInstallForCurrent:
en: Fresh install for current user only.
de: Neuinstallation nur für den aktuellen Benutzer durchführen.
ru: Новая установка только для текущего пользователя.
cs: Nová instalace pro aktuálního uživatele.
fr: Nouvelle installation uniquement pour l'utilisateur actuel.
hu_HU: Új telepítés csak a jelenlegi felhasználó számára.
pt_BR: Instalação limpa somente para o usuário atual.
zh_CN: 仅为当前用户进行全新安装.
zh_TW: 僅為當前用戶進行全新安裝.
tr_TR: Sadece mevcut kullanıcı için yeni yükleme.
sv_SE: Ny installation endast för den aktuella användaren.
pl_PL: Nowa instalacja wyłącznie dla obecnego użytkownika.
no: Ny installasjon kun for nåværende bruker.
nl_NL: Nieuwe installatie alleen voor huidige gebruiker.
it_IT: Re-installa solo per l'utente attuale.
fi: Uusi asennus vain nykyiselle käyttäjälle.
es: Instalación nueva solo para el usuario actual.
da: Ny installering kun til nuværende bruger.
ja: 現在のユーザーのみ新規インストール
onlyForMe:
en: Only for &me
de: Nur für &mich
ru: Только для &меня
sk: Iba pre mňa
cs: Pouze pro &mě
fr: Juste pour moi
hu_HU: Csak az én számomra
pt_BR: Apenas para &mim
zh_CN: 仅为我安装
zh_TW: 僅為我安裝
tr_TR: Sadece benim için
sv_SE: Endast för &mig
pl_PL: Tylko dla &mnie
no: Kun for &meg
nl_NL: Alleen voor &mij
it_IT: Solo per &me
fi: Vain minulle
es: Solo para mí.
da: Kun til mig
ja: 現在のユーザーのみにインストールする
forAll:
en: Anyone who uses this computer (&all users)
de: Für alle Benutzer dieses Computers (&alle Benutzer)
ru: Для &всех пользователей данного компьютера
sk: Pre každého kto použiva tento počitač (všetci uživatelia)
cs: Pro každého, kdo používá tento počítač (všichni uživatelé)
fr: Pour tous ceux qui utilisent cet ordinateur (tous les utilisateurs)
hu_HU: Bárki számára, aki ezt a számítógépet használja (minden felhasználó)
pt_BR: Para todos que usam esta máquina (&todos os usuários)
zh_CN: 为使用这台电脑的任何人安装 (所有用户)
zh_TW: 為使用這台電腦的任何人安裝 (所有用戶)
tr_TR: Bu bilgisayarı kullanan herkes (ve tüm kullanıcılar)
sv_SE: Alla som använder den här datorn (alla användare)
pl_PL: Każdy korzystający z tego komputera (wszyscy użytkownicy)
no: Alle som bruker denne datamaskinen (alle brukere)
nl_NL: Iedereen die deze computer gebruikt (alle gebruikers)
it_IT: Per chiunque usi questo computer (tutti gli utenti)
fi: Kaikille, jotka käyttävät tätä tietokonetta (kaikki käyttäjät)
es: Cualquiera que utilice este ordenador (todos los usuarios)
da: Enhver, der bruger denne computer (alle brugere)
ja: このコンピューターを使用しているすべてのユーザー用にインストールする
loginWithAdminAccount:
en: You need to login with an account that is a member of the admin group to continue...
de: Um die Installation fortzusetzen müssen Sie sich mit einem Administrator-Account anmelden...
ru: Чтобы продолжить, тебе нужно войти в учетную запись, которая входит в группу администраторов...
sk: Pre pokračovanie sa musíte zalogovať s účtom ktorý patrí do skupiny adminstrátorov...
cs: Pro pokračování se musíte přihlásit s účtem, který patří do skupiny administrátorů...
fr: Tu dois te connecter avec un compte ayant des droits d'administrateur pour continuer...
hu_HU: A folytatáshoz adminisztrátori jogokkal rendelkező fiókkal kell bejelentkezned...
pt_BR: Você precisa realizar o login com uma conta que é membro do grupo de administração para continuar...
zh_CN: 您需要用属于管理员群组的用户账户登录来继续...
zh_TW: 您需要用屬於管理員群組的用戶賬戶登錄來繼續...
tr_TR: Devam etmek için yönetici grubunun üyesi olan bir hesapla giriş yapmanız gerekiyor..
sv_SE: Du måste logga in med ett konto som är medlem i admingruppen för att fortsätta...
pl_PL: Musisz się zalogować za pomocą konta będącego członkiem grupy administratora, by kontynuować...
no: Du må logge inn med en konto som er medlem av administrasjonsgruppen for å fortsette...
nl_NL: Je dient in te loggen met een account dat lid is van de beheerdersgroep om verder te gaan...
it_IT: Devi accedere con un account incluso nel gruppo amministratore per continuare...
fi: Jatkaaksesi sinun on kirjauduttava käyttäjätilillä, joka on ylläpitäjäryhmän jäsen...
es: Para continuar, tienes que iniciar sesión con una cuenta que pertenezca al grupo de administradores...
da: Du skal logge ind med en konto, der er medlem af administrationsgruppen for at kunne fortsætte...
ja: 続行するには、管理者権限アカウントでログインする必要があります...
perUserInstallExists:
en: There is already a per-user installation.
de: Es existiert bereits eine Installtion für den ausgewählten Benutzer.
ru: Уже есть установленная программа для отдельного пользователя.
cs: Již existuje instalace pro uživatele.
fr: Il y a déjà une installation par utilisateur.
hu_HU: Már van egy felhasználónkénti telepítés.
pt_BR: Já existe uma instalação por usuário.
zh_CN: 已经存在一个安装到当前用户的安装.
zh_TW: 已經存在一個安裝到當前用戶的安裝.
tr_TR: Her kullanıcı için zaten bir kurulum var.
sv_SE: Det finns redan en ”per användare”-installation.
pl_PL: Instalacja dla użytkownika już istnieje.
no: Det er allerede en per-bruker-installasjon.
nl_NL: Er is al een installatie 'per gebruiker'.
it_IT: È già presente un'installazione per utente.
fi: Tämä on jo käyttäjäkohtainen asennus.
es: Ya hay una instalación por usuario.
da: Der er allerede en pr. bruger installation.
ja: すでに現在のユーザーにインストールされています。
perUserInstall:
en: There is a per-user installation.
de: Benutzerinstallation bereits vorhanden.
ru: Есть установленная программа для отдельного пользователя.
cs: Instalace pro uživatele.
fr: Il y a une installation par utilisateur.
hu_HU: Van felhasználónkénti telepítés.
pt_BR: Existe uma instalação por usuário.
zh_CN: 存在一个安装到当前用户的安装.
zh_TW: 存在一個安裝到當前用戶的安裝.
tr_TR: Kullanıcı başına bir kurulum var.
sv_SE: Det finns en ”per användare”-installation.
pl_PL: Instalacja dla użytkownika istnieje.
no: Det er en per-bruker-installasjon.
nl_NL: Er is een installatie 'per gebruiker'.
it_IT: È presente un'installazione per utente.
fi: Käyttäjäkohtainen asennus on olemassa.
es: Hay una instalación por usuario.
da: Der er en pr. bruger installation.
ja: ユーザーごとのインストールがあります。
perMachineInstallExists:
en: There is already a per-machine installation.
de: Es existiert bereits eine Installation für diesen Computer.
ru: Уже есть установленная программа для всего компьютера.
cs: Již existuje instalace pro tento počítač.
fr: Il y a déjà une installation par machine.
hu_HU: Már van egy számítógépenkénti telepítés.
pt_BR: Já existe uma instalação por máquina.
zh_CN: 已经存在一个安装到所有用户的安装.
zh_TW: 已經存在一個安裝到所有用戶的安裝.
tr_TR: Zaten makine başına bir kurulum var.
sv_SE: Det finns redan en ”per dator”-installation.
pl_PL: Instalacja dla urządzenia już istnieje.
no: Det er allerede en per-maskin-installasjon.
nl_NL: Er is al een installatie 'per apparaat'.
it_IT: È già presente un'installazione per computer.
fi: Tämä on jo tietokonekohtainen asennus.
es: Ya hay una instalación por máquina.
da: Der er allerede en pr. maskine installation.
ja: 既にすべてのユーザー用にインストールされています。
perMachineInstall:
en: There is a per-machine installation.
de: Es existiert eine Installation für diesen Computer.
ru: Есть установленная программа для всего компьютера.
cs: Instalace pro tento počítač.
fr: Il y a une installation par machine.
hu_HU: Van számítógépenkénti telepítés.
pt_BR: Existe uma instalação por máquina.
zh_CN: 存在一个安装到所有用户的安装.
zh_TW: 存在一個安裝到所有用戶的安裝.
tr_TR: Makine başına bir yükleme var.
sv_SE: Det finns en ”per dator”-installation.
pl_PL: Instalacja dla urządzenia istnieje.
no: Det er en per-maskin-installasjon.
nl_NL: Er is een installatie 'per apparaat'.
it_IT: È presente un'installazione per computer.
fi: Tietokonekohtainen asennus on olemassa.
es: Hay una instalación por máquina.
da: Der er en pr. maskine installation.
ja: すべてのユーザー用のインストールがあります。
reinstallUpgrade:
en: Will reinstall/upgrade.
de: Die Anwendung wird aktualisiert.
ru: Приложение будет переустановлено/обновлено.
cs: Bude přeinstalováno/aktualizováno.
fr: Va réinstaller/mettre à jour.
hu_HU: Újratelepít/frissít.
pt_BR: Irá reinstalar/atualizar.
zh_CN: 即将重新安装/升级.
zh_TW: 即將重新安裝/升級.
tr_TR: Yeniden yükleme/yükseltme
sv_SE: Kommer att ominstallera/uppgradera.
pl_PL: Nastąpi ponowna instalacja/aktualizacja.
no: Vil installere på nytt / oppgradere.
nl_NL: Zal opnieuw installeren/upgraden.
it_IT: Re-installa/aggiorna il programma.
fi: Asennetaan uudelleen/päivitetään.
es: Se reinstalará/actualizará.
da: Reinstallerer/opgraderer.
ja: 再インストール/アップグレードします。
uninstall:
en: Will uninstall.
de: Die Anwendung wird deinstalliert.
ru: Приложение будет удалено.
cs: Odinstaluje se.
fr: Va désinstaller.
hu_HU: Eltávolít.
pt_BR: Irá desinstalar.
zh_CN: 即将卸载.
zh_TW: 即將卸載.
tr_TR: Kaldıralacak.
sv_SE: Kommer att avinstallera.
pl_PL: Nastąpi dezinstalacja.
no: Vil avinstallere.
nl_NL: Zal installatie verwijderen.
it_IT: Disinstalla il programma.
fi: Poistetaan asennus.
es: Se desinstalará.
da: Afinstallerer.
ja: アンインストールします。

View File

@ -0,0 +1,101 @@
!include x64.nsh
!include WinVer.nsh
BrandingText "${PRODUCT_NAME} ${VERSION}"
ShowInstDetails nevershow
SpaceTexts none
!ifdef BUILD_UNINSTALLER
ShowUninstDetails nevershow
!endif
FileBufSize 64
Name "${PRODUCT_NAME}"
!define APP_EXECUTABLE_FILENAME "${PRODUCT_FILENAME}.exe"
!define UNINSTALL_FILENAME "Uninstall ${PRODUCT_FILENAME}.exe"
!macro check64BitAndSetRegView
# https://github.com/electron-userland/electron-builder/issues/2420
${If} ${IsWin2000}
${OrIf} ${IsWinME}
${OrIf} ${IsWinXP}
${OrIf} ${IsWinVista}
MessageBox MB_OK "$(win7Required)"
Quit
${EndIf}
!ifdef APP_ARM64
${If} ${RunningX64}
SetRegView 64
${EndIf}
${If} ${IsNativeARM64}
SetRegView 64
${EndIf}
!else
!ifdef APP_64
${If} ${RunningX64}
SetRegView 64
${Else}
!ifndef APP_32
MessageBox MB_OK|MB_ICONEXCLAMATION "$(x64WinRequired)"
Quit
!endif
${EndIf}
!endif
!endif
!macroend
# avoid exit code 2
!macro quitSuccess
SetErrorLevel 0
Quit
!macroend
!macro setLinkVars
# old desktop shortcut (could exist or not since the user might has selected to delete it)
ReadRegStr $oldShortcutName SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" ShortcutName
${if} $oldShortcutName == ""
StrCpy $oldShortcutName "${PRODUCT_FILENAME}"
${endIf}
StrCpy $oldDesktopLink "$DESKTOP\$oldShortcutName.lnk"
# new desktop shortcut (will be created/renamed in case of a fresh installation or if the user haven't deleted the initial one)
StrCpy $newDesktopLink "$DESKTOP\${SHORTCUT_NAME}.lnk"
ReadRegStr $oldMenuDirectory SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" MenuDirectory
${if} $oldMenuDirectory == ""
StrCpy $oldStartMenuLink "$SMPROGRAMS\$oldShortcutName.lnk"
${else}
StrCpy $oldStartMenuLink "$SMPROGRAMS\$oldMenuDirectory\$oldShortcutName.lnk"
${endIf}
# new menu shortcut (will be created/renamed in case of a fresh installation or if the user haven't deleted the initial one)
!ifdef MENU_FILENAME
StrCpy $newStartMenuLink "$SMPROGRAMS\${MENU_FILENAME}\${SHORTCUT_NAME}.lnk"
!else
StrCpy $newStartMenuLink "$SMPROGRAMS\${SHORTCUT_NAME}.lnk"
!endif
!macroend
!macro skipPageIfUpdated
!define UniqueID ${__LINE__}
Function skipPageIfUpdated_${UniqueID}
${if} ${isUpdated}
Abort
${endif}
FunctionEnd
!define MUI_PAGE_CUSTOMFUNCTION_PRE skipPageIfUpdated_${UniqueID}
!undef UniqueID
!macroend
!macro StartApp
Var /GLOBAL startAppArgs
${if} ${isUpdated}
StrCpy $startAppArgs "--updated"
${else}
StrCpy $startAppArgs ""
${endif}
${StdUtils.ExecShellAsUser} $0 "$launchLink" "open" "$startAppArgs"
!macroend

View File

@ -0,0 +1 @@
Loading...

View File

@ -0,0 +1,132 @@
; fileassoc.nsh
; File association helper macros
; Written by Saivert
;
; Features automatic backup system and UPDATEFILEASSOC macro for
; shell change notification.
;
; |> How to use <|
; To associate a file with an application so you can double-click it in explorer, use
; the APP_ASSOCIATE macro like this:
;
; Example:
; !insertmacro APP_ASSOCIATE "txt" "myapp.textfile" "Description of txt files" \
; "$INSTDIR\myapp.exe,0" "Open with myapp" "$INSTDIR\myapp.exe $\"%1$\""
;
; Never insert the APP_ASSOCIATE macro multiple times, it is only ment
; to associate an application with a single file and using the
; the "open" verb as default. To add more verbs (actions) to a file
; use the APP_ASSOCIATE_ADDVERB macro.
;
; Example:
; !insertmacro APP_ASSOCIATE_ADDVERB "myapp.textfile" "edit" "Edit with myapp" \
; "$INSTDIR\myapp.exe /edit $\"%1$\""
;
; To have access to more options when registering the file association use the
; APP_ASSOCIATE_EX macro. Here you can specify the verb and what verb is to be the
; standard action (default verb).
;
; Note, that this script takes into account user versus global installs.
; To properly work you must initialize the SHELL_CONTEXT variable via SetShellVarContext.
;
; And finally: To remove the association from the registry use the APP_UNASSOCIATE
; macro. Here is another example just to wrap it up:
; !insertmacro APP_UNASSOCIATE "txt" "myapp.textfile"
;
; |> Note <|
; When defining your file class string always use the short form of your application title
; then a period (dot) and the type of file. This keeps the file class sort of unique.
; Examples:
; Winamp.Playlist
; NSIS.Script
; Photoshop.JPEGFile
;
; |> Tech info <|
; The registry key layout for a global file association is:
;
; HKEY_LOCAL_MACHINE\Software\Classes
; <".ext"> = <applicationID>
; <applicationID> = <"description">
; shell
; <verb> = <"menu-item text">
; command = <"command string">
;
;
; The registry key layout for a per-user file association is:
;
; HKEY_CURRENT_USER\Software\Classes
; <".ext"> = <applicationID>
; <applicationID> = <"description">
; shell
; <verb> = <"menu-item text">
; command = <"command string">
;
!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND
; Backup the previously associated file class
ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" ""
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0"
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}"
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" "open"
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}`
!macroend
!macro APP_ASSOCIATE_EX EXT FILECLASS DESCRIPTION ICON VERB DEFAULTVERB SHELLNEW COMMANDTEXT COMMAND
; Backup the previously associated file class
ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" ""
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0"
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}"
StrCmp "${SHELLNEW}" "0" +2
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}\ShellNew" "NullFile" ""
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" `${DEFAULTVERB}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
!macroend
!macro APP_ASSOCIATE_ADDVERB FILECLASS VERB COMMANDTEXT COMMAND
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
!macroend
!macro APP_ASSOCIATE_REMOVEVERB FILECLASS VERB
DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}\shell\${VERB}`
!macroend
!macro APP_UNASSOCIATE EXT FILECLASS
; Backup the previously associated file class
ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" `${FILECLASS}_backup`
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "$R0"
DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}`
!macroend
!macro APP_ASSOCIATE_GETFILECLASS OUTPUT EXT
ReadRegStr ${OUTPUT} SHELL_CONTEXT "Software\Classes\.${EXT}" ""
!macroend
; !defines for use with SHChangeNotify
!ifdef SHCNE_ASSOCCHANGED
!undef SHCNE_ASSOCCHANGED
!endif
!define SHCNE_ASSOCCHANGED 0x08000000
!ifdef SHCNF_FLUSH
!undef SHCNF_FLUSH
!endif
!define SHCNF_FLUSH 0x1000
!macro UPDATEFILEASSOC
; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we
; can update the shell.
System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
!macroend

View File

@ -0,0 +1,496 @@
#################################################################################
# StdUtils plug-in for NSIS
# Copyright (C) 2004-2018 LoRd_MuldeR <MuldeR2@GMX.de>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# http://www.gnu.org/licenses/lgpl-2.1.txt
#################################################################################
# DEVELOPER NOTES:
# - Please see "https://github.com/lordmulder/stdutils/" for news and updates!
# - Please see "Docs\StdUtils\StdUtils.html" for detailed function descriptions!
# - Please see "Examples\StdUtils\StdUtilsTest.nsi" for usage examples!
#################################################################################
# FUNCTION DECLARTIONS
#################################################################################
!ifndef ___STDUTILS__NSH___
!define ___STDUTILS__NSH___
!define StdUtils.Time '!insertmacro _StdU_Time' #time(), as in C standard library
!define StdUtils.GetMinutes '!insertmacro _StdU_GetMinutes' #GetSystemTimeAsFileTime(), returns the number of minutes
!define StdUtils.GetHours '!insertmacro _StdU_GetHours' #GetSystemTimeAsFileTime(), returns the number of hours
!define StdUtils.GetDays '!insertmacro _StdU_GetDays' #GetSystemTimeAsFileTime(), returns the number of days
!define StdUtils.Rand '!insertmacro _StdU_Rand' #rand(), as in C standard library
!define StdUtils.RandMax '!insertmacro _StdU_RandMax' #rand(), as in C standard library, with maximum value
!define StdUtils.RandMinMax '!insertmacro _StdU_RandMinMax' #rand(), as in C standard library, with minimum/maximum value
!define StdUtils.RandList '!insertmacro _StdU_RandList' #rand(), as in C standard library, with list support
!define StdUtils.RandBytes '!insertmacro _StdU_RandBytes' #Generates random bytes, returned as Base64-encoded string
!define StdUtils.FormatStr '!insertmacro _StdU_FormatStr' #sprintf(), as in C standard library, one '%d' placeholder
!define StdUtils.FormatStr2 '!insertmacro _StdU_FormatStr2' #sprintf(), as in C standard library, two '%d' placeholders
!define StdUtils.FormatStr3 '!insertmacro _StdU_FormatStr3' #sprintf(), as in C standard library, three '%d' placeholders
!define StdUtils.ScanStr '!insertmacro _StdU_ScanStr' #sscanf(), as in C standard library, one '%d' placeholder
!define StdUtils.ScanStr2 '!insertmacro _StdU_ScanStr2' #sscanf(), as in C standard library, two '%d' placeholders
!define StdUtils.ScanStr3 '!insertmacro _StdU_ScanStr3' #sscanf(), as in C standard library, three '%d' placeholders
!define StdUtils.TrimStr '!insertmacro _StdU_TrimStr' #Remove whitspaces from string, left and right
!define StdUtils.TrimStrLeft '!insertmacro _StdU_TrimStrLeft' #Remove whitspaces from string, left side only
!define StdUtils.TrimStrRight '!insertmacro _StdU_TrimStrRight' #Remove whitspaces from string, right side only
!define StdUtils.RevStr '!insertmacro _StdU_RevStr' #Reverse a string, e.g. "reverse me" <-> "em esrever"
!define StdUtils.ValidFileName '!insertmacro _StdU_ValidFileName' #Test whether string is a valid file name - no paths allowed
!define StdUtils.ValidPathSpec '!insertmacro _StdU_ValidPathSpec' #Test whether string is a valid full(!) path specification
!define StdUtils.ValidDomainName '!insertmacro _StdU_ValidDomain' #Test whether string is a valid host name or domain name
!define StdUtils.StrToUtf8 '!insertmacro _StdU_StrToUtf8' #Convert string from Unicode (UTF-16) or ANSI to UTF-8 bytes
!define StdUtils.StrFromUtf8 '!insertmacro _StdU_StrFromUtf8' #Convert string from UTF-8 bytes to Unicode (UTF-16) or ANSI
!define StdUtils.SHFileMove '!insertmacro _StdU_SHFileMove' #SHFileOperation(), using the FO_MOVE operation
!define StdUtils.SHFileCopy '!insertmacro _StdU_SHFileCopy' #SHFileOperation(), using the FO_COPY operation
!define StdUtils.AppendToFile '!insertmacro _StdU_AppendToFile' #Append contents of an existing file to another file
!define StdUtils.ExecShellAsUser '!insertmacro _StdU_ExecShlUser' #ShellExecute() as NON-elevated user from elevated installer
!define StdUtils.InvokeShellVerb '!insertmacro _StdU_InvkeShlVrb' #Invokes a "shell verb", e.g. for pinning items to the taskbar
!define StdUtils.ExecShellWaitEx '!insertmacro _StdU_ExecShlWaitEx' #ShellExecuteEx(), returns the handle of the new process
!define StdUtils.WaitForProcEx '!insertmacro _StdU_WaitForProcEx' #WaitForSingleObject(), e.g. to wait for a running process
!define StdUtils.GetParameter '!insertmacro _StdU_GetParameter' #Get the value of a specific command-line option
!define StdUtils.TestParameter '!insertmacro _StdU_TestParameter' #Test whether a specific command-line option has been set
!define StdUtils.ParameterCnt '!insertmacro _StdU_ParameterCnt' #Get number of command-line tokens, similar to argc in main()
!define StdUtils.ParameterStr '!insertmacro _StdU_ParameterStr' #Get the n-th command-line token, similar to argv[i] in main()
!define StdUtils.GetAllParameters '!insertmacro _StdU_GetAllParams' #Get complete command-line, but without executable name
!define StdUtils.GetRealOSVersion '!insertmacro _StdU_GetRealOSVer' #Get the *real* Windows version number, even on Windows 8.1+
!define StdUtils.GetRealOSBuildNo '!insertmacro _StdU_GetRealOSBld' #Get the *real* Windows build number, even on Windows 8.1+
!define StdUtils.GetRealOSName '!insertmacro _StdU_GetRealOSStr' #Get the *real* Windows version, as a "friendly" name
!define StdUtils.GetOSEdition '!insertmacro _StdU_GetOSEdition' #Get the Windows edition, i.e. "workstation" or "server"
!define StdUtils.GetOSReleaseId '!insertmacro _StdU_GetOSRelIdNo' #Get the Windows release identifier (on Windows 10)
!define StdUtils.VerifyOSVersion '!insertmacro _StdU_VrfyRealOSVer' #Compare *real* operating system to an expected version number
!define StdUtils.VerifyOSBuildNo '!insertmacro _StdU_VrfyRealOSBld' #Compare *real* operating system to an expected build number
!define StdUtils.HashText '!insertmacro _StdU_HashText' #Compute hash from text string (CRC32, MD5, SHA1/2/3, BLAKE2)
!define StdUtils.HashFile '!insertmacro _StdU_HashFile' #Compute hash from file (CRC32, MD5, SHA1/2/3, BLAKE2)
!define StdUtils.NormalizePath '!insertmacro _StdU_NormalizePath' #Simplifies the path to produce a direct, well-formed path
!define StdUtils.GetParentPath '!insertmacro _StdU_GetParentPath' #Get parent path by removing the last component from the path
!define StdUtils.SplitPath '!insertmacro _StdU_SplitPath' #Split the components of the given path
!define StdUtils.GetDrivePart '!insertmacro _StdU_GetDrivePart' #Get drive component of path
!define StdUtils.GetDirectoryPart '!insertmacro _StdU_GetDirPart' #Get directory component of path
!define StdUtils.GetFileNamePart '!insertmacro _StdU_GetFNamePart' #Get file name component of path
!define StdUtils.GetExtensionPart '!insertmacro _StdU_GetExtnPart' #Get file extension component of path
!define StdUtils.TimerCreate '!insertmacro _StdU_TimerCreate' #Create a new event-timer that will be triggered periodically
!define StdUtils.TimerDestroy '!insertmacro _StdU_TimerDestroy' #Destroy a running timer created with TimerCreate()
!define StdUtils.ProtectStr '!insertmacro _StdU_PrtctStr' #Protect a given String using Windows' DPAPI
!define StdUtils.UnprotectStr '!insertmacro _StdU_UnprtctStr' #Unprotect a string that was protected via ProtectStr()
!define StdUtils.GetLibVersion '!insertmacro _StdU_GetLibVersion' #Get the current StdUtils library version (for debugging)
!define StdUtils.SetVerbose '!insertmacro _StdU_SetVerbose' #Enable or disable "verbose" mode (for debugging)
#################################################################################
# MACRO DEFINITIONS
#################################################################################
!macro _StdU_Time out
StdUtils::Time /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetMinutes out
StdUtils::GetMinutes /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetHours out
StdUtils::GetHours /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetDays out
StdUtils::GetDays /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_Rand out
StdUtils::Rand /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_RandMax out max
push ${max}
StdUtils::RandMax /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_RandMinMax out min max
push ${min}
push ${max}
StdUtils::RandMinMax /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_RandList count max
push ${max}
push ${count}
StdUtils::RandList /NOUNLOAD
!macroend
!macro _StdU_RandBytes out count
push ${count}
StdUtils::RandBytes /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_FormatStr out format val
push `${format}`
push ${val}
StdUtils::FormatStr /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_FormatStr2 out format val1 val2
push `${format}`
push ${val1}
push ${val2}
StdUtils::FormatStr2 /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_FormatStr3 out format val1 val2 val3
push `${format}`
push ${val1}
push ${val2}
push ${val3}
StdUtils::FormatStr3 /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_ScanStr out format input default
push `${format}`
push `${input}`
push ${default}
StdUtils::ScanStr /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_ScanStr2 out1 out2 format input default1 default2
push `${format}`
push `${input}`
push ${default1}
push ${default2}
StdUtils::ScanStr2 /NOUNLOAD
pop ${out1}
pop ${out2}
!macroend
!macro _StdU_ScanStr3 out1 out2 out3 format input default1 default2 default3
push `${format}`
push `${input}`
push ${default1}
push ${default2}
push ${default3}
StdUtils::ScanStr3 /NOUNLOAD
pop ${out1}
pop ${out2}
pop ${out3}
!macroend
!macro _StdU_TrimStr var
push ${var}
StdUtils::TrimStr /NOUNLOAD
pop ${var}
!macroend
!macro _StdU_TrimStrLeft var
push ${var}
StdUtils::TrimStrLeft /NOUNLOAD
pop ${var}
!macroend
!macro _StdU_TrimStrRight var
push ${var}
StdUtils::TrimStrRight /NOUNLOAD
pop ${var}
!macroend
!macro _StdU_RevStr var
push ${var}
StdUtils::RevStr /NOUNLOAD
pop ${var}
!macroend
!macro _StdU_ValidFileName out test
push `${test}`
StdUtils::ValidFileName /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_ValidPathSpec out test
push `${test}`
StdUtils::ValidPathSpec /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_ValidDomain out test
push `${test}`
StdUtils::ValidDomainName /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_StrToUtf8 out str
push `${str}`
StdUtils::StrToUtf8 /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_StrFromUtf8 out trnc str
push ${trnc}
push `${str}`
StdUtils::StrFromUtf8 /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_SHFileMove out from to hwnd
push `${from}`
push `${to}`
push ${hwnd}
StdUtils::SHFileMove /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_SHFileCopy out from to hwnd
push `${from}`
push `${to}`
push ${hwnd}
StdUtils::SHFileCopy /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_AppendToFile out from dest offset maxlen
push `${from}`
push `${dest}`
push ${offset}
push ${maxlen}
StdUtils::AppendToFile /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_ExecShlUser out file verb args
push `${file}`
push `${verb}`
push `${args}`
StdUtils::ExecShellAsUser /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_InvkeShlVrb out path file verb_id
push "${path}"
push "${file}"
push ${verb_id}
StdUtils::InvokeShellVerb /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_ExecShlWaitEx out_res out_val file verb args
push `${file}`
push `${verb}`
push `${args}`
StdUtils::ExecShellWaitEx /NOUNLOAD
pop ${out_res}
pop ${out_val}
!macroend
!macro _StdU_WaitForProcEx out handle
push `${handle}`
StdUtils::WaitForProcEx /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetParameter out name default
push `${name}`
push `${default}`
StdUtils::GetParameter /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_TestParameter out name
push `${name}`
StdUtils::TestParameter /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_ParameterCnt out
StdUtils::ParameterCnt /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_ParameterStr out index
push ${index}
StdUtils::ParameterStr /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetAllParams out truncate
push `${truncate}`
StdUtils::GetAllParameters /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetRealOSVer out_major out_minor out_spack
StdUtils::GetRealOsVersion /NOUNLOAD
pop ${out_major}
pop ${out_minor}
pop ${out_spack}
!macroend
!macro _StdU_GetRealOSBld out
StdUtils::GetRealOsBuildNo /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetRealOSStr out
StdUtils::GetRealOsName /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_VrfyRealOSVer out major minor spack
push `${major}`
push `${minor}`
push `${spack}`
StdUtils::VerifyRealOsVersion /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_VrfyRealOSBld out build
push `${build}`
StdUtils::VerifyRealOsBuildNo /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetOSEdition out
StdUtils::GetOsEdition /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetOSRelIdNo out
StdUtils::GetOsReleaseId /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_HashText out type text
push `${type}`
push `${text}`
StdUtils::HashText /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_HashFile out type file
push `${type}`
push `${file}`
StdUtils::HashFile /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_NormalizePath out path
push `${path}`
StdUtils::NormalizePath /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetParentPath out path
push `${path}`
StdUtils::GetParentPath /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_SplitPath out_drive out_dir out_fname out_ext path
push `${path}`
StdUtils::SplitPath /NOUNLOAD
pop ${out_drive}
pop ${out_dir}
pop ${out_fname}
pop ${out_ext}
!macroend
!macro _StdU_GetDrivePart out path
push `${path}`
StdUtils::GetDrivePart /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetDirPart out path
push `${path}`
StdUtils::GetDirectoryPart /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetFNamePart out path
push `${path}`
StdUtils::GetFileNamePart /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetExtnPart out path
push `${path}`
StdUtils::GetExtensionPart /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_TimerCreate out callback interval
GetFunctionAddress ${out} ${callback}
push ${out}
push ${interval}
StdUtils::TimerCreate /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_TimerDestroy out timer_id
push ${timer_id}
StdUtils::TimerDestroy /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_PrtctStr out dpsc salt text
push `${dpsc}`
push `${salt}`
push `${text}`
StdUtils::ProtectStr /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_UnprtctStr out trnc salt data
push `${trnc}`
push `${salt}`
push `${data}`
StdUtils::UnprotectStr /NOUNLOAD
pop ${out}
!macroend
!macro _StdU_GetLibVersion out_ver out_tst
StdUtils::GetLibVersion /NOUNLOAD
pop ${out_ver}
pop ${out_tst}
!macroend
!macro _StdU_SetVerbose enable
Push ${enable}
StdUtils::SetVerboseMode /NOUNLOAD
!macroend
#################################################################################
# MAGIC NUMBERS
#################################################################################
!define StdUtils.Const.ShellVerb.PinToTaskbar 0
!define StdUtils.Const.ShellVerb.UnpinFromTaskbar 1
!define StdUtils.Const.ShellVerb.PinToStart 2
!define StdUtils.Const.ShellVerb.UnpinFromStart 3
!endif # !___STDUTILS__NSH___

View File

@ -0,0 +1,48 @@
; StrContains
; This function does a case sensitive searches for an occurrence of a substring in a string.
; It returns the substring if it is found.
; Otherwise it returns null("").
; Written by kenglish_hi
; Adapted from StrReplace written by dandaman32
Var STR_HAYSTACK
Var STR_NEEDLE
Var STR_CONTAINS_VAR_1
Var STR_CONTAINS_VAR_2
Var STR_CONTAINS_VAR_3
Var STR_CONTAINS_VAR_4
Var STR_RETURN_VAR
Function StrContains
Exch $STR_NEEDLE
Exch 1
Exch $STR_HAYSTACK
; Uncomment to debug
;MessageBox MB_OK 'STR_NEEDLE = $STR_NEEDLE STR_HAYSTACK = $STR_HAYSTACK '
StrCpy $STR_RETURN_VAR ""
StrCpy $STR_CONTAINS_VAR_1 -1
StrLen $STR_CONTAINS_VAR_2 $STR_NEEDLE
StrLen $STR_CONTAINS_VAR_4 $STR_HAYSTACK
loop:
IntOp $STR_CONTAINS_VAR_1 $STR_CONTAINS_VAR_1 + 1
StrCpy $STR_CONTAINS_VAR_3 $STR_HAYSTACK $STR_CONTAINS_VAR_2 $STR_CONTAINS_VAR_1
StrCmp $STR_CONTAINS_VAR_3 $STR_NEEDLE found
StrCmp $STR_CONTAINS_VAR_1 $STR_CONTAINS_VAR_4 done
Goto loop
found:
StrCpy $STR_RETURN_VAR $STR_NEEDLE
Goto done
done:
Pop $STR_NEEDLE ;Prevent "invalid opcode" errors and keep the
Exch $STR_RETURN_VAR
FunctionEnd
!macro _StrContainsConstructor OUT NEEDLE HAYSTACK
Push `${HAYSTACK}`
Push `${NEEDLE}`
Call StrContains
Pop `${OUT}`
!macroend
!define StrContains '!insertmacro "_StrContainsConstructor"'

View File

@ -0,0 +1,299 @@
/*** UAC Plug-in ***
Interactive User (MediumIL) Admin user (HighIL)
***[Setup.exe]************* ***[Setup.exe]**************
* * * *
* +++[.OnInit]+++++++++++ * * +++[.OnInit]++++++++++++ *
* + UAC_RunElevated >---+-+----> * + + *
* + NSIS.Quit + * * + + *
* +++++++++++++++++++++++ * * ++++++++++++++++++++++++ *
* * * *
* * * *
* +++[Section]+++++++++++ * * +++[Section]++++++++++++ *
* + + * /--+-+-<UAC_AsUser_ExecShell+ *
* +++++++++++++++++++++++ * | * ++++++++++++++++++++++++ *
* * | * *
* Win32.ShellExecute <---+--/ * *
* * * *
*************************** ****************************
*/
!ifndef UAC_HDR__INC
!verbose push
!verbose 3
!ifndef UAC_VERBOSE
!define UAC_VERBOSE 3
!endif
!verbose ${UAC_VERBOSE}
!define UAC_HDR__INC 0x00020400 ;MMmmbbrr
!include LogicLib.nsh
/* UAC_RunElevated
**
** Starts the elevation operation.
**
** Return values:
**
** $0: Win32 error code (0 on success, 1223 if user aborted elevation dialog, anything else should be treated as a fatal error)
** $1: If $0==0:
** 0 UAC is not supported by the OS
** 1 Started a elevated child process, the current process should act like a wrapper (Call Quit without any further processing)
** 2 The process is already running @ HighIL (Member of admin group)
** 3 You should call RunElevated again (This can happen if a user without admin priv. is used in the runas dialog)
** $2: If $0==0 && $1==1: ExitCode of the elevated fork process (The NSIS errlvl is also set)
** $3: If $0==0: 1 if the user is a member of the admin group or 0 otherwise
**/
!macro UAC_RunElevated
UAC::_ 0
!macroend
!macro UAC_PageElevation_RunElevated
UAC::_ 0
!macroend
/*!macro UAC_OnInitElevation_RunElevated
UAC::_ 0
!macroend
!macro UAC_OnInitElevation_OnGuiInit
!macroend*/
/* UAC_GetIntegrityLevel <NSISVar:Output | "s">
**
** Get integrity level of current process
**
**/
!macro UAC_GetIntegrityLevel outvar
UAC::_ 6
!if "${outvar}" != "s"
Pop ${outvar}
!endif
!macroend
/* UAC_IsAdmin
**
** Is the current process running with administrator privileges? Result in $0
**
** ${If} ${UAC_IsAdmin} ...
**
**/
!macro UAC_IsAdmin
UAC::_ 2
!macroend
!define UAC_IsAdmin `"" UAC_IsAdmin ""`
!macro _UAC_IsAdmin _a _b _t _f
!insertmacro _UAC_MakeLL_Cmp _!= 0 2s
!macroend
/* UAC_IsInnerInstance
**
** Does the current process have a NSIS/UAC parent process that is part of the elevation operation?
**
** ${If} ${UAC_IsInnerInstance} ...
**
**/
!macro UAC_IsInnerInstance
UAC::_ 3
!macroend
!define UAC_IsInnerInstance `"" UAC_IsInnerInstance ""`
!macro _UAC_IsInnerInstance _a _b _t _f
!insertmacro _UAC_MakeLL_Cmp _!= 0 3s
!macroend
/* UAC_PageElevation_OnInit, UAC_PageElevation_OnGuiInit,
**
** Helper macros for elevation on a custom elevation page, see the DualMode example for more information.
**
**/
!macro UAC_Notify_OnGuiInit
UAC::_ 4
!macroend
!macro UAC_PageElevation_OnGuiInit
!insertmacro UAC_Notify_OnGuiInit
!macroend
!macro UAC_PageElevation_OnInit
UAC::_ 5
${IfThen} ${Errors} ${|} Quit ${|}
!macroend
/* UAC_AsUser_Call <Function|Label> <NSISAddressName> <UAC_* flags>
**
** Calls a function or label in the user process instance.
** All the UAC_AsUser_* macros use this helper macro.
**
**/
!define UAC_SYNCREGISTERS 0x1
;define UAC_SYNCSTACK 0x2
!define UAC_SYNCOUTDIR 0x4
!define UAC_SYNCINSTDIR 0x8
;define UAC_CLEARERRFLAG 0x10
!macro UAC_AsUser_Call type name flags
push $0
Get${type}Address $0 ${name}
!verbose push
!verbose ${UAC_VERBOSE}
!insertmacro _UAC_ParseDefineFlagsToInt _UAC_AsUser_Call__flags ${flags}
!verbose pop
StrCpy $0 "1$0:${_UAC_AsUser_Call__flags}"
!undef _UAC_AsUser_Call__flags
Exch $0
UAC::_
!macroend
/*
** UAC_AsUser_GetSection <Flags|InstTypes|Size|Text> <SectionIndex> <NSISVar:Output>
*/
!macro UAC_AsUser_GetSection secprop secidx outvar
!insertmacro _UAC_AsUser_GenOp ${outvar} SectionGet${secprop} ${secidx} ""
!macroend
/*
** UAC_AsUser_GetGlobalVar <NSISVar:SourceAndOutput>
** UAC_AsUser_GetGlobal <NSISVar:Output> <NSISVar:Source>
*/
!macro UAC_AsUser_GetGlobalVar var
!insertmacro _UAC_AsUser_GenOp ${var} StrCpy "" ${var}
!macroend
!macro UAC_AsUser_GetGlobal outvar srcvar
!insertmacro _UAC_AsUser_GenOp ${outvar} StrCpy "" ${srcvar}
!macroend
/*
** UAC_AsUser_ExecShell <Verb> <ApplicationOrFile> <Parameters> <Working Directory> <SW_*>
**
** Call ExecShell in the user process instance.
**
*/
!macro UAC_AsUser_ExecShell verb command params workdir show
!insertmacro _UAC_IncL
goto _UAC_L_E_${__UAC_L}
_UAC_L_F_${__UAC_L}:
ExecShell "${verb}" "${command}" '${params}' ${show}
return
_UAC_L_E_${__UAC_L}:
!if "${workdir}" != ""
push $outdir
SetOutPath "${workdir}"
!endif
!insertmacro UAC_AsUser_Call Label _UAC_L_F_${__UAC_L} ${UAC_SYNCREGISTERS}|${UAC_SYNCOUTDIR}|${UAC_SYNCINSTDIR} #|${UAC_CLEARERRFLAG}
!if "${workdir}" != ""
pop $outdir
SetOutPath $outdir
!endif
!macroend
!macro _UAC_MakeLL_Cmp cmpop cmp pluginparams
!insertmacro _LOGICLIB_TEMP
UAC::_ ${pluginparams}
pop $_LOGICLIB_TEMP
!insertmacro ${cmpop} $_LOGICLIB_TEMP ${cmp} `${_t}` `${_f}`
!macroend
!macro _UAC_definemath def val1 op val2
!define /math _UAC_definemath "${val1}" ${op} ${val2}
!ifdef ${def}
!undef ${def}
!endif
!define ${def} "${_UAC_definemath}"
!undef _UAC_definemath
!macroend
!macro _UAC_ParseDefineFlags_orin parse outflags
!searchparse /noerrors ${${parse}} "" _UAC_ParseDefineFlags_orin_f1 "|" _UAC_ParseDefineFlags_orin_f2
!define _UAC_ParseDefineFlags_orin_this ${_UAC_ParseDefineFlags_orin_f1}
!undef ${parse}
!define ${parse} ${_UAC_ParseDefineFlags_orin_f2}
!define _UAC_ParseDefineFlags_orin_saveout ${${outflags}}
!undef ${outflags}
!define /math ${outflags} "${_UAC_ParseDefineFlags_orin_saveout}" | "${_UAC_ParseDefineFlags_orin_this}"
!undef _UAC_ParseDefineFlags_orin_saveout
!undef _UAC_ParseDefineFlags_orin_this
!ifdef _UAC_ParseDefineFlags_orin_f1
!undef _UAC_ParseDefineFlags_orin_f1
!endif
!ifdef _UAC_ParseDefineFlags_orin_f2
!undef _UAC_ParseDefineFlags_orin_f2
!endif
!macroend
!macro _UAC_ParseDefineFlags_Begin _outdef _in
!define _UAC_PDF${_outdef}_parse "${_in}"
!define _UAC_PDF${_outdef}_flags ""
!define _UAC_PDF${_outdef}_r 0
!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x1
!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x2
!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x4
!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x8
!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x10
!macroend
!macro _UAC_ParseDefineFlags_End _outdef
!define ${_outdef} ${_UAC_PDF${_outdef}_r}
!undef _UAC_PDF${_outdef}_r
!undef _UAC_PDF${_outdef}_flags
!undef _UAC_PDF${_outdef}_parse
!macroend
!macro _UAC_ParseDefineFlags_IncludeFlag _outdef flag
!if ${_UAC_PDF${_outdef}_flags} & ${flag}
!insertmacro _UAC_definemath _UAC_PDF${_outdef}_r ${_UAC_PDF${_outdef}_r} | ${flag}
!endif
!macroend
!macro _UAC_ParseDefineFlagsToInt _outdef _in
!insertmacro _UAC_ParseDefineFlags_Begin _UAC_ParseDefineFlagsToInt_tmp "${_in}"
!define ${_outdef} ${_UAC_PDF_UAC_ParseDefineFlagsToInt_tmp_flags}
!insertmacro _UAC_ParseDefineFlags_End _UAC_ParseDefineFlagsToInt_tmp
!undef _UAC_ParseDefineFlagsToInt_tmp
!macroend
!macro _UAC_IncL
!insertmacro _UAC_definemath __UAC_L "${__UAC_L}" + 1
!macroend
!macro _UAC_AsUser_GenOp outvar op opparam1 opparam2
!define _UAC_AUGOGR_ID _UAC_AUGOGR_OP${outvar}${op}${opparam1}${opparam2}
!ifndef ${_UAC_AUGOGR_ID} ;Has this exact action been done before?
!if ${outvar} == $0
!define ${_UAC_AUGOGR_ID} $1
!else
!define ${_UAC_AUGOGR_ID} $0
!endif
!if "${opparam1}" == ""
!define _UAC_AUGOGR_OPP1 ${${_UAC_AUGOGR_ID}}
!define _UAC_AUGOGR_OPP2 ${opparam2}
!else
!define _UAC_AUGOGR_OPP1 ${opparam1}
!define _UAC_AUGOGR_OPP2 ${${_UAC_AUGOGR_ID}}
!endif
goto ${_UAC_AUGOGR_ID}_C
${_UAC_AUGOGR_ID}_F:
${op} ${_UAC_AUGOGR_OPP1} ${_UAC_AUGOGR_OPP2}
return
${_UAC_AUGOGR_ID}_C:
!undef _UAC_AUGOGR_OPP1
!undef _UAC_AUGOGR_OPP2
!endif
push ${${_UAC_AUGOGR_ID}}
!insertmacro UAC_AsUser_Call Label ${_UAC_AUGOGR_ID}_F ${UAC_SYNCREGISTERS}
StrCpy ${outvar} ${${_UAC_AUGOGR_ID}}
pop ${${_UAC_AUGOGR_ID}}
!undef _UAC_AUGOGR_ID
!macroend
!verbose pop
!endif /* UAC_HDR__INC */

View File

@ -0,0 +1,77 @@
!include "nsProcess.nsh"
!ifmacrondef customCheckAppRunning
!include "getProcessInfo.nsh"
Var pid
!endif
# http://nsis.sourceforge.net/Allow_only_one_installer_instance
!macro ALLOW_ONLY_ONE_INSTALLER_INSTANCE
BringToFront
!define /ifndef SYSTYPE_PTR p ; NSIS v3.0+
System::Call 'kernel32::CreateMutex(${SYSTYPE_PTR}0, i1, t"${APP_GUID}")?e'
Pop $0
IntCmpU $0 183 0 launch launch ; ERROR_ALREADY_EXISTS
StrLen $0 "$(^SetupCaption)"
IntOp $0 $0 + 1 ; GetWindowText count includes \0
StrCpy $1 "" ; Start FindWindow with NULL
loop:
FindWindow $1 "#32770" "" "" $1
StrCmp 0 $1 notfound
System::Call 'user32::GetWindowText(${SYSTYPE_PTR}r1, t.r2, ir0)'
StrCmp $2 "$(^SetupCaption)" 0 loop
SendMessage $1 0x112 0xF120 0 /TIMEOUT=2000 ; WM_SYSCOMMAND:SC_RESTORE to restore the window if it is minimized
System::Call "user32::SetForegroundWindow(${SYSTYPE_PTR}r1)"
notfound:
Abort
launch:
!macroend
!macro CHECK_APP_RUNNING
!ifmacrodef customCheckAppRunning
!insertmacro customCheckAppRunning
!else
!insertmacro _CHECK_APP_RUNNING
!endif
!macroend
!macro _CHECK_APP_RUNNING
${GetProcessInfo} 0 $pid $1 $2 $3 $4
${if} $3 != "${APP_EXECUTABLE_FILENAME}"
${if} ${isUpdated}
# allow app to exit without explicit kill
Sleep 300
${endIf}
${nsProcess::FindProcess} "${APP_EXECUTABLE_FILENAME}" $R0
${if} $R0 == 0
${if} ${isUpdated}
# allow app to exit without explicit kill
Sleep 1000
Goto doStopProcess
${endIf}
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(appRunning)" /SD IDOK IDOK doStopProcess
Quit
doStopProcess:
DetailPrint `Closing running "${PRODUCT_NAME}"...`
# https://github.com/electron-userland/electron-builder/issues/2516#issuecomment-372009092
nsExec::Exec `taskkill /t /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid"` $R0
# to ensure that files are not "in-use"
Sleep 300
${nsProcess::FindProcess} "${APP_EXECUTABLE_FILENAME}" $R0
${if} $R0 == 0
# wait to give a chance to exit gracefully
Sleep 1000
nsExec::Exec `taskkill /f /t /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid"` $R0
${If} $R0 != 0
DetailPrint `Waiting for "${PRODUCT_NAME}" to close (taskkill exit code $R0).`
Sleep 2000
${endIf}
${endIf}
${endIf}
${endIf}
!macroend

View File

@ -0,0 +1,91 @@
!macro extractEmbeddedAppPackage
!ifdef COMPRESS
SetCompress off
!endif
Var /GLOBAL packageArch
!ifdef APP_64
!ifdef APP_ARM64
StrCpy $packageArch "ARM64"
!else
StrCpy $packageArch "64"
!endif
!insertmacro compute_files_for_current_arch
!else
!insertmacro ia32_app_files
!endif
!ifdef COMPRESS
SetCompress "${COMPRESS}"
!endif
!ifdef ZIP_COMPRESSION
nsisunz::Unzip "$PLUGINSDIR\app-$packageArch.zip" "$INSTDIR"
!else
!insertmacro extractUsing7za "$PLUGINSDIR\app-$packageArch.7z"
!endif
# after decompression
${if} $packageArch == "ARM64"
!ifmacrodef customFiles_arm64
!insertmacro customFiles_arm64
!endif
${elseif} $packageArch == "64"
!ifmacrodef customFiles_x64
!insertmacro customFiles_x64
!endif
${else}
!ifmacrodef customFiles_ia32
!insertmacro customFiles_ia32
!endif
${endIf}
!macroend
!macro compute_files_for_current_arch
!ifdef APP_32
!ifdef APP_ARM64
${if} ${IsNativeARM64}
!insertmacro arm64_app_files
${elseif} ${RunningX64}
!insertmacro x64_app_files
${else}
!insertmacro ia32_app_files
${endIf}
!else
${if} ${RunningX64}
!insertmacro x64_app_files
${else}
!insertmacro ia32_app_files
${endIf}
!endif
!else
!ifdef APP_ARM64
${if} ${IsNativeARM64}
!insertmacro arm64_app_files
${else}
!insertmacro x64_app_files
${endIf}
!else
!insertmacro x64_app_files
!endif
!endif
!macroend
!macro arm64_app_files
File /oname=$PLUGINSDIR\app-arm64.${COMPRESSION_METHOD} "${APP_ARM64}"
!macroend
!macro x64_app_files
File /oname=$PLUGINSDIR\app-64.${COMPRESSION_METHOD} "${APP_64}"
!macroend
!macro ia32_app_files
StrCpy $packageArch "32"
File /oname=$PLUGINSDIR\app-32.${COMPRESSION_METHOD} "${APP_32}"
!macroend
!macro extractUsing7za FILE
Nsis7z::Extract "${FILE}"
!macroend

View File

@ -0,0 +1,157 @@
; NSIS PROCESS INFO LIBRARY - GetProcessInfo.nsh
; Version 1.1 - Mar 28th, 2011
;
; Description:
; Gets process information.
;
; Usage example:
; ${GetProcessInfo} 0 $0 $1 $2 $3 $4
; DetailPrint "pid=$0 parent_pid=$1 priority=$2 process_name=$3 exe=$4"
;
; History:
; 1.1 - 28/03/2011 - Added uninstall function, include guards, file header. Fixed getting full exe path on pre vista systems. (Sergius)
;
!ifndef GETPROCESSINFO_INCLUDED
!define GETPROCESSINFO_INCLUDED
!define PROCESSINFO.TH32CS_SNAPPROCESS 2
!define PROCESSINFO.INVALID_HANDLE_VALUE -1
!define GetProcessInfo '!insertmacro GetProcessInfo'
;@in pid_in - if 0 - get current process info
;@out pid_out - real process id (may be useful, if pid_in=0)
;@out ppid - parent process id
;@out priority
;@out name - name of process
;@out fullname - fully-qualified path of process
!macro GetProcessInfo pid_in pid_out ppid priority name fullname
Push ${pid_in}
!ifdef BUILD_UNINSTALLER
Call un._GetProcessInfo
!else
Call _GetProcessInfo
!endif
;name;pri;ppid;fname;pid;
Pop ${name}
Pop ${priority}
Pop ${ppid}
Pop ${fullname}
Pop ${pid_out}
!macroend
!macro FUNC_GETPROCESSINFO
Exch $R3 ;pid
Push $0
Push $1
Push $2
Push $3
Push $4
Push $5
Push $R0 ;hSnapshot
Push $R1 ;result
Push $R9 ;PROCESSENTRY32;MODULEENTRY32 and so on
Push $R8
;zero registers to waste trash, if error occurred
StrCpy $0 ""
StrCpy $1 ""
StrCpy $2 ""
StrCpy $3 ""
StrCpy $4 ""
StrCpy $5 ""
IntCmp $R3 0 0 skip_pid_detection skip_pid_detection
System::Call 'kernel32::GetCurrentProcess() i.R0'
System::Call "Kernel32::GetProcessId(i R0) i.R3"
skip_pid_detection:
System::Call 'Kernel32::CreateToolhelp32Snapshot(i ${PROCESSINFO.TH32CS_SNAPPROCESS},i R3) i.R0'
IntCmp $R0 ${PROCESSINFO.INVALID_HANDLE_VALUE} end ;someting wrong
;$R9=PROCESSENTRY32
;typedef struct tagPROCESSENTRY32 {
; DWORD dwSize;
; DWORD cntUsage;
; DWORD th32ProcessID;
; ULONG_PTR th32DefaultHeapID;
; DWORD th32ModuleID;
; DWORD cntThreads;
; DWORD th32ParentProcessID;
; LONG pcPriClassBase;
; DWORD dwFlags;
; TCHAR szExeFile[MAX_PATH];
;}PROCESSENTRY32, *PPROCESSENTRY32;
;dwSize=4*9+2*260
System::Alloc 1024
pop $R9
System::Call "*$R9(i 556)"
System::Call 'Kernel32::Process32FirstW(i R0, i $R9) i.R1'
StrCmp $R1 0 end
nnext_iteration:
System::Call "*$R9(i,i,i.R1)" ;get PID
IntCmp $R1 $R3 exitloop
System::Call 'Kernel32::Process32NextW(i R0, i $R9) i.R1'
IntCmp $R1 0 0 nnext_iteration nnext_iteration
exitloop:
;$0 - pid
;$1 - threads
;$2 - ppid
;$3 - priority
;$4 - process name
System::Call "*$R9(i,i,i.r0,i,i,i.r1,i.r2,i.r3,i,&w256.r4)" ; Get next module
;free:
System::Free $R9
System::Call "Kernel32::CloseToolhelp32Snapshot(i R0)"
;===============
;now get full path and commandline
System::Call "Kernel32::OpenProcess(i 1040, i 0, i r0)i .R0"
StrCmp $R0 0 end
IntOp $R8 0 + 256
System::Call "psapi::GetModuleFileNameExW(i R0,i 0,t .r5, *i $R8)i .R1"
end:
Pop $R8
Pop $R9
Pop $R1
Pop $R0
Exch $5
Exch 1
Exch $4
Exch 2
Exch $3
Exch 3
Exch $2
Exch 4
Pop $1
Exch 4
Exch $0
Exch 5
Pop $R3
!macroend ;FUNC_GETPROCESSINFO
!ifndef BUILD_UNINSTALLER
Function _GetProcessInfo
!insertmacro FUNC_GETPROCESSINFO
FunctionEnd
!endif
!ifdef BUILD_UNINSTALLER
Function un._GetProcessInfo
!insertmacro FUNC_GETPROCESSINFO
FunctionEnd
!endif
!endif ;GETPROCESSINFO_INCLUDED

View File

@ -0,0 +1,192 @@
!macro moveFile FROM TO
ClearErrors
Rename `${FROM}` `${TO}`
${if} ${errors}
# not clear - can NSIS rename on another drive or not, so, in case of error, just copy
ClearErrors
!insertmacro copyFile `${FROM}` `${TO}`
Delete `${FROM}`
${endif}
!macroend
!macro copyFile FROM TO
${StdUtils.GetParentPath} $R5 `${TO}`
CreateDirectory `$R5`
ClearErrors
CopyFiles /SILENT `${FROM}` `${TO}`
!macroend
Function GetInQuotes
Exch $R0
Push $R1
Push $R2
Push $R3
StrCpy $R2 -1
IntOp $R2 $R2 + 1
StrCpy $R3 $R0 1 $R2
StrCmp $R3 "" 0 +3
StrCpy $R0 ""
Goto Done
StrCmp $R3 '"' 0 -5
IntOp $R2 $R2 + 1
StrCpy $R0 $R0 "" $R2
StrCpy $R2 0
IntOp $R2 $R2 + 1
StrCpy $R3 $R0 1 $R2
StrCmp $R3 "" 0 +3
StrCpy $R0 ""
Goto Done
StrCmp $R3 '"' 0 -5
StrCpy $R0 $R0 $R2
Done:
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
!macro GetInQuotes Var Str
Push "${Str}"
Call GetInQuotes
Pop "${Var}"
!macroend
Function GetFileParent
Exch $R0
Push $R1
Push $R2
Push $R3
StrCpy $R1 0
StrLen $R2 $R0
loop:
IntOp $R1 $R1 + 1
IntCmp $R1 $R2 get 0 get
StrCpy $R3 $R0 1 -$R1
StrCmp $R3 "\" get
Goto loop
get:
StrCpy $R0 $R0 -$R1
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
Var /GLOBAL isTryToKeepShortcuts
!macro setIsTryToKeepShortcuts
StrCpy $isTryToKeepShortcuts "true"
!ifdef allowToChangeInstallationDirectory
${ifNot} ${isUpdated}
StrCpy $isTryToKeepShortcuts "false"
${endIf}
!endif
!macroend
# https://nsis-dev.github.io/NSIS-Forums/html/t-172971.html
!macro readReg VAR ROOT_KEY SUB_KEY NAME
${if} "${ROOT_KEY}" == "SHELL_CONTEXT"
ReadRegStr "${VAR}" SHELL_CONTEXT "${SUB_KEY}" "${NAME}"
${elseif} "${ROOT_KEY}" == "HKEY_CURRENT_USER"
ReadRegStr "${VAR}" HKEY_CURRENT_USER "${SUB_KEY}" "${NAME}"
${elseif} "${ROOT_KEY}" == "HKEY_LOCAL_MACHINE"
ReadRegStr "${VAR}" HKEY_LOCAL_MACHINE "${SUB_KEY}" "${NAME}"
${else}
MessageBox MB_OK "Unsupported ${ROOT_KEY}"
${endif}
!macroend
# http://stackoverflow.com/questions/24595887/waiting-for-nsis-uninstaller-to-finish-in-nsis-installer-either-fails-or-the-uni
Function uninstallOldVersion
Var /GLOBAL uninstallerFileName
Var /Global uninstallerFileNameTemp
Var /GLOBAL installationDir
Var /GLOBAL uninstallString
Var /GLOBAL rootKey
ClearErrors
Exch $rootKey
!insertmacro readReg $uninstallString "$rootKey" "${UNINSTALL_REGISTRY_KEY}" UninstallString
${if} $uninstallString == ""
!ifdef UNINSTALL_REGISTRY_KEY_2
!insertmacro readReg $uninstallString "$rootKey" "${UNINSTALL_REGISTRY_KEY_2}" UninstallString
!endif
${if} $uninstallString == ""
Goto Done
${endif}
${endif}
# uninstaller should be copied out of app installation dir (because this dir will be deleted), so, extract uninstaller file name
!insertmacro GetInQuotes $uninstallerFileName "$uninstallString"
!insertmacro readReg $installationDir "$rootKey" "${INSTALL_REGISTRY_KEY}" InstallLocation
${if} $installationDir == ""
${andIf} $uninstallerFileName != ""
# https://github.com/electron-userland/electron-builder/issues/735#issuecomment-246918567
Push $uninstallerFileName
Call GetFileParent
Pop $installationDir
${endif}
${if} $installationDir == ""
${andIf} $uninstallerFileName == ""
Goto Done
${endif}
${if} $installMode == "CurrentUser"
${orIf} $rootKey == "HKEY_CURRENT_USER"
StrCpy $0 "/currentuser"
${else}
StrCpy $0 "/allusers"
${endif}
!insertMacro setIsTryToKeepShortcuts
${if} $isTryToKeepShortcuts == "true"
!insertmacro readReg $R5 "$rootKey" "${INSTALL_REGISTRY_KEY}" KeepShortcuts
# if true, it means that old uninstaller supports --keep-shortcuts flag
${if} $R5 == "true"
${andIf} ${FileExists} "$appExe"
StrCpy $0 "$0 --keep-shortcuts"
${endIf}
${endIf}
${if} ${isDeleteAppData}
StrCpy $0 "$0 --delete-app-data"
${else}
# always pass --updated flag - to ensure that if DELETE_APP_DATA_ON_UNINSTALL is defined, user data will be not removed
StrCpy $0 "$0 --updated"
${endif}
StrCpy $uninstallerFileNameTemp "$PLUGINSDIR\old-uninstaller.exe"
!insertmacro copyFile "$uninstallerFileName" "$uninstallerFileNameTemp"
ExecWait '"$uninstallerFileNameTemp" /S /KEEP_APP_DATA $0 _?=$installationDir' $R0
ifErrors 0 ExecErrorHandler
# the execution failed - might have been caused by some group policy restrictions
# we try to execute the uninstaller in place
ExecWait '"$uninstallerFileName" /S /KEEP_APP_DATA $0 _?=$installationDir' $R0
ifErrors 0 ExecErrorHandler
# this also failed...
DetailPrint `Aborting, uninstall was not successful. Not able to launch uninstaller!`
ExecErrorHandler:
${if} $R0 != 0
DetailPrint `Aborting, uninstall was not successful. Uninstaller error code: $R0.`
${endif}
Done:
FunctionEnd
!macro uninstallOldVersion ROOT_KEY
Push "${ROOT_KEY}"
Call uninstallOldVersion
!macroend

View File

@ -0,0 +1,227 @@
# functions (nsis macro) for installer
!include "extractAppPackage.nsh"
!ifdef APP_PACKAGE_URL
!include webPackage.nsh
!endif
!macro installApplicationFiles
!ifdef APP_BUILD_DIR
File /r "${APP_BUILD_DIR}\*.*"
!else
!ifdef APP_PACKAGE_URL
Var /GLOBAL packageFile
Var /GLOBAL isPackageFileExplicitlySpecified
${StdUtils.GetParameter} $packageFile "package-file" ""
${if} $packageFile == ""
!ifdef APP_64_NAME
!ifdef APP_32_NAME
!ifdef APP_ARM64_NAME
${if} ${IsNativeARM64}
StrCpy $packageFile "${APP_ARM64_NAME}"
StrCpy $1 "${APP_ARM64_HASH}"
${elseif} ${IsNativeAMD64}
StrCpy $packageFile "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
${else}
StrCpy $packageFile "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
${endif}
!else
${if} ${RunningX64}
StrCpy $packageFile "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
${else}
StrCpy $packageFile "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
${endif}
!endif
!else
StrCpy $packageFile "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
!endif
!else
StrCpy $packageFile "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
!endif
StrCpy $4 "$packageFile"
StrCpy $packageFile "$EXEDIR/$packageFile"
StrCpy $isPackageFileExplicitlySpecified "false"
${else}
StrCpy $isPackageFileExplicitlySpecified "true"
${endIf}
# we do not check file hash is specifed explicitly using --package-file because it is clear that user definitely want to use this file and it is user responsibility to check
# 1. auto-updater uses --package-file and validates checksum
# 2. user can user another package file (use case - one installer suitable for any app version (use latest version))
${if} ${FileExists} "$packageFile"
${if} $isPackageFileExplicitlySpecified == "true"
Goto fun_extract
${else}
${StdUtils.HashFile} $3 "SHA2-512" "$packageFile"
${if} $3 == $1
Goto fun_extract
${else}
MessageBox MB_OK "Package file $4 found locally, but checksum doesn't match — expected $1, actual $3.$\r$\nLocal file is ignored and package will be downloaded from Internet."
${endIf}
${endIf}
${endIf}
!insertmacro downloadApplicationFiles
fun_extract:
!insertmacro extractUsing7za "$packageFile"
# electron always uses per user app data
${if} $installMode == "all"
SetShellVarContext current
${endif}
!insertmacro moveFile "$packageFile" "$LOCALAPPDATA\${APP_PACKAGE_STORE_FILE}"
${if} $installMode == "all"
SetShellVarContext all
${endif}
!else
!insertmacro extractEmbeddedAppPackage
# electron always uses per user app data
${if} $installMode == "all"
SetShellVarContext current
${endif}
!insertmacro copyFile "$EXEPATH" "$LOCALAPPDATA\${APP_INSTALLER_STORE_FILE}"
${if} $installMode == "all"
SetShellVarContext all
${endif}
!endif
!endif
File "/oname=${UNINSTALL_FILENAME}" "${UNINSTALLER_OUT_FILE}"
!macroend
!macro registryAddInstallInfo
WriteRegStr SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" InstallLocation "$INSTDIR"
WriteRegStr SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" KeepShortcuts "true"
WriteRegStr SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" ShortcutName "${SHORTCUT_NAME}"
!ifdef MENU_FILENAME
WriteRegStr SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" MenuDirectory "${MENU_FILENAME}"
!endif
${if} $installMode == "all"
StrCpy $0 "/allusers"
StrCpy $1 ""
${else}
StrCpy $0 "/currentuser"
StrCpy $1 ""
${endIf}
WriteRegStr SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}" DisplayName "${UNINSTALL_DISPLAY_NAME}$1"
# https://github.com/electron-userland/electron-builder/issues/750
StrCpy $2 "$INSTDIR\${UNINSTALL_FILENAME}"
WriteRegStr SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}" UninstallString '"$2" $0'
WriteRegStr SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}" QuietUninstallString '"$2" $0 /S'
WriteRegStr SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}" "DisplayVersion" "${VERSION}"
!ifdef UNINSTALLER_ICON
WriteRegStr SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}" "DisplayIcon" "$INSTDIR\uninstallerIcon.ico"
!else
WriteRegStr SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}" "DisplayIcon" "$appExe,0"
!endif
!ifdef COMPANY_NAME
WriteRegStr SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}" "Publisher" "${COMPANY_NAME}"
!endif
WriteRegDWORD SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}" NoModify 1
WriteRegDWORD SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}" NoRepair 1
# allow user to define ESTIMATED_SIZE to avoid GetSize call
!ifdef ESTIMATED_SIZE
IntFmt $0 "0x%08X" ${ESTIMATED_SIZE}
!else
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
!endif
WriteRegDWORD SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}" "EstimatedSize" "$0"
!macroend
!macro cleanupOldMenuDirectory
${if} $oldMenuDirectory != ""
!ifdef MENU_FILENAME
${if} $oldMenuDirectory != "${MENU_FILENAME}"
RMDir "$SMPROGRAMS\$oldMenuDirectory"
${endIf}
!else
RMDir "$SMPROGRAMS\$oldMenuDirectory"
!endif
${endIf}
!macroend
!macro createMenuDirectory
!ifdef MENU_FILENAME
CreateDirectory "$SMPROGRAMS\${MENU_FILENAME}"
ClearErrors
!endif
!macroend
!macro addStartMenuLink keepShortcuts
!ifndef DO_NOT_CREATE_START_MENU_SHORTCUT
# The keepShortcuts mechanism is NOT enabled.
# Menu shortcut will be recreated.
${if} $keepShortcuts == "false"
!insertmacro cleanupOldMenuDirectory
!insertmacro createMenuDirectory
CreateShortCut "$newStartMenuLink" "$appExe" "" "$appExe" 0 "" "" "${APP_DESCRIPTION}"
# clear error (if shortcut already exists)
ClearErrors
WinShell::SetLnkAUMI "$newStartMenuLink" "${APP_ID}"
# The keepShortcuts mechanism IS enabled.
# The menu shortcut could either not exist (it shouldn't be recreated) or exist in an obsolete location.
${elseif} $oldStartMenuLink != $newStartMenuLink
${andIf} ${FileExists} "$oldStartMenuLink"
!insertmacro createMenuDirectory
Rename $oldStartMenuLink $newStartMenuLink
WinShell::UninstShortcut "$oldStartMenuLink"
WinShell::SetLnkAUMI "$newStartMenuLink" "${APP_ID}"
!insertmacro cleanupOldMenuDirectory
${endIf}
!endif
!macroend
!macro addDesktopLink keepShortcuts
!ifndef DO_NOT_CREATE_DESKTOP_SHORTCUT
# https://github.com/electron-userland/electron-builder/pull/1432
${ifNot} ${isNoDesktopShortcut}
# The keepShortcuts mechanism is NOT enabled.
# Shortcuts will be recreated.
${if} $keepShortcuts == "false"
CreateShortCut "$newDesktopLink" "$appExe" "" "$appExe" 0 "" "" "${APP_DESCRIPTION}"
ClearErrors
WinShell::SetLnkAUMI "$newDesktopLink" "${APP_ID}"
# The keepShortcuts mechanism IS enabled.
# The desktop shortcut could exist in an obsolete location (due to name change).
${elseif} $oldDesktopLink != $newDesktopLink
${orIf} ${FileExists} "$oldDesktopLink"
Rename $oldDesktopLink $newDesktopLink
WinShell::UninstShortcut "$oldDesktopLink"
WinShell::SetLnkAUMI "$newDesktopLink" "${APP_ID}"
!ifdef RECREATE_DESKTOP_SHORTCUT
${elseif} $oldDesktopLink != $newDesktopLink
${orIfNot} ${FileExists} "$oldDesktopLink"
${ifNot} ${isUpdated}
CreateShortCut "$newDesktopLink" "$appExe" "" "$appExe" 0 "" "" "${APP_DESCRIPTION}"
ClearErrors
WinShell::SetLnkAUMI "$newDesktopLink" "${APP_ID}"
${endIf}
!endif
${endIf}
System::Call 'Shell32::SHChangeNotify(i 0x8000000, i 0, i 0, i 0)'
${endIf}
!endif
!macroend

View File

@ -0,0 +1,28 @@
!define nsProcess::FindProcess `!insertmacro nsProcess::FindProcess`
!macro nsProcess::FindProcess _FILE _ERR
nsProcess::_FindProcess /NOUNLOAD `${_FILE}`
Pop ${_ERR}
!macroend
!define nsProcess::KillProcess `!insertmacro nsProcess::KillProcess`
!macro nsProcess::KillProcess _FILE _ERR
nsProcess::_KillProcess /NOUNLOAD `${_FILE}`
Pop ${_ERR}
!macroend
!define nsProcess::CloseProcess `!insertmacro nsProcess::CloseProcess`
!macro nsProcess::CloseProcess _FILE _ERR
nsProcess::_CloseProcess /NOUNLOAD `${_FILE}`
Pop ${_ERR}
!macroend
!define nsProcess::Unload `!insertmacro nsProcess::Unload`
!macro nsProcess::Unload
nsProcess::_Unload
!macroend

View File

@ -0,0 +1,64 @@
!macro downloadApplicationFiles
Var /GLOBAL packageUrl
Var /GLOBAL packageArch
StrCpy $packageUrl "${APP_PACKAGE_URL}"
StrCpy $packageArch "${APP_PACKAGE_URL}"
!ifdef APP_PACKAGE_URL_IS_INCOMLETE
!ifdef APP_64_NAME
!ifdef APP_32_NAME
!ifdef APP_ARM64_NAME
${if} ${IsNativeARM64}
StrCpy $packageUrl "$packageUrl/${APP_ARM64_NAME}"
${elseif} ${IsNativeAMD64}
StrCpy $packageUrl "$packageUrl/${APP_64_NAME}"
${else}
StrCpy $packageUrl "$packageUrl/${APP_32_NAME}"
${endif}
!else
${if} ${IsNativeAMD64}
StrCpy $packageUrl "$packageUrl/${APP_64_NAME}"
${else}
StrCpy $packageUrl "$packageUrl/${APP_32_NAME}"
${endif}
!endif
!else
StrCpy $packageUrl "$packageUrl/${APP_64_NAME}"
!endif
!else
StrCpy $packageUrl "$packageUrl/${APP_32_NAME}"
!endif
!endif
${if} ${IsNativeARM64}
StrCpy $packageArch "ARM64"
${elseif} ${IsNativeAMD64}
StrCpy $packageArch "64"
${else}
StrCpy $packageArch "32"
${endif}
download:
inetc::get /USERAGENT "electron-builder (Mozilla)" /HEADER "X-Arch: $packageArch" /RESUME "" "$packageUrl" "$PLUGINSDIR\package.7z" /END
Pop $0
${if} $0 == "Cancelled"
Quit
${endif}
${if} $0 != "OK"
# try without proxy
inetc::get /NOPROXY /USERAGENT "electron-builder (Mozilla)" /HEADER "X-Arch: $packageArch" /RESUME "" "$packageUrl" "$PLUGINSDIR\package.7z" /END
Pop $0
${endif}
${if} $0 == "Cancelled"
quit
${elseif} $0 != "OK"
Messagebox MB_RETRYCANCEL|MB_ICONEXCLAMATION "Unable to download application package from $packageUrl (status: $0).$\r$\n$\r$\nPlease check you Internet connection and retry." IDRETRY download
Quit
${endif}
StrCpy $packageFile "$PLUGINSDIR\package.7z"
!macroend

View File

@ -0,0 +1,104 @@
!include installer.nsh
InitPluginsDir
${IfNot} ${Silent}
SetDetailsPrint none
${endif}
StrCpy $appExe "$INSTDIR\${APP_EXECUTABLE_FILENAME}"
# must be called before uninstallOldVersion
!insertmacro setLinkVars
!ifdef ONE_CLICK
!ifdef HEADER_ICO
File /oname=$PLUGINSDIR\installerHeaderico.ico "${HEADER_ICO}"
!endif
${IfNot} ${Silent}
!ifdef HEADER_ICO
SpiderBanner::Show /MODERN /ICON "$PLUGINSDIR\installerHeaderico.ico"
!else
SpiderBanner::Show /MODERN
!endif
FindWindow $0 "#32770" "" $hwndparent
FindWindow $0 "#32770" "" $hwndparent $0
GetDlgItem $0 $0 1000
SendMessage $0 ${WM_SETTEXT} 0 "STR:$(installing)"
${endif}
!insertmacro CHECK_APP_RUNNING
!else
${ifNot} ${UAC_IsInnerInstance}
!insertmacro CHECK_APP_RUNNING
${endif}
!endif
Var /GLOBAL keepShortcuts
StrCpy $keepShortcuts "false"
!insertMacro setIsTryToKeepShortcuts
${if} $isTryToKeepShortcuts == "true"
ReadRegStr $R1 SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" KeepShortcuts
${if} $R1 == "true"
${andIf} ${FileExists} "$appExe"
StrCpy $keepShortcuts "true"
${endIf}
${endif}
!insertmacro uninstallOldVersion SHELL_CONTEXT
${if} $installMode == "all"
!insertmacro uninstallOldVersion HKEY_CURRENT_USER
${endIf}
SetOutPath $INSTDIR
!ifdef UNINSTALLER_ICON
File /oname=uninstallerIcon.ico "${UNINSTALLER_ICON}"
!endif
!insertmacro installApplicationFiles
!insertmacro registryAddInstallInfo
!insertmacro addStartMenuLink $keepShortcuts
!insertmacro addDesktopLink $keepShortcuts
${if} ${FileExists} "$newStartMenuLink"
StrCpy $launchLink "$newStartMenuLink"
${else}
StrCpy $launchLink "$INSTDIR\${APP_EXECUTABLE_FILENAME}"
${endIf}
!ifmacrodef registerFileAssociations
!insertmacro registerFileAssociations
!endif
!ifmacrodef customInstall
!insertmacro customInstall
!endif
!macro doStartApp
# otherwise app window will be in background
HideWindow
!insertmacro StartApp
!macroend
!ifdef ONE_CLICK
# https://github.com/electron-userland/electron-builder/pull/3093#issuecomment-403734568
!ifdef RUN_AFTER_FINISH
${ifNot} ${Silent}
${orIf} ${isForceRun}
!insertmacro doStartApp
${endIf}
!else
${if} ${isForceRun}
!insertmacro doStartApp
${endIf}
!endif
!insertmacro quitSuccess
!else
# for assisted installer run only if silent, because assisted installer has run after finish option
${if} ${isForceRun}
${andIf} ${Silent}
!insertmacro doStartApp
${endIf}
!endif

View File

@ -0,0 +1,90 @@
Var newStartMenuLink
Var oldStartMenuLink
Var newDesktopLink
Var oldDesktopLink
Var oldShortcutName
Var oldMenuDirectory
!include "common.nsh"
!include "MUI2.nsh"
!include "multiUser.nsh"
!include "allowOnlyOneInstallerInstance.nsh"
!ifdef INSTALL_MODE_PER_ALL_USERS
!ifdef BUILD_UNINSTALLER
RequestExecutionLevel user
!else
RequestExecutionLevel admin
!endif
!else
RequestExecutionLevel user
!endif
!ifdef BUILD_UNINSTALLER
SilentInstall silent
!else
Var appExe
Var launchLink
!endif
!ifdef ONE_CLICK
!include "oneClick.nsh"
!else
!include "assistedInstaller.nsh"
!endif
!insertmacro addLangs
!ifmacrodef customHeader
!insertmacro customHeader
!endif
Function .onInit
!ifmacrodef preInit
!insertmacro preInit
!endif
!ifdef DISPLAY_LANG_SELECTOR
!insertmacro MUI_LANGDLL_DISPLAY
!endif
!ifdef BUILD_UNINSTALLER
WriteUninstaller "${UNINSTALLER_OUT_FILE}"
!insertmacro quitSuccess
!else
!insertmacro check64BitAndSetRegView
!ifdef ONE_CLICK
!insertmacro ALLOW_ONLY_ONE_INSTALLER_INSTANCE
!else
${IfNot} ${UAC_IsInnerInstance}
!insertmacro ALLOW_ONLY_ONE_INSTALLER_INSTANCE
${EndIf}
!endif
!insertmacro initMultiUser
!ifmacrodef customInit
!insertmacro customInit
!endif
!ifmacrodef addLicenseFiles
InitPluginsDir
!insertmacro addLicenseFiles
!endif
!endif
FunctionEnd
!ifndef BUILD_UNINSTALLER
!include "installUtil.nsh"
!endif
Section "install"
!ifndef BUILD_UNINSTALLER
!include "installSection.nsh"
!endif
SectionEnd
!ifdef BUILD_UNINSTALLER
!include "uninstaller.nsh"
!endif

View File

@ -0,0 +1,112 @@
# one-click installer messages, see assistedMessages.yml for assisted installer messages
# en must be first (https://github.com/electron-userland/electron-builder/issues/2517)
win7Required:
en: Windows 7 and above is required
de: Windows 7 oder höher wird vorausgesetzt
it: È necessario disporre del sistema operativo Windows 7 e successivi
fr: Windows 7 (ou une version ultérieure) est requis
ja: Windows 7 以降が必要です
ko: Windows 7 이상이 필요합니다
ru: Требуется Windows 7 и выше
sk: Iba Windows 7 a vyššie je podporovaný
cs: Jsou podporovány pouze Windows 7 a vyšší
hu: Windows 7 vagy újabb szükséges
pl: Windows 7 lub nowszy jest wymagany
pt_BR: Requer Windows 7 ou superior
zh_CN: 需要 Windows 7 或以上系统
zh_TW: 需要 Windows 7 或以上系統
tr_TR: Windows 7 ve üstü gereklidir
sv_SE: Windows 7 eller högre krävs
no: Windows 7 og over er nødvendig
nl_NL: Windows 7 en hoger is vereist
fi: Windows 7 tai uudempi vaaditaan
es: Se necesita Windows 7 o una versión superior.
da: Windows 7 og højere er nødvendig
x64WinRequired:
en: 64-bit Windows is required
de: 64-Bit-Windows wird vorausgesetzt
it: È necessario disporre di un sistema operativo Windows a 64 bit
fr: Windows 64 bits est requis
ja: 64 ビット バージョンの Windows が必要です
ko: 64 비트 버전의 Windows가 필요합니다
ru: Требуется Windows 64-bit
sk: Potrebujete 64-bit Windows
cs: Potřebujete 64-bit Windows
hu: 64-bit Windows szükséges
pl: Windows 64-bitowy jest wymagany
pt_BR: Requer Windows 64 bits
zh_CN: 需要 64 位 Windows 系统
zh_TW: 需要 64 位 Windows 系統
tr_TR: 64 bit Windows gerekli
sv_SE: 64-bitars Windows krävs
no: 64-biters Windows er nødvendig
nl_NL: 64-bit Windows is vereist
fi: 64-bittinen Windows on pakollinen
es: Windows de 64 bits es requerido
da: 64-bit Windows er påkrævet
appRunning:
en: "${PRODUCT_NAME} is running.\nClick OK to close it."
de: "${PRODUCT_NAME} ist geöffnet. \nKlicken Sie zum Schliessen auf «OK»."
it: "${PRODUCT_NAME} è in esecuzione. \nPremi OK per chiudere."
fr: "${PRODUCT_NAME} est en cours dutilisation. \nCliquez sur «OK» pour fermer ce programme."
ja: "${PRODUCT_NAME} が実行中です。\nOK をクリックすると終了します。"
ko: "${PRODUCT_NAME}이(가) 실행 중입니다. \nOK을 클릭하면 종료됩니다."
ru: "Приложение ${PRODUCT_NAME} уже запущено.\nНажмите OK для закрытия."
sk: "${PRODUCT_NAME} práve beží.\nUkončite ho kliknutím na OK."
cs: "${PRODUCT_NAME} právě běží.\nUkončíte jej kliknutím na OK."
hu: "${PRODUCT_NAME} éppen fut. \nKattiontson az «OK»-ra a bezárásához."
pl: "${PRODUCT_NAME} jest otwarty. Aby zamknąć kliknij na OK."
pt_BR: "${PRODUCT_NAME} está em execução.\nClique em OK para fechar."
zh_CN: "${PRODUCT_NAME} 正在运行.\n点击“确定”关闭."
zh_TW: "${PRODUCT_NAME} 正在運行.\n點擊“確定”關閉."
tr_TR: "${PRODUCT_NAME} çalışıyor.\nKapatmak için Tamam'ı tıklayın."
sv_SE: "${PRODUCT_NAME} körs. \nKlicka på OK för att stänga det."
no: "${PRODUCT_NAME} kjører. \nKlikk OK for å lukke det."
nl_NL: "${PRODUCT_NAME} draait. \nKlik op 'OK' om het te sluiten."
fi: "${PRODUCT_NAME} on käynnissä. Napsauta OK sulkeaksesi sen."
es: "${PRODUCT_NAME} se está ejecutando. Haz clic en Aceptar para cerrarlo."
da: "${PRODUCT_NAME} er i gang. Klik OK for at lukke."
installing:
en: Installing, please wait...
de: Installation läuft, bitte warten...
it: Attendere prego. Installazione in corso...
fr: En cours dinstallation... Veuillez patienter s'il vous plaît.
ja: インストールしています。しばらくお待ちください...
ko: 설치하고 있습니다. 잠시 기다려주십시오...
ru: Установка, пожалуйста, подождите...
sk: Inštalujem, prosím počkajte...
cs: Instalování, prosím počkejte...
hu: Telepítés, kérem várjon...
pl: Zaczekaj na ukończenie instalacji...
pt_BR: Instalando, por favor aguarde...
zh_CN: 正在安装, 请稍候...
zh_TW: 正在安裝, 請稍候...
tr_TR: Yükleniyor, lütfen bekleyin...
sv_SE: Installerar, vänligen vänta...
no: Installerer, vennligst vent...
nl_NL: Installeren, even geduld...
fi: Asennetaan, odota...
es: Instalando, espera un momento...
da: Installerer, vent venligst...
areYouSureToUninstall:
en: Are you sure you want to uninstall ${PRODUCT_NAME}?
de: Sind Sie sicher, dass Sie ${PRODUCT_NAME} deinstallieren möchten?
it: Sicuro di voler procedere alla disinstallazione di ${PRODUCT_NAME}?
fr: Etes-vous sûr(e) de vouloir désinstaller ${PRODUCT_NAME}?
ja: ${PRODUCT_NAME} をアンインストールしてもよろしいですか?
ko: ${PRODUCT_NAME}을(를) 제거 하시겠습니까?
ru: Вы уверены, что хотите удалить ${PRODUCT_NAME}?
sk: Ste si istý že chcete odinštalovať ${PRODUCT_NAME}?
cs: Jste si jistí, že chcete odinstalovat ${PRODUCT_NAME}?
hu: Biztos benne, hogy szeretné eltávolítani a ${PRODUCT_NAME} alkalmazást?
pl: Czy na pewno chcesz odinstalować ${PRODUCT_NAME}?
pt_BR: Tem certeza que deseja desinstalar ${PRODUCT_NAME}?
zh_CN: 确定卸载 ${PRODUCT_NAME} 吗?
zh_TW: 確定卸載 ${PRODUCT_NAME} 嗎?
tr_TR: ${PRODUCT_NAME} kaldırmak istediğinize Eminmisiniz?
sv_SE: Är du säker på att du vill avinstallera ${PRODUCT_NAME}?
no: Er du sikker på at du vil avinstallere ${PRODUCT_NAME}?
nl_NL: Weet je zeker dat je ${PRODUCT_NAME} wilt verwijderen?
fi: Oletko varma, että haluat poistaa ${PRODUCT_NAME} asennuksen?
es: ¿Seguro que quieres desinstalar ${PRODUCT_NAME}?
da: Er du sikker på, at du vil afinstallere ${PRODUCT_NAME}?

View File

@ -0,0 +1,93 @@
!include FileFunc.nsh
!include UAC.nsh
!define FOLDERID_UserProgramFiles {5CD7AEE2-2219-4A67-B85D-6C9CE15660CB}
!define KF_FLAG_CREATE 0x00008000
# allow user to define own custom
!define /ifndef INSTALL_REGISTRY_KEY "Software\${APP_GUID}"
!define /ifndef UNINSTALL_REGISTRY_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_APP_KEY}"
# current Install Mode ("all" or "CurrentUser")
Var installMode
!ifndef INSTALL_MODE_PER_ALL_USERS
!ifndef ONE_CLICK
Var hasPerUserInstallation
Var hasPerMachineInstallation
!endif
Var PerUserInstallationFolder
!macro setInstallModePerUser
StrCpy $installMode CurrentUser
SetShellVarContext current
# сhecks registry for previous installation path
ReadRegStr $perUserInstallationFolder HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation
${if} $perUserInstallationFolder != ""
StrCpy $INSTDIR $perUserInstallationFolder
${else}
StrCpy $0 "$LocalAppData\Programs"
System::Store S
# Win7 has a per-user programfiles known folder and this can be a non-default location
System::Call 'SHELL32::SHGetKnownFolderPath(g "${FOLDERID_UserProgramFiles}", i ${KF_FLAG_CREATE}, p 0, *p .r2)i.r1'
${If} $1 == 0
System::Call '*$2(&w${NSIS_MAX_STRLEN} .s)'
StrCpy $0 $1
System::Call 'OLE32::CoTaskMemFree(p r2)'
${endif}
System::Store L
StrCpy $INSTDIR "$0\${APP_FILENAME}"
${endif}
# allow /D switch to override installation path https://github.com/electron-userland/electron-builder/issues/1551
${StdUtils.GetParameter} $R0 "D" ""
${If} $R0 != ""
StrCpy $INSTDIR $R0
${endif}
!macroend
!endif
!ifdef INSTALL_MODE_PER_ALL_USERS_REQUIRED
Var perMachineInstallationFolder
!macro setInstallModePerAllUsers
StrCpy $installMode all
SetShellVarContext all
!ifdef BUILD_UNINSTALLER
${IfNot} ${UAC_IsAdmin}
ShowWindow $HWNDPARENT ${SW_HIDE}
!insertmacro UAC_RunElevated
Quit
${endif}
!endif
# сheck registry for previous installation path
ReadRegStr $perMachineInstallationFolder HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation
${if} $perMachineInstallationFolder != ""
StrCpy $INSTDIR $perMachineInstallationFolder
${else}
StrCpy $0 "$PROGRAMFILES"
!ifdef APP_64
${if} ${RunningX64}
StrCpy $0 "$PROGRAMFILES64"
${endif}
!endif
!ifdef MENU_FILENAME
StrCpy $0 "$0\${MENU_FILENAME}"
!endif
StrCpy $INSTDIR "$0\${APP_FILENAME}"
${endif}
# allow /D switch to override installation path https://github.com/electron-userland/electron-builder/issues/1551
${StdUtils.GetParameter} $R0 "D" ""
${If} $R0 != ""
StrCpy $INSTDIR $R0
${endif}
!macroend
!endif

View File

@ -0,0 +1,230 @@
!include nsDialogs.nsh
Var HasTwoAvailableOptions
Var RadioButtonLabel1
Var isForceMachineInstall
Var isForceCurrentInstall
!macro PAGE_INSTALL_MODE
!insertmacro MUI_PAGE_INIT
!insertmacro MUI_SET MULTIUSER_${MUI_PAGE_UNINSTALLER_PREFIX}INSTALLMODEPAGE ""
Var MultiUser.InstallModePage
Var MultiUser.InstallModePage.Text
Var MultiUser.InstallModePage.AllUsers
Var MultiUser.InstallModePage.CurrentUser
Var MultiUser.InstallModePage.ReturnValue
!ifndef BUILD_UNINSTALLER
!insertmacro FUNCTION_INSTALL_MODE_PAGE_FUNCTION MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID} ""
PageEx custom
PageCallbacks MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}
Caption " "
PageExEnd
!else
!insertmacro FUNCTION_INSTALL_MODE_PAGE_FUNCTION MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID} un.
UninstPage custom un.multiUser.InstallModePre_${MUI_UNIQUEID} un.MultiUser.InstallModeLeave_${MUI_UNIQUEID}
!endif
!macroend
!macro FUNCTION_INSTALL_MODE_PAGE_FUNCTION PRE LEAVE UNINSTALLER_FUNCPREFIX
Function "${UNINSTALLER_FUNCPREFIX}${PRE}"
${if} ${UAC_IsInnerInstance}
${andIf} ${UAC_IsAdmin}
# inner Process (and Admin) - skip selection, inner process is always used for elevation (machine-wide)
!insertmacro setInstallModePerAllUsers
Abort
${endIf}
StrCpy $isForceMachineInstall "0"
StrCpy $isForceCurrentInstall "0"
!ifmacrodef customInstallmode
!insertmacro customInstallMode
!endif
${if} $isForceMachineInstall == "1"
${OrIf} ${isForAllUsers}
StrCpy $hasPerMachineInstallation "1"
StrCpy $hasPerUserInstallation "0"
${ifNot} ${UAC_IsAdmin}
ShowWindow $HWNDPARENT ${SW_HIDE}
!insertmacro UAC_RunElevated
Quit
${endIf}
!insertmacro setInstallModePerAllUsers
Abort
${endIf}
${if} $isForceCurrentInstall == "1"
${OrIf} ${isForCurrentUser}
StrCpy $hasPerMachineInstallation "0"
StrCpy $hasPerUserInstallation "1"
!insertmacro setInstallModePerUser
Abort
${endIf}
# If uninstalling, will check if there is both a per-user and per-machine installation. If there is only one, will skip the form.
# If uninstallation was invoked from the "add/remove programs" Windows will automatically requests elevation (depending if uninstall keys are in HKLM or HKCU)
# so (for uninstallation) just checking UAC_IsAdmin would probably be enought to determine if it's a per-user or per-machine. However, user can run the uninstall.exe from the folder itself
!ifdef BUILD_UNINSTALLER
${if} $hasPerUserInstallation == "1"
${andif} $hasPerMachineInstallation == "0"
!insertmacro setInstallModePerUser
Abort
${elseIf} $hasPerUserInstallation == "0"
${andIf} $hasPerMachineInstallation == "1"
${IfNot} ${UAC_IsAdmin}
ShowWindow $HWNDPARENT ${SW_HIDE}
!insertmacro UAC_RunElevated
Quit
${endIf}
!insertmacro setInstallModePerAllUsers
Abort
${endIf}
!insertmacro MUI_HEADER_TEXT "$(chooseUninstallationOptions)" "$(whichInstallationShouldBeRemoved)"
!else
!insertmacro MUI_HEADER_TEXT "$(chooseInstallationOptions)" "$(whoShouldThisApplicationBeInstalledFor)"
!endif
!insertmacro MUI_PAGE_FUNCTION_CUSTOM PRE
nsDialogs::Create 1018
Pop $MultiUser.InstallModePage
!ifndef BUILD_UNINSTALLER
${NSD_CreateLabel} 0u 0u 300u 20u "$(selectUserMode)"
StrCpy $8 "$(forAll)"
StrCpy $9 "$(onlyForMe)"
!else
${NSD_CreateLabel} 0u 0u 300u 20u "$(whichInstallationRemove)"
StrCpy $8 "$(forAll)"
StrCpy $9 "$(onlyForMe)"
!endif
Pop $MultiUser.InstallModePage.Text
${NSD_CreateRadioButton} 10u 30u 280u 20u "$8"
Pop $MultiUser.InstallModePage.AllUsers
${IfNot} ${UAC_IsAdmin}
!ifdef MULTIUSER_INSTALLMODE_ALLOW_ELEVATION
StrCpy $HasTwoAvailableOptions 1
!else
# since radio button is disabled, we add that comment to the disabled control itself
SendMessage $MultiUser.InstallModePage.AllUsers ${WM_SETTEXT} 0 "STR:$8 (must run as admin)"
EnableWindow $MultiUser.InstallModePage.AllUsers 0 # start out disabled
StrCpy $HasTwoAvailableOptions 0
!endif
${else}
StrCpy $HasTwoAvailableOptions 1
${endif}
System::Call "advapi32::GetUserName(t.r0,*i${NSIS_MAX_STRLEN})i"
${NSD_CreateRadioButton} 10u 50u 280u 20u "$9 ($0)"
Pop $MultiUser.InstallModePage.CurrentUser
nsDialogs::SetUserData $MultiUser.InstallModePage.AllUsers 1 ; Install for All Users (1, pra exibir o icone SHIELD de elevation)
nsDialogs::SetUserData $MultiUser.InstallModePage.CurrentUser 0 ; Install for Single User (0 pra não exibir)
${if} $HasTwoAvailableOptions == "1" ; if there are 2 available options, bind to radiobutton change
${NSD_OnClick} $MultiUser.InstallModePage.CurrentUser ${UNINSTALLER_FUNCPREFIX}InstModeChange
${NSD_OnClick} $MultiUser.InstallModePage.AllUsers ${UNINSTALLER_FUNCPREFIX}InstModeChange
${endif}
${NSD_CreateLabel} 0u 110u 280u 50u ""
Pop $RadioButtonLabel1
${if} $installMode == "all"
SendMessage $MultiUser.InstallModePage.AllUsers ${BM_SETCHECK} ${BST_CHECKED} 0 ; set as default
SendMessage $MultiUser.InstallModePage.AllUsers ${BM_CLICK} 0 0 ; trigger click event
${else}
SendMessage $MultiUser.InstallModePage.CurrentUser ${BM_SETCHECK} ${BST_CHECKED} 0 ; set as default
SendMessage $MultiUser.InstallModePage.CurrentUser ${BM_CLICK} 0 0 ; trigger click event
${endif}
!insertmacro MUI_PAGE_FUNCTION_CUSTOM SHOW
nsDialogs::Show
FunctionEnd
Function "${UNINSTALLER_FUNCPREFIX}${LEAVE}"
SendMessage $MultiUser.InstallModePage.AllUsers ${BM_GETCHECK} 0 0 $MultiUser.InstallModePage.ReturnValue
${if} $MultiUser.InstallModePage.ReturnValue = ${BST_CHECKED}
${IfNot} ${UAC_IsAdmin}
ShowWindow $HWNDPARENT ${SW_HIDE}
!insertmacro UAC_RunElevated
${Switch} $0
${Case} 0
${If} $1 = 1
Quit ;we are the outer process, the inner process has done its work (ExitCode is $2), we are done
${EndIf}
${If} $1 = 3 ;RunAs completed successfully, but with a non-admin user
${OrIf} $2 = 0x666666 ;our special return, the new process was not admin after all
MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "$(loginWithAdminAccount)"
${EndIf}
${Break}
${Case} 1223 ;user aborted
;MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "This option requires admin privileges, aborting!"
;Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons
${Break}
${Case} 1062
MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Logon service not running, aborting!" ; "Unable to elevate, Secondary Logon service not running!"
;Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons
${Break}
${Default}
MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Unable to elevate, error $0"
;Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons
${Break}
${EndSwitch}
ShowWindow $HWNDPARENT ${SW_SHOW}
BringToFront
Abort
${else}
!insertmacro setInstallModePerAllUsers
${endif}
${else}
!insertmacro setInstallModePerUser
${endif}
!insertmacro MUI_PAGE_FUNCTION_CUSTOM LEAVE
FunctionEnd
Function "${UNINSTALLER_FUNCPREFIX}InstModeChange"
pop $1
nsDialogs::GetUserData $1
pop $1
GetDlgItem $0 $hwndParent 1 ; get item 1 (next button) at parent window, store in $0 - (0 is back, 1 is next .. what about CANCEL? http://nsis.sourceforge.net/Buttons_Header )
StrCpy $7 ""
${if} "$1" == "0" ; current user
${if} $hasPerUserInstallation == "1"
!ifndef BUILD_UNINSTALLER
StrCpy $7 "$(perUserInstallExists)($perUserInstallationFolder)$\r$\n$(reinstallUpgrade)"
!else
StrCpy $7 "$(perUserInstall)($perUserInstallationFolder)$\r$\n$(uninstall)"
!endif
${else}
StrCpy $7 "$(freshInstallForCurrent)"
${endif}
SendMessage $0 ${BCM_SETSHIELD} 0 0 ; hide SHIELD
${else} ; all users
${if} $hasPerMachineInstallation == "1"
!ifndef BUILD_UNINSTALLER
StrCpy $7 "$(perMachineInstallExists)($perMachineInstallationFolder)$\r$\n$(reinstallUpgrade)"
!else
StrCpy $7 "$(perMachineInstall)($perMachineInstallationFolder)$\r$\n$(uninstall)"
!endif
${else}
StrCpy $7 "$(freshInstallForAll)"
${endif}
${ifNot} ${UAC_IsAdmin}
StrCpy $7 "$7"
SendMessage $0 ${BCM_SETSHIELD} 0 1 ; display SHIELD
${else}
SendMessage $0 ${BCM_SETSHIELD} 0 0 ; hide SHIELD
${endif}
${endif}
SendMessage $RadioButtonLabel1 ${WM_SETTEXT} 0 "STR:$7"
FunctionEnd
!macroend

View File

@ -0,0 +1,19 @@
!ifndef BUILD_UNINSTALLER
!ifmacrodef licensePage
!insertmacro skipPageIfUpdated
!insertmacro licensePage
!endif
!endif
!insertmacro MUI_PAGE_INSTFILES
!ifdef BUILD_UNINSTALLER
!insertmacro MUI_UNPAGE_INSTFILES
!endif
!macro initMultiUser
!ifdef INSTALL_MODE_PER_ALL_USERS
!insertmacro setInstallModePerAllUsers
!else
!insertmacro setInstallModePerUser
!endif
!macroend

View File

@ -0,0 +1,87 @@
!include "common.nsh"
!include "extractAppPackage.nsh"
# https://github.com/electron-userland/electron-builder/issues/3972#issuecomment-505171582
CRCCheck off
WindowIcon Off
AutoCloseWindow True
RequestExecutionLevel ${REQUEST_EXECUTION_LEVEL}
Function .onInit
!ifndef SPLASH_IMAGE
SetSilent silent
!endif
!insertmacro check64BitAndSetRegView
FunctionEnd
Function .onGUIInit
InitPluginsDir
!ifdef SPLASH_IMAGE
File /oname=$PLUGINSDIR\splash.bmp "${SPLASH_IMAGE}"
BgImage::SetBg $PLUGINSDIR\splash.bmp
BgImage::Redraw
!endif
FunctionEnd
Section
!ifdef SPLASH_IMAGE
HideWindow
!endif
StrCpy $INSTDIR "$TEMP\${UNPACK_DIR_NAME}"
RMDir /r $INSTDIR
SetOutPath $INSTDIR
!ifdef APP_DIR_64
!ifdef APP_DIR_ARM64
!ifdef APP_DIR_32
${if} ${IsNativeARM64}
File /r "${APP_DIR_ARM64}\*.*"
${elseif} ${RunningX64}
File /r "${APP_DIR_64}\*.*"
${else}
File /r "${APP_DIR_32}\*.*"
${endIf}
!else
${if} ${IsNativeARM64}
File /r "${APP_DIR_ARM64}\*.*"
${else}
File /r "${APP_DIR_64}\*.*"
{endIf}
!endif
!else
!ifdef APP_DIR_32
${if} ${RunningX64}
File /r "${APP_DIR_64}\*.*"
${else}
File /r "${APP_DIR_32}\*.*"
${endIf}
!else
File /r "${APP_DIR_64}\*.*"
!endif
!endif
!else
!ifdef APP_DIR_32
File /r "${APP_DIR_32}\*.*"
!else
!insertmacro extractEmbeddedAppPackage
!endif
!endif
System::Call 'Kernel32::SetEnvironmentVariable(t, t)i ("PORTABLE_EXECUTABLE_DIR", "$EXEDIR").r0'
System::Call 'Kernel32::SetEnvironmentVariable(t, t)i ("PORTABLE_EXECUTABLE_FILE", "$EXEPATH").r0'
System::Call 'Kernel32::SetEnvironmentVariable(t, t)i ("PORTABLE_EXECUTABLE_APP_FILENAME", "${APP_FILENAME}").r0'
${StdUtils.GetAllParameters} $R0 0
!ifdef SPLASH_IMAGE
BgImage::Destroy
!endif
ExecWait "$INSTDIR\${APP_EXECUTABLE_FILENAME} $R0" $0
SetErrorLevel $0
SetOutPath $PLUGINSDIR
RMDir /r $INSTDIR
SectionEnd

View File

@ -0,0 +1,36 @@
It is developer documentation. See [user documentation](https://electron.build/configuration/nsis).
http://www.mathiaswestin.net/2012/09/how-to-make-per-user-installation-with.html
https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx#FOLDERID_UserProgramFiles
https://github.com/Drizin/NsisMultiUser
NSIS vs Inno Setup — it is not easy to choose because both are far from ideal, e.g. inno also doesn't have built-in per-user installation implementation — http://stackoverflow.com/questions/34330668/inno-setup-custom-dialog-with-per-user-or-per-machine-installation.
http://stackoverflow.com/questions/2565215/checking-if-the-application-is-running-in-nsis-before-uninstalling
One-click installer: http://forums.winamp.com/showthread.php?t=300479
# GUID
See [docs](https://electron.build/configuration/nsis).
We use UUID v5 to generate sha-1 name-based UUID.
http://stackoverflow.com/questions/3029994/convert-uri-to-guid
https://alexandrebrisebois.wordpress.com/2013/11/14/create-predictable-guids-for-your-windows-azure-table-storage-entities/
https://github.com/Squirrel/Squirrel.Windows/pull/658
# Compression
NSIS LZMA compression is slower and worse compared to external `7za` compression. Slower because `7za` is multi-threaded, worse because LZMA codec implementation is outdated and BCJ2 filter is not enabled.
Difference for test app — 4 MB (before: 36.3 after: 32.8).
And compression time is also greatly reduced.
Since NSIS is awesome, no disadvantages in our approach — [compression is disabled](http://nsis.sourceforge.net/Reference/SetCompress) before `File /oname=app.7z "${APP_ARCHIVE}"` and enabled after (it is the reasons why `SOLID` compression is not used).
So, opposite to Squirrel.Windows, archive is not twice compressed.
So, in your custom NSIS scripts you should not use any compression instructions. Only `SetCompress` if you need to disable compression for already archived file.

View File

@ -0,0 +1,110 @@
Function un.onInit
!insertmacro check64BitAndSetRegView
${IfNot} ${Silent}
!ifdef ONE_CLICK
MessageBox MB_OKCANCEL "$(areYouSureToUninstall)" IDOK +2
Quit
# one-click installer executes uninstall section in the silent mode, but we must show message dialog if silent mode was not explicitly set by user (using /S flag)
!insertmacro CHECK_APP_RUNNING
SetSilent silent
!endif
${endIf}
!insertmacro initMultiUser
!ifmacrodef customUnInit
!insertmacro customUnInit
!endif
FunctionEnd
Section "un.install"
!ifndef ONE_CLICK
# for assisted installer we check it here to show progress
!insertmacro CHECK_APP_RUNNING
!endif
!insertmacro setLinkVars
${ifNot} ${isKeepShortcuts}
WinShell::UninstAppUserModelId "${APP_ID}"
!ifndef DO_NOT_CREATE_DESKTOP_SHORTCUT
WinShell::UninstShortcut "$oldDesktopLink"
Delete "$oldDesktopLink"
!endif
!ifndef DO_NOT_CREATE_START_MENU_SHORTCUT
WinShell::UninstShortcut "$oldStartMenuLink"
Delete "$oldStartMenuLink"
ReadRegStr $R1 SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" MenuDirectory
${ifNot} $R1 == ""
RMDir "$SMPROGRAMS\$R1"
${endIf}
!endif
${endIf}
# refresh the desktop
System::Call 'shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
!ifmacrodef unregisterFileAssociations
!insertmacro unregisterFileAssociations
!endif
# delete the installed files
!ifmacrodef customRemoveFiles
!insertmacro customRemoveFiles
!else
RMDir /r $INSTDIR
!endif
Var /GLOBAL isDeleteAppData
StrCpy $isDeleteAppData "0"
ClearErrors
${GetParameters} $R0
${GetOptions} $R0 "--delete-app-data" $R1
${if} ${Errors}
!ifdef DELETE_APP_DATA_ON_UNINSTALL
${ifNot} ${isUpdated}
StrCpy $isDeleteAppData "1"
${endif}
!endif
${else}
StrCpy $isDeleteAppData "1"
${endIf}
${if} $isDeleteAppData == "1"
# electron always uses per user app data
${if} $installMode == "all"
SetShellVarContext current
${endif}
RMDir /r "$APPDATA\${APP_FILENAME}"
!ifdef APP_PRODUCT_FILENAME
RMDir /r "$APPDATA\${APP_PRODUCT_FILENAME}"
!endif
# electron use package.json name for cache,indexdb etc.
!ifdef APP_PACKAGE_NAME
RMDir /r "$APPDATA\${APP_PACKAGE_NAME}"
!endif
${if} $installMode == "all"
SetShellVarContext all
${endif}
${endif}
DeleteRegKey SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY}"
!ifdef UNINSTALL_REGISTRY_KEY_2
DeleteRegKey SHELL_CONTEXT "${UNINSTALL_REGISTRY_KEY_2}"
!endif
DeleteRegKey SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}"
!ifmacrodef customUnInstall
!insertmacro customUnInstall
!endif
!ifdef ONE_CLICK
!insertmacro quitSuccess
!endif
SectionEnd

View File

@ -0,0 +1,148 @@
base: core18
grade: stable
confinement: strict
parts:
launch-scripts:
plugin: dump
source: scripts
gnome-platform-empty-dirs:
plugin: nil
override-build: >
mkdir -p "$SNAPCRAFT_PART_INSTALL/data-dir/themes"
mkdir -p "$SNAPCRAFT_PART_INSTALL/data-dir/icons"
mkdir -p "$SNAPCRAFT_PART_INSTALL/data-dir/sounds"
mkdir $SNAPCRAFT_PART_INSTALL/gnome-platform
app-files:
plugin: dump
source: app
organize:
'*': app/
stage:
- -app/chrome-sandbox
- -LICENSES.chromium.html
app:
plugin: "nil"
# cd ~ && rm -rf ~/squashfs-root && unsquashfs /media/psf/ramdisk/electron-builder-test/dist/__snap-x64/se-wo-template_1.1.0_amd64.snap
# comm -12 <(ls ~/squashfs-root/usr/lib/x86_64-linux-gnu/) <(ls /snap/gnome-3-28-1804/current/usr/lib/x86_64-linux-gnu/) > /media/psf/Home/f.txt
# run snap-exclude-list.js
stage:
- '-usr/lib/python*'
- '-usr/bin/python*'
- '-var/lib/ucf'
- '-usr/include'
- '-usr/lib/X11'
- '-usr/share'
- '-usr/sbin'
- '-usr/bin'
- "-usr/lib/*/libicudata.*"
- "-usr/lib/*/libicui18n.*"
- "-usr/lib/*/libgtk-*"
- "-usr/lib/*/libgdk-*"
- "-usr/lib/*/glib-*"
- "-usr/lib/*/gtk-*"
- "-usr/lib/*/gdk-*"
- "-usr/lib/*/krb5"
- "-usr/lib/systemd"
- "-usr/lib/glib-networking"
- "-usr/lib/dconf"
- "-usr/lib/*/avahi"
- "-usr/lib/*/gio"
- "-usr/lib/*/libatk*"
- "-usr/lib/*/libatspi*"
- "-usr/lib/*/libavahi*"
- "-usr/lib/*/libcairo*"
- "-usr/lib/*/libcolordprivate*"
- "-usr/lib/*/libcolord*"
- "-usr/lib/*/libcroco*"
- "-usr/lib/*/libcups*"
- "-usr/lib/*/libdatrie*"
- "-usr/lib/*/libdconf*"
- "-usr/lib/*/libepoxy*"
- "-usr/lib/*/libexpatw*"
- "-usr/lib/*/libffi*"
- "-usr/lib/*/libfontconfig*"
- "-usr/lib/*/libfreetype*"
- "-usr/lib/*/libgdk_pixbuf*"
- "-usr/lib/*/libgdk_pixbuf_xlib*"
- "-usr/lib/*/libgio*"
- "-usr/lib/*/libglib*"
- "-usr/lib/*/libgmodule*"
- "-usr/lib/*/libgmp*"
- "-usr/lib/*/libgnutls*"
- "-usr/lib/*/libgobject*"
- "-usr/lib/*/libgraphite2*"
- "-usr/lib/*/libgssapi_krb5*"
- "-usr/lib/*/libgthread*"
- "-usr/lib/*/libharfbuzz*"
- "-usr/lib/*/libhogweed*"
- "-usr/lib/*/libicuio*"
- "-usr/lib/*/libicutest*"
- "-usr/lib/*/libicutu*"
- "-usr/lib/*/libicuuc*"
- "-usr/lib/*/libidn2*"
- "-usr/lib/*/libjbig*"
- "-usr/lib/*/libjpeg*"
- "-usr/lib/*/libjson*"
- "-usr/lib/*/libk5crypto*"
- "-usr/lib/*/libkrb5*"
- "-usr/lib/*/libkrb5support*"
- "-usr/lib/*/liblcms2*"
- "-usr/lib/*/libnettle*"
- "-usr/lib/*/libp11*"
- "-usr/lib/*/libpango*"
- "-usr/lib/*/libpangocairo*"
- "-usr/lib/*/libpangoft2*"
- "-usr/lib/*/libpixman*"
- "-usr/lib/*/libpng16*"
- "-usr/lib/*/libproxy*"
- "-usr/lib/*/librest*"
- "-usr/lib/*/librsvg*"
- "-usr/lib/*/libsecret*"
- "-usr/lib/*/libsoup*"
- "-usr/lib/*/libsqlite3*"
- "-usr/lib/*/libtasn1*"
- "-usr/lib/*/libthai*"
- "-usr/lib/*/libtiff*"
- "-usr/lib/*/libunistring*"
- "-usr/lib/*/libwayland*"
- "-usr/lib/*/libX11*"
- "-usr/lib/*/libXau*"
- "-usr/lib/*/libxcb.so*"
- "-usr/lib/*/libxcb-dri2*"
- "-usr/lib/*/libxcb-dri3*"
- "-usr/lib/*/libxcb-glx*"
- "-usr/lib/*/libxcb-present*"
- "-usr/lib/*/libxcb-render*"
- "-usr/lib/*/libxcb-shm*"
- "-usr/lib/*/libxcb-sync*"
- "-usr/lib/*/libxcb-xfixes*"
- "-usr/lib/*/libXcomposite*"
- "-usr/lib/*/libXcursor*"
- "-usr/lib/*/libXdamage*"
- "-usr/lib/*/libXdmcp*"
- "-usr/lib/*/libXext*"
- "-usr/lib/*/libXfixes*"
- "-usr/lib/*/libXinerama*"
- "-usr/lib/*/libXi*"
- "-usr/lib/*/libxkbcommon*"
- "-usr/lib/*/libxml2*"
- "-usr/lib/*/libXrandr*"
- "-usr/lib/*/libXrender*"
plugs:
gnome-3-28-1804:
interface: content
target: $SNAP/gnome-platform
default-provider: gnome-3-28-1804
gtk-3-themes:
interface: content
target: $SNAP/data-dir/themes
default-provider: gtk-common-themes
icon-themes:
interface: content
target: $SNAP/data-dir/icons
default-provider: gtk-common-themes
sound-themes:
interface: content
target: $SNAP/data-dir/sounds
default-provider: gtk-common-themes