├── src ├── Bootstrap │ ├── 0install.exe.ignore │ ├── chocolateyUninstall.ps1 │ ├── chocolateyInstall.ps1 │ ├── _Namespace.md │ ├── Program.cs │ ├── VERIFICATION.txt │ ├── ConfigExtensions.cs │ ├── CliBootstrapHandler.cs │ ├── App.config │ ├── IBootstrapHandler.cs │ ├── Bootstrap.csproj │ ├── Chocolatey.nuspec │ ├── ExitCode.cs │ └── BootstrapConfig.ini ├── Central.WinForms │ ├── Logo_150.png │ ├── Logo_70.png │ ├── Resources │ │ ├── AppAdded.png │ │ ├── AppIcon.png │ │ ├── ArrowUp.png │ │ ├── ArrowDown.png │ │ ├── ArrowRight.png │ │ ├── AppCandidate.png │ │ └── AppIntegrated.png │ ├── _Namespace.md │ ├── ZeroInstall.VisualElementsManifest.xml │ ├── AppTileStatus.cs │ ├── Properties │ │ └── AppResources.cs │ ├── MinimalTaskHandler.cs │ ├── Program.cs │ ├── CommandUtils.cs │ ├── PortableCreatorDialog.cs │ ├── Central.WinForms.csproj │ ├── IntroDialog.zh.resx │ ├── IntroDialog.ja.resx │ ├── IntroDialog.ko.resx │ ├── IntroDialog.fr.resx │ ├── IntroDialog.el.resx │ ├── IntroDialog.tr.resx │ ├── IntroDialog.de.resx │ ├── IntroDialog.it.resx │ ├── IntroDialog.cs.resx │ ├── IntroDialog.pt-BR.resx │ ├── IntroDialog.id.resx │ ├── IntroDialog.nl.resx │ ├── IntroDialog.es.resx │ ├── IntroDialog.pl.resx │ ├── IntroDialog.ru.resx │ ├── IntroDialog.ro.resx │ ├── IntroDialog.pt-PT.resx │ └── AppDropDown.cs ├── Bootstrap.WinForms │ ├── SplashScreen.png │ ├── Program.cs │ ├── GlobalSuppressions.cs │ ├── App.config │ ├── zero-install.wsx │ ├── GuiBootstrapHandler.cs │ └── Bootstrap.WinForms.csproj ├── Alias.Cli │ ├── _Namespace.md │ ├── Program.cs │ ├── Alias.Cli.csproj │ └── GlobalSuppressions.cs ├── Launcher.Cli │ ├── _Namespace.md │ ├── Program.cs │ └── Launcher.Cli.csproj ├── Store.Management.Cli │ ├── _Namespace.md │ ├── Program.cs │ └── Store.Management.Cli.csproj ├── Store.Service │ ├── _Namespace.md │ ├── GlobalSuppressions.cs │ ├── Program.cs │ ├── StoreServiceInstaller.cs │ ├── Store.Service.csproj │ ├── app.manifest │ ├── StoreService.Designer.cs │ └── Properties │ │ ├── Resources.zh.resx │ │ ├── Resources.ko.resx │ │ ├── Resources.ja.resx │ │ ├── Resources.tr.resx │ │ ├── Resources.pt-BR.resx │ │ ├── Resources.id.resx │ │ ├── Resources.cs.resx │ │ ├── Resources.pl.resx │ │ └── Resources.ru.resx ├── Commands.WinForms │ ├── _Namespace.md │ ├── Program.cs │ ├── GlobalSuppressions.cs │ ├── FormUtils.cs │ ├── CommandUtils.cs │ ├── GuiCommandHandler.Form.cs │ ├── Commands.WinForms.csproj │ ├── CacheNodeWithContextMenu.cs │ └── FeedSearchDialog.cs ├── nuget.config ├── ZeroInstall.Windows.slnx ├── App.config ├── app.manifest ├── Directory.Build.props └── build.ps1 ├── icon.ico ├── icon.png ├── tests ├── search.ps1 ├── store-audit.ps1 ├── store-optimise.ps1 ├── run.ps1 ├── download.ps1 ├── update.ps1 ├── select.ps1 ├── export.ps1 ├── store-dirs.ps1 ├── catalog.ps1 ├── trust.ps1 ├── config.ps1 ├── desktop-integration.au3 ├── feed-dirs.ps1 ├── apps.ps1 ├── store.ps1 └── desktop-integration.ps1 ├── .gitattributes ├── .config └── dotnet-tools.json ├── .gitignore ├── GitVersion.yml ├── renovate.json ├── 0install.ps1 ├── appveyor.yml ├── .github └── workflows │ ├── translate-upload.yml │ ├── translate.yml │ └── release.yml ├── 0install.sh ├── 0install-win.xml.template ├── test.ps1 ├── .tx └── config └── README.md /src/Bootstrap/0install.exe.ignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/icon.ico -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/icon.png -------------------------------------------------------------------------------- /tests/search.ps1: -------------------------------------------------------------------------------- 1 | 0install search vlc 2 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Disable linebreak normalization 2 | * -text 3 | 4 | # Language-aware diff 5 | *.cs diff=csharp 6 | -------------------------------------------------------------------------------- /tests/store-audit.ps1: -------------------------------------------------------------------------------- 1 | 0install store audit 2 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 3 | -------------------------------------------------------------------------------- /src/Central.WinForms/Logo_150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/src/Central.WinForms/Logo_150.png -------------------------------------------------------------------------------- /src/Central.WinForms/Logo_70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/src/Central.WinForms/Logo_70.png -------------------------------------------------------------------------------- /src/Bootstrap.WinForms/SplashScreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/src/Bootstrap.WinForms/SplashScreen.png -------------------------------------------------------------------------------- /src/Bootstrap/chocolateyUninstall.ps1: -------------------------------------------------------------------------------- 1 | 0install self remove --batch 2 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 3 | -------------------------------------------------------------------------------- /src/Alias.Cli/_Namespace.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: ZeroInstall.Alias.Cli 3 | summary: *content 4 | --- 5 | A shortcut for '0install add-alias'. 6 | -------------------------------------------------------------------------------- /src/Central.WinForms/Resources/AppAdded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/src/Central.WinForms/Resources/AppAdded.png -------------------------------------------------------------------------------- /src/Central.WinForms/Resources/AppIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/src/Central.WinForms/Resources/AppIcon.png -------------------------------------------------------------------------------- /src/Central.WinForms/Resources/ArrowUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/src/Central.WinForms/Resources/ArrowUp.png -------------------------------------------------------------------------------- /src/Launcher.Cli/_Namespace.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: ZeroInstall.Launcher.Cli 3 | summary: *content 4 | --- 5 | A shortcut for '0install run'. 6 | -------------------------------------------------------------------------------- /tests/store-optimise.ps1: -------------------------------------------------------------------------------- 1 | 0install-win store optimise --batch | Out-Null 2 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 3 | -------------------------------------------------------------------------------- /src/Central.WinForms/Resources/ArrowDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/src/Central.WinForms/Resources/ArrowDown.png -------------------------------------------------------------------------------- /src/Central.WinForms/Resources/ArrowRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/src/Central.WinForms/Resources/ArrowRight.png -------------------------------------------------------------------------------- /src/Central.WinForms/Resources/AppCandidate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/src/Central.WinForms/Resources/AppCandidate.png -------------------------------------------------------------------------------- /src/Central.WinForms/Resources/AppIntegrated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0install/0install-win/HEAD/src/Central.WinForms/Resources/AppIntegrated.png -------------------------------------------------------------------------------- /src/Store.Management.Cli/_Namespace.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: ZeroInstall.Store.Management.Cli 3 | summary: *content 4 | --- 5 | A shortcut for '0install store'. 6 | -------------------------------------------------------------------------------- /tests/run.ps1: -------------------------------------------------------------------------------- 1 | 0install run https://apps.0install.net/devel/terraform.xml --help | Out-Null 2 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 3 | -------------------------------------------------------------------------------- /tests/download.ps1: -------------------------------------------------------------------------------- 1 | 0install-win download --batch https://apps.0install.net/gui/naps2.xml | Out-Null 2 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 3 | -------------------------------------------------------------------------------- /src/Bootstrap/chocolateyInstall.ps1: -------------------------------------------------------------------------------- 1 | . "$PSScriptRoot\0install.exe" --version=1.0.0-pre self deploy --machine --batch 2 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 3 | -------------------------------------------------------------------------------- /src/Store.Service/_Namespace.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: ZeroInstall.Store.Service 3 | summary: *content 4 | --- 5 | Windows service for managing a Zero Install implementation cache shared between all users. 6 | -------------------------------------------------------------------------------- /tests/update.ps1: -------------------------------------------------------------------------------- 1 | 0install update --batch https://apps.0install.net/gui/notepad-plus-plus.xml | Out-Null 2 | if ((0, 1) -NotContains $LASTEXITCODE) {throw "Exit Code: $LASTEXITCODE"} # Expect OK or NoChanges 3 | -------------------------------------------------------------------------------- /src/Bootstrap/_Namespace.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: ZeroInstall 3 | summary: *content 4 | --- 5 | Code for bootstrapping Zero Install, i.e., downloading and running a full version of Zero Install using a small embedded version. 6 | -------------------------------------------------------------------------------- /src/Commands.WinForms/_Namespace.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: ZeroInstall.Commands.WinForms 3 | summary: *content 4 | --- 5 | A WinForms-based GUI for Zero Install, for installing and launching applications, managing caches, etc.. 6 | -------------------------------------------------------------------------------- /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "wix": { 6 | "version": "6.0.2", 7 | "commands": [ 8 | "wix" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Bootstrap/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | ProgramUtils.Init(); 5 | 6 | using var handler = new CliBootstrapHandler(); 7 | return (int)ProgramUtils.Run(args, handler); 8 | -------------------------------------------------------------------------------- /src/Central.WinForms/_Namespace.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: ZeroInstall.Central.WinForms 3 | summary: *content 4 | --- 5 | A WinForms-based GUI for Zero Install, for discovering and installing new applications, managing and launching installed applications, etc.. 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.user 2 | *.bak 3 | *.a.resx 4 | *.o.resx 5 | 6 | # Caches 7 | /src/.vs/ 8 | /src/.idea/ 9 | /src/_ReSharper.*/ 10 | /src/*/obj/ 11 | /src/*/bin/ 12 | 13 | # Output 14 | /artifacts/ 15 | /0install-win-*.xml 16 | /0install-win-*.tar.gz 17 | 18 | # Embedded content 19 | /src/Bootstrap/content/* 20 | -------------------------------------------------------------------------------- /tests/select.ps1: -------------------------------------------------------------------------------- 1 | 0install select https://apps.0install.net/devel/terraform.xml 2 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 3 | 4 | $output = 0install list 5 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 6 | if ($output -NotContains "https://apps.0install.net/devel/terraform.xml") { throw "Wrong output" } 7 | -------------------------------------------------------------------------------- /src/Central.WinForms/ZeroInstall.VisualElementsManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | -------------------------------------------------------------------------------- /src/Launcher.Cli/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using ZeroInstall.Commands; 5 | using ZeroInstall.Commands.Basic; 6 | 7 | ProgramUtils.Init(); 8 | 9 | using var handler = new CliCommandHandler(); 10 | return (int)ProgramUtils.Run("0install", [Run.Name, ..args], handler); 11 | -------------------------------------------------------------------------------- /src/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Alias.Cli/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using ZeroInstall.Commands; 5 | using ZeroInstall.Commands.Desktop; 6 | 7 | ProgramUtils.Init(); 8 | 9 | using var handler = new CliCommandHandler(); 10 | return (int)ProgramUtils.Run("0install", [AddAlias.Name, ..args], handler); 11 | -------------------------------------------------------------------------------- /tests/export.ps1: -------------------------------------------------------------------------------- 1 | 0install export https://apps.0install.net/devel/cloc.xml $env:TEMP\0install-export 2 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 3 | 4 | & $env:TEMP\0install-export\import.cmd 5 | if ((0, 1) -NotContains $LASTEXITCODE) {throw "Exit Code: $LASTEXITCODE"} # Expect OK or NoChanges 6 | 7 | Remove-Item -Recurse $env:TEMP\0install-export 8 | -------------------------------------------------------------------------------- /src/Store.Management.Cli/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using ZeroInstall.Commands; 5 | using ZeroInstall.Commands.Basic; 6 | 7 | ProgramUtils.Init(); 8 | 9 | using var handler = new CliCommandHandler(); 10 | return (int)ProgramUtils.Run("0install", [StoreMan.Name, ..args], handler); 11 | -------------------------------------------------------------------------------- /src/Bootstrap/VERIFICATION.txt: -------------------------------------------------------------------------------- 1 | VERIFICATION 2 | Verification is intended to assist the Chocolatey moderators and community 3 | in verifying that this package's contents are trustworthy. 4 | 5 | This package is published by the Zero Install Project itself. The binary 6 | 0install.exe is identical to the file that can be downloaded from: 7 | https://get.0install.net/0install.exe 8 | -------------------------------------------------------------------------------- /tests/store-dirs.ps1: -------------------------------------------------------------------------------- 1 | 0install store add-dir $env:TEMP\implementations 2 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 3 | 4 | $output = 0install store list --batch 5 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 6 | if ($output -NotContains "ReadWrite: $env:TEMP\implementations") { throw "Wrong output" } 7 | 8 | 0install store remove-dir $env:TEMP\implementations 9 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 10 | -------------------------------------------------------------------------------- /tests/catalog.ps1: -------------------------------------------------------------------------------- 1 | 0install catalog refresh 2 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 3 | 4 | 0install catalog search vlc 5 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 6 | 7 | 0install catalog add https://apps.0install.net/0install/catalog.xml 8 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 9 | 10 | 0install catalog remove https://apps.0install.net/0install/catalog.xml 11 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 12 | -------------------------------------------------------------------------------- /tests/trust.ps1: -------------------------------------------------------------------------------- 1 | 0install trust remove 88C8A1F375928691D7365C0259AA3927C24E4E1E apps.0install.net 2 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 3 | 4 | Write-Output "Error expected here:" 5 | 0install select --refresh --batch https://apps.0install.net/devel/terraform.xml 6 | if ($LASTEXITCODE -ne 27) {throw "Exit Code: $LASTEXITCODE"} 7 | 8 | 0install trust add 88C8A1F375928691D7365C0259AA3927C24E4E1E apps.0install.net 9 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 10 | -------------------------------------------------------------------------------- /src/Bootstrap/ConfigExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using ZeroInstall.Store.Configuration; 5 | 6 | namespace ZeroInstall; 7 | 8 | public static class ConfigExtensions 9 | { 10 | /// 11 | /// Reads options bundled together with the . 12 | /// 13 | public static void ReadFromBootstrapConfig(this Config config) 14 | => config.ReadFrom(BootstrapConfig.Instance.IniData); 15 | } 16 | -------------------------------------------------------------------------------- /GitVersion.yml: -------------------------------------------------------------------------------- 1 | mode: ContinuousDeployment 2 | 3 | # Generate 0install-compatible version numbers 4 | branches: 5 | # Mainline branches 6 | main: 7 | tag: rc-pre 8 | develop: 9 | tag: pre 10 | increment: patch 11 | 12 | # Stabilization branches 13 | release: 14 | tag: rc 15 | hotfix: 16 | tag: rc 17 | 18 | # Topic branches 19 | feature: 20 | tag: pre-pre 21 | pull-request: 22 | tag: pre-pre 23 | fallback: 24 | source-branches: [main] 25 | regex: ^(?!main|master|develop|release|hotfix|feature|pull|pr) 26 | tag: pre-pre 27 | -------------------------------------------------------------------------------- /tests/config.ps1: -------------------------------------------------------------------------------- 1 | 0install config 2 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 3 | 4 | 0install config self_update_uri 5 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 6 | 7 | 0install config self_update_uri '""' 8 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 9 | 10 | Write-Output "Error expected here:" 11 | 0install self update 12 | if ($LASTEXITCODE -eq 0) { throw "Exit Code: $LASTEXITCODE" } 13 | 14 | 0install config self_update_uri default 15 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 16 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:base", ":disableDependencyDashboard"], 4 | "ignoreDeps": ["System.Resources.Extensions"], 5 | "packageRules": [ 6 | { 7 | "matchPackagePatterns": ["^Generator\\.Equals"], 8 | "groupName": "Generator.Equals", 9 | "automerge": true, 10 | "automergeType": "branch" 11 | }, 12 | { 13 | "matchPackagePatterns": ["wix", "ILRepack", "AeroWizard"], 14 | "automerge": true, 15 | "automergeType": "branch" 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/desktop-integration.au3: -------------------------------------------------------------------------------- 1 | Run("ZeroInstall") 2 | 3 | ;Search for VLC in catalog 4 | WinWaitActive("Zero Install") 5 | Send("{RIGHT}{TAB}VLC") 6 | 7 | ;Integrate VLC 8 | Send("{TAB}{TAB}{ENTER}{ENTER}") 9 | Opt("WinTitleMatchMode", 2) 10 | WinWaitActive("VLC media player") 11 | Send("{ENTER}") 12 | 13 | ;Ensure menu entry was created 14 | If Not FileExists(EnvGet("appdata") & "\Microsoft\Windows\Start Menu\Programs\AudioVideo\VLC media player.lnk") Then 15 | Exit(1) 16 | EndIf 17 | 18 | ;Remove VLC 19 | WinWaitActive("Zero Install") 20 | Send("{ENTER}{TAB}{ENTER}") 21 | 22 | WinClose("Zero Install") 23 | -------------------------------------------------------------------------------- /tests/feed-dirs.ps1: -------------------------------------------------------------------------------- 1 | 0install add-feed https://apps.0install.net/0install/0install.xml https://apps.0install.net/0install/0install-win.xml 2 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 3 | 4 | $output = 0install list-feeds https://apps.0install.net/0install/0install.xml --batch 5 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 6 | if ($output -NotContains "https://apps.0install.net/0install/0install-win.xml") { throw "Wrong output" } 7 | 8 | 0install remove-feed https://apps.0install.net/0install/0install.xml https://apps.0install.net/0install/0install-win.xml 9 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 10 | -------------------------------------------------------------------------------- /src/Commands.WinForms/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using NanoByte.Common.Native; 5 | using ZeroInstall.Commands; 6 | using ZeroInstall.Commands.WinForms; 7 | 8 | ProgramUtils.Init(); 9 | WindowsUtils.SetCurrentProcessAppID(ZeroInstallInstance.IsIntegrated ? "ZeroInstall" : "ZeroInstall.NotIntegrated"); 10 | Application.EnableVisualStyles(); 11 | Application.SetCompatibleTextRenderingDefault(false); 12 | ErrorReportForm.SetupMonitoring(new("https://0install.de/error-report/")); 13 | 14 | using var handler = new GuiCommandHandler(); 15 | return (int)ProgramUtils.Run("0install-win", args, handler); 16 | -------------------------------------------------------------------------------- /src/Bootstrap.WinForms/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | ProgramUtils.Init(); 5 | Application.EnableVisualStyles(); 6 | Application.SetCompatibleTextRenderingDefault(false); 7 | 8 | ErrorReportForm.SetupMonitoring(new("https://0install.de/error-report/")); 9 | 10 | using var handler = new GuiBootstrapHandler(); 11 | 12 | try 13 | { 14 | return (int)ProgramUtils.Run(args, handler); 15 | } 16 | #region Error handling 17 | catch (Win32Exception ex) // Commonly caused by GDI object exhaustion 18 | { 19 | Msg.Inform(null, ex.Message, MsgSeverity.Error); 20 | return -1; 21 | } 22 | #endregion 23 | -------------------------------------------------------------------------------- /src/Alias.Cli/Alias.Cli.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ZeroInstall.Alias.Cli 6 | 0alias 7 | A shortcut for '0install add-alias'. 8 | Exe 9 | ..\..\artifacts\$(Configuration)\ 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Launcher.Cli/Launcher.Cli.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ZeroInstall.Launcher.Cli 6 | 0launch 7 | A shorcut for '0install run'. 8 | Exe 9 | ..\..\artifacts\$(Configuration)\ 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Store.Service/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | // 6 | // To add a suppression to this file, right-click the message in the 7 | // Code Analysis results, point to "Suppress Message", and click 8 | // "In Suppression File". 9 | // You do not need to add suppressions to this file manually. 10 | 11 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2232:MarkWindowsFormsEntryPointsWithStaThread", Justification = "Does not show a GUI")] 12 | -------------------------------------------------------------------------------- /src/ZeroInstall.Windows.slnx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Commands.WinForms/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | // 6 | // To add a suppression to this file, right-click the message in the 7 | // Code Analysis results, point to "Suppress Message", and click 8 | // "In Suppression File". 9 | // You do not need to add suppressions to this file manually. 10 | 11 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2232:MarkWindowsFormsEntryPointsWithStaThread", Justification = "GUI is created on a different thread")] 12 | -------------------------------------------------------------------------------- /src/Bootstrap.WinForms/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | // 6 | // To add a suppression to this file, right-click the message in the 7 | // Code Analysis results, point to "Suppress Message", and click 8 | // "In Suppression File". 9 | // You do not need to add suppressions to this file manually. 10 | 11 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2232:MarkWindowsFormsEntryPointsWithStaThread", Justification = "GUI is created on a different thread")] 12 | -------------------------------------------------------------------------------- /src/Alias.Cli/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | // 6 | // To add a suppression to this file, right-click the message in the 7 | // Error List, point to "Suppress Message(s)", and click 8 | // "In Project Suppression File". 9 | // You do not need to add suppressions to this file manually. 10 | 11 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Alias", Scope = "namespace", Target = "ZeroInstall.Alias.Cli")] 12 | -------------------------------------------------------------------------------- /src/Bootstrap/CliBootstrapHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | namespace ZeroInstall; 5 | 6 | /// 7 | /// Informs the user about the progress of tasks and ask questions during the bootstrap process using console output. 8 | /// 9 | /// This class is thread-safe. 10 | public class CliBootstrapHandler : CliTaskHandler, IBootstrapHandler 11 | { 12 | /// 13 | public bool IsGui => false; 14 | 15 | /// 16 | public bool Background { get => false; set {} } 17 | 18 | /// 19 | public string? GetCustomStorePath(bool machineWide, string? currentPath) => currentPath; 20 | } 21 | -------------------------------------------------------------------------------- /0install.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | 3 | function Download-ZeroInstall { 4 | $dir = "$env:LOCALAPPDATA\0install.net\bootstrapper" 5 | $file = "$dir\0install.exe" 6 | if (!(Test-Path $file)) { 7 | mkdir -Force $dir | Out-Null 8 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Tls11,Tls12' 9 | Invoke-WebRequest "https://get.0install.net/0install.exe" -OutFile $file 10 | } 11 | return $file 12 | } 13 | 14 | function Run-ZeroInstall { 15 | if (Get-Command 0install -ErrorAction SilentlyContinue) { 16 | 0install @args | %{ "$_" } 17 | } else { 18 | . $(Download-ZeroInstall) @args | %{ "$_" } 19 | } 20 | } 21 | 22 | Run-ZeroInstall @args 23 | -------------------------------------------------------------------------------- /src/Store.Management.Cli/Store.Management.Cli.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ZeroInstall.Store.Management.Cli 6 | 0store 7 | Manages caches of Zero Install implementations via the command-line. 8 | Exe 9 | ..\..\artifacts\$(Configuration)\ 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Bootstrap/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Store.Service/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using System.ServiceProcess; 5 | using NanoByte.Common.Native; 6 | using ZeroInstall.Store.Service; 7 | 8 | // Encode installation path into mutex name to allow instance detection during updates 9 | string mutexName = "mutex-" + Locations.InstallBase.GetHashCode(); 10 | if (AppMutex.Probe(mutexName + "-update")) return 999; 11 | 12 | // NOTE: Do not block updater from starting because it will automatically stop service 13 | 14 | using var service = new StoreService(); 15 | if (args.Contains("--debug")) 16 | { 17 | service.Start(); 18 | Thread.Sleep(int.MaxValue); 19 | } 20 | else ServiceBase.Run([new StoreService()]); 21 | 22 | return 0; 23 | -------------------------------------------------------------------------------- /src/Commands.WinForms/FormUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using NanoByte.Common.Native; 5 | 6 | namespace ZeroInstall.Commands.WinForms; 7 | 8 | /// 9 | /// Provides extension methods for s. 10 | /// 11 | internal static class FormExtensions 12 | { 13 | /// 14 | /// Prevents the window from being pinned to the taskbar if the current Zero Install instance is not integrated into the desktop environment. 15 | /// 16 | public static void PreventPinningIfNotIntegrated(this Form form) 17 | { 18 | if (!ZeroInstallInstance.IsIntegrated) 19 | form.HandleCreated += delegate { WindowsTaskbar.PreventPinning(form.Handle); }; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Bootstrap.WinForms/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Store.Service/StoreServiceInstaller.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using System.Configuration.Install; 5 | using System.ServiceProcess; 6 | 7 | namespace ZeroInstall.Store.Service; 8 | 9 | /// 10 | /// Entry point used by InstallUtil.exe. 11 | /// 12 | [RunInstaller(true)] 13 | public class StoreServiceInstaller : Installer 14 | { 15 | public StoreServiceInstaller() 16 | { 17 | Installers.Add(new ServiceProcessInstaller {Account = ServiceAccount.LocalSystem}); 18 | Installers.Add(new ServiceInstaller 19 | { 20 | Description = "Manages a Zero Install implementation cache shared between all users.", 21 | DisplayName = "Zero Install Store Service", 22 | ServiceName = "0store-service", 23 | StartType = ServiceStartMode.Automatic 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Central.WinForms/AppTileStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using ZeroInstall.DesktopIntegration; 5 | 6 | namespace ZeroInstall.Central.WinForms; 7 | 8 | /// 9 | /// Describes the status of an application represented by an . 10 | /// 11 | /// 12 | public enum AppTileStatus 13 | { 14 | /// The state has not been set yet. 15 | Unset, 16 | 17 | /// The application is listed in a but not in the . 18 | Candidate, 19 | 20 | /// The application is listed in the but is null. 21 | Added, 22 | 23 | /// The application is listed in the and is set. 24 | Integrated 25 | } 26 | -------------------------------------------------------------------------------- /src/Store.Service/Store.Service.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ZeroInstall.Store.Service 6 | 0store-service 7 | Windows service for managing a Zero Install implementation cache shared between all users. 8 | WinExe 9 | ..\..\artifacts\$(Configuration)\ 10 | app.manifest 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | branches: 2 | except: [translate] 3 | 4 | image: Visual Studio 2022 5 | 6 | environment: 7 | IGNORE_NORMALISATION_GIT_HEAD_MOVE: '1' 8 | DOTNET_NOLOGO: '1' 9 | 10 | cache: 11 | - '%USERPROFILE%\.nuget\packages -> **\*.csproj,**\*.targets,**\*.props' 12 | 13 | before_build: 14 | - gitversion /verbosity quiet /output buildserver 15 | 16 | build_script: 17 | - powershell .\src\build.ps1 %GitVersion_NuGetVersion% 18 | 19 | test_script: 20 | - powershell .\test.ps1 -Purge 21 | - powershell .\test.ps1 -Deploy -Purge 22 | - powershell .\test.ps1 -Deploy -Machine -Purge 23 | - powershell .\test.ps1 -Deploy -Portable -Purge 24 | 25 | artifacts: 26 | - path: artifacts 27 | 28 | deploy: 29 | - provider: Webhook 30 | url: https://app.signpath.io/API/v1/0e70cf92-49a1-4427-a800-b6bc5b497936/Integrations/AppVeyor?ProjectSlug=win&SigningPolicySlug=release-signing 31 | authorization: 32 | secure: 1lrrvByUN3qR7P/QQN6XXy4LWmh8ls/veOESoeVffvyF4kOqo28JxoZtIxYOZZpAZKlbAv8tWQaLFZiUxXFHmA== 33 | on: 34 | appveyor_repo_tag: true 35 | -------------------------------------------------------------------------------- /src/Central.WinForms/Properties/AppResources.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | namespace ZeroInstall.Central.WinForms.Properties; 5 | 6 | /// 7 | /// Static preload of commonly used app-related resources. 8 | /// 9 | internal static class AppResources 10 | { 11 | public static readonly ScalableImage 12 | CandidateImage = new(ImageResources.AppCandidate), 13 | AddedImage = new(ImageResources.AppAdded), 14 | IntegratedImage = new (ImageResources.AppIntegrated); 15 | 16 | public static readonly string 17 | CandidateText = Resources.MyAppsAdd, 18 | AddedText = Resources.MyAppsAdded, 19 | IntegratedText = Resources.MyAppsAddedAndIntegrate; 20 | 21 | public static readonly string 22 | RunText = Resources.Run, 23 | RunWithOptionsText = Resources.RunWithOptions, 24 | UpdateText = Resources.Update, 25 | IntegrateText = Resources.Integrate, 26 | ModifyText = Resources.ModifyIntegration, 27 | RemoveText = Resources.Remove, 28 | Working = Resources.Working; 29 | } 30 | -------------------------------------------------------------------------------- /tests/apps.ps1: -------------------------------------------------------------------------------- 1 | 0install add https://apps.0install.net/devel/terraform.xml --no-download 2 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 3 | 4 | $output = 0install list-apps terraform --batch 5 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 6 | if ($output -NotContains "https://apps.0install.net/devel/terraform.xml: HashiCorp Terraform []") { throw "Wrong output" } 7 | 8 | 0install list-apps --xml > "$env:TEMP\0install-applist.xml" 9 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 10 | 11 | 0install remove https://apps.0install.net/devel/terraform.xml 12 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 13 | 14 | 0install import-apps "$env:TEMP\0install-applist.xml" --no-download 15 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 16 | 17 | $output = 0install list-apps terraform --batch 18 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 19 | if ($output -NotContains "https://apps.0install.net/devel/terraform.xml: HashiCorp Terraform []") { throw "Wrong output" } 20 | 21 | 0install remove https://apps.0install.net/devel/terraform.xml 22 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 23 | -------------------------------------------------------------------------------- /src/Store.Service/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | true 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Central.WinForms/MinimalTaskHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | namespace ZeroInstall.Central.WinForms; 5 | 6 | /// 7 | /// Like but with for . 8 | /// 9 | public class MinimalTaskHandler : GuiTaskHandlerBase 10 | { 11 | private readonly Control _owner; 12 | 13 | /// 14 | /// Creates a new minimal handler. 15 | /// 16 | /// The parent window owning the handler. 17 | public MinimalTaskHandler(Control owner) 18 | { 19 | _owner = owner; 20 | } 21 | 22 | /// 23 | protected override bool AskInteractive(string question, bool defaultAnswer) 24 | { 25 | bool result = false; 26 | Log.Debug("Question: " + question); 27 | _owner.Invoke(() => result = Msg.YesNo(_owner, question, MsgSeverity.Info)); 28 | Log.Debug("Answer: " + result); 29 | return result; 30 | } 31 | 32 | /// 33 | /// Cancels currently running s. 34 | /// 35 | public void Cancel() 36 | => CancellationTokenSource.Cancel(); 37 | } 38 | -------------------------------------------------------------------------------- /tests/store.ps1: -------------------------------------------------------------------------------- 1 | $digest = 0install digest "$PSScriptRoot\..\artifacts\Release\net472\publish" --algorithm=sha256new --batch 2 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 3 | 4 | 0install store add $digest "$PSScriptRoot\..\artifacts\Release\net472\publish" 5 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 6 | 7 | 0install store find $digest 8 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 9 | 10 | 0install store verify $digest 11 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 12 | 13 | $output = 0install store list-implementations --batch 14 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 15 | if ($output.Where({ $_.Contains($digest) }, 'First').Count -eq 0) { throw "Wrong output" } 16 | 17 | 0install store export $digest "$env:TEMP\0install-export.tar.gz" 18 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 19 | 20 | 0install store remove $digest 21 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 22 | 23 | 0install store add $digest "$env:TEMP\0install-export.tar.gz" 24 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 25 | 26 | Remove-Item "$env:TEMP\0install-export.tar.gz" 27 | 28 | 0install store remove $digest 29 | if ($LASTEXITCODE -ne 0) { throw "Exit Code: $LASTEXITCODE" } 30 | -------------------------------------------------------------------------------- /.github/workflows/translate-upload.yml: -------------------------------------------------------------------------------- 1 | name: Translate Upload 2 | on: 3 | workflow_dispatch: {} 4 | push: 5 | branches: [master] 6 | paths: ['**/*.resx', '!**/*.*.resx'] # non-localized resource files 7 | 8 | jobs: 9 | translate-upload: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v6 13 | with: 14 | fetch-depth: 0 15 | show-progress: false 16 | 17 | - name: Filter non-localizable WinForms resources 18 | shell: pwsh 19 | run: | 20 | foreach ($file in (Get-ChildItem src -Recurse -Filter "*Form.resx") + (Get-ChildItem src -Recurse -Filter "*Dialog.resx") + (Get-ChildItem src -Recurse -Filter "*Wizard.resx")) { 21 | [xml]$localized = Get-Content $file.FullName.Replace(".resx", ".de.resx") 22 | [xml]$source = Get-Content $file.FullName 23 | $source.root.assembly + $source.root.metadata + ($source.root.data | where { !$localized.root.data.name.Contains($_.name) }) | foreach { $source.root.RemoveChild($_) } | Out-Null 24 | $source.Save($file.FullName) 25 | git update-index --assume-unchanged $file.FullName 26 | } 27 | 28 | - name: Transifex Push 29 | run: ./0install.sh run https://apps.0install.net/devel/transifex-cli.xml --token ${{secrets.TRANSIFEX_API_KEY}} push --source 30 | -------------------------------------------------------------------------------- /0install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ "$#" -eq 0 ]; then 5 | echo "This script runs 0install from your PATH or downloads it on-demand." 6 | echo "" 7 | echo "To run 0install commands without adding 0install to your PATH:" 8 | echo "./0install.sh --help" 9 | echo "./0install.sh COMMAND [OPTIONS]" 10 | echo "" 11 | echo "To install to /usr/local:" 12 | echo "sudo ./0install.sh install local" 13 | echo "" 14 | echo "To install to your home directory:" 15 | echo "./0install.sh install home" 16 | exit 1 17 | fi 18 | 19 | download() { 20 | zeroinstall_release=0install-$(uname | tr '[:upper:]' '[:lower:]')-$(uname -m)-${ZEROINSTALL_VERSION:-latest} 21 | download_dir=~/.cache/0install.net/$zeroinstall_release 22 | 23 | if [ ! -f $download_dir/files/0install ]; then 24 | echo "Downloading 0install..." >&2 25 | rm -rf $download_dir 26 | mkdir -p $download_dir 27 | curl -sSL https://get.0install.net/$zeroinstall_release.tar.bz2 | tar xj --strip-components 1 --directory $download_dir 28 | fi 29 | } 30 | 31 | if [ "$1" = "install" ]; then 32 | download 33 | shift 1 34 | $download_dir/install.sh "$@" 35 | else 36 | if command -v 0install > /dev/null 2> /dev/null; then 37 | 0install "$@" 38 | else 39 | download 40 | $download_dir/files/0install "$@" 41 | fi 42 | fi 43 | -------------------------------------------------------------------------------- /src/Bootstrap/IBootstrapHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | namespace ZeroInstall; 5 | 6 | /// 7 | /// Used to run and track s and ask the user questions during the bootstrap process. 8 | /// 9 | /// Implementations of this interface are thread-safe. 10 | public interface IBootstrapHandler : ITaskHandler 11 | { 12 | /// 13 | /// Indicates whether this handler is a GUI. 14 | /// 15 | bool IsGui { get; } 16 | 17 | /// 18 | /// Hides the GUI. Has no effect when is false. 19 | /// 20 | bool Background { get; set; } 21 | 22 | /// 23 | /// Asks the user to provide a custom path for storing implementations. 24 | /// 25 | /// Ask for a path for machine-wide deployment instead of just for the current user. 26 | /// The currently set custom path for storing implementations; null if using default location. 27 | /// The path to a directory; null or empty to use the default location. 28 | /// The user cancelled the operation. 29 | string? GetCustomStorePath(bool machineWide, string? currentPath); 30 | } 31 | -------------------------------------------------------------------------------- /0install-win.xml.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | Zero Install for Windows 4 | Windows version of 0install, the decentralized installation system 5 | This is the Windows version of Zero Install. Zero Install is a cross-platform, decentralized installation system. Instead of having a central repository in which all software is placed under a naming scheme managed by some central authority, programs and libraries in Zero Install are identified by URIs. Anyone who can create a web-page can publish software. Anyone can install software (not just administrators). 6 | 7 | 8 | https://0install.net/ 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/desktop-integration.ps1: -------------------------------------------------------------------------------- 1 | 0install add terraform https://apps.0install.net/devel/terraform.xml --no-download --batch 2 | if ($LASTEXITCODE -eq 50) { 3 | Write-Output "Skipping desktop integration tests in portable mode" 4 | return 5 | } 6 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 7 | 8 | $output = 0install list-apps terraform --batch 9 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 10 | if ($output -NotContains "https://apps.0install.net/devel/terraform.xml: HashiCorp Terraform [AppAlias: terraform]") { throw "Wrong output" } 11 | 12 | & "$env:appdata\0install.net\desktop-integration\aliases\terraform.exe" --help | Out-Null 13 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 14 | 15 | 0install-win integrate https://apps.0install.net/gui/vlc.xml --add-standard --no-download | Out-Null 16 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 17 | if (-Not(Test-Path "$env:appdata\Microsoft\Windows\Start Menu\Programs\AudioVideo\VLC media player.lnk")) {throw "Missing menu entry"} 18 | 19 | 0install repair-all 20 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 21 | 22 | 0install remove https://apps.0install.net/devel/terraform.xml 23 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 24 | 25 | 0install remove https://apps.0install.net/gui/vlc.xml 26 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 27 | Start-Sleep -Seconds 5 # May trigger implicit removal of "library mode" instance of Zero Install 28 | -------------------------------------------------------------------------------- /test.ps1: -------------------------------------------------------------------------------- 1 | Param ([Switch]$Deploy, [Switch]$Machine, [Switch]$Portable, [Switch]$Purge) 2 | $ErrorActionPreference = "Stop" 3 | 4 | $previousPath = $env:PATH 5 | $env:PATH = "$PSScriptRoot\artifacts\Release\net472\publish;$env:PATH" 6 | if ($Deploy) { 7 | if ($Portable) { 8 | Write-Output "Deploying portable instance for integration tests" 9 | 0install self deploy --batch --portable "$env:TEMP\0install-portable" 10 | $env:PATH = "$env:TEMP\0install-portable;$env:PATH" 11 | } elseif ($Machine) { 12 | Write-Output "Deploying machine-wide instance for integration tests" 13 | 0install self deploy --batch --machine 14 | $env:PATH = "$env:appdata\Programs\Zero Install;$env:PATH" 15 | } else { 16 | Write-Output "Deploying per-user instance for integration tests" 17 | 0install self deploy --batch 18 | $env:PATH = "$env:ProgramFiles\Zero Install;$env:PATH" 19 | } 20 | } else { 21 | Write-Output "Using local build for integration tests" 22 | } 23 | 24 | foreach ($script in Get-ChildItem "$PSScriptRoot\tests" -Filter "*.ps1") { 25 | Write-Output $script.Name 26 | & $script.FullName 27 | } 28 | 29 | if ($Purge) { 30 | 0install store purge --batch 31 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 32 | } 33 | 34 | if ($Deploy) { 35 | if ($Portable) { 36 | Remove-Item -Recurse "$env:TEMP\0install-portable" 37 | } else { 38 | 0install self remove --batch 39 | Start-Sleep -Seconds 5 40 | } 41 | } 42 | $env:PATH = $previousPath 43 | -------------------------------------------------------------------------------- /src/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | true 30 | true 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/Commands.WinForms/CommandUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using System.Diagnostics; 5 | 6 | namespace ZeroInstall.Commands.WinForms; 7 | 8 | /// 9 | /// Helpers for running 0install-win commands. 10 | /// 11 | public class CommandUtils 12 | { 13 | /// 14 | /// Starts a 0install-win command and does not wait for it to complete. 15 | /// 16 | /// Command name with arguments to execute. 17 | public static void Start(params string?[] args) 18 | { 19 | try 20 | { 21 | GetStartInfo(args).Start(); 22 | } 23 | #region Error handling 24 | catch (IOException ex) 25 | { 26 | Msg.Inform(null, ex.Message, MsgSeverity.Error); 27 | } 28 | #endregion 29 | } 30 | 31 | /// 32 | /// Starts a 0install-win command elevated as Administrator and does not wait for it to complete. 33 | /// 34 | /// Command name with arguments to execute. 35 | public static void StartAsAdmin(params string?[] args) 36 | { 37 | try 38 | { 39 | GetStartInfo(args).AsAdmin().Start(); 40 | } 41 | #region Error handling 42 | catch (OperationCanceledException) {} 43 | catch (IOException ex) 44 | { 45 | Msg.Inform(null, ex.Message, MsgSeverity.Error); 46 | } 47 | #endregion 48 | } 49 | 50 | private static ProcessStartInfo GetStartInfo(string?[] args) 51 | => ProcessUtils.Assembly("0install-win", args.WhereNotNull().ToArray()); 52 | } 53 | -------------------------------------------------------------------------------- /src/Store.Service/StoreService.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ZeroInstall.Store.Service 2 | { 3 | partial class StoreService 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.eventLog = new System.Diagnostics.EventLog(); 32 | ((System.ComponentModel.ISupportInitialize)(this.eventLog)).BeginInit(); 33 | // 34 | // eventLog 35 | // 36 | this.eventLog.Log = "Application"; 37 | this.eventLog.Source = "Zero Install Store Service"; 38 | // 39 | // Service 40 | // 41 | this.ServiceName = "Zero Install Store Service"; 42 | ((System.ComponentModel.ISupportInitialize)(this.eventLog)).EndInit(); 43 | 44 | } 45 | 46 | #endregion 47 | 48 | private System.Diagnostics.EventLog eventLog; 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Commands.WinForms/GuiCommandHandler.Form.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using NanoByte.Common.Threading; 5 | 6 | namespace ZeroInstall.Commands.WinForms; 7 | 8 | partial class GuiCommandHandler 9 | { 10 | private readonly Lazy _branding; 11 | 12 | private FeedBranding Branding => _branding.Value; 13 | 14 | private readonly AsyncFormWrapper _form; 15 | 16 | private void ShowForm(Action action) => _form.Post(form => 17 | { 18 | ShowOnce(form); 19 | action(form); 20 | }); 21 | 22 | private T ShowForm(Func action) => _form.Post(form => 23 | { 24 | ShowOnce(form); 25 | return action(form); 26 | }); 27 | 28 | private bool _shown; 29 | 30 | private void ShowOnce(ProgressForm form) 31 | { 32 | if (_shown) return; 33 | _shown = true; 34 | 35 | if (Background) form.ShowTrayIcon(); 36 | else form.Show(); 37 | } 38 | 39 | private DialogResult SwitchToDialog(Func
buildDialog) => _form.Post(form => 40 | { 41 | using var dialog = buildDialog(); 42 | dialog.Shown += delegate { form.Hide(); }; 43 | return dialog.ShowDialog(); 44 | }); 45 | 46 | public GuiCommandHandler() 47 | { 48 | _branding = new(() => new(FeedUri)); 49 | _form = new AsyncFormWrapper(() => new ProgressForm(Branding, CancellationTokenSource)); 50 | } 51 | 52 | public override void Dispose() 53 | { 54 | try 55 | { 56 | _form.Dispose(); 57 | if (_branding.IsValueCreated) Branding.Dispose(); 58 | } 59 | finally 60 | { 61 | base.Dispose(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Central.WinForms/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using NanoByte.Common.Native; 5 | using ZeroInstall.Commands; 6 | 7 | namespace ZeroInstall.Central.WinForms; 8 | 9 | /// 10 | /// The main GUI for Zero Install, for discovering and installing new applications, managing and launching installed applications, etc. 11 | /// 12 | public static class Program 13 | { 14 | /// 15 | /// The main entry point for the application. 16 | /// 17 | [STAThread] // Required for WinForms 18 | private static int Main(string[] args) 19 | { 20 | ProgramUtils.Init(); 21 | WindowsUtils.SetCurrentProcessAppID(ZeroInstallInstance.IsIntegrated ? "ZeroInstall" : "ZeroInstall.NotIntegrated"); 22 | Application.EnableVisualStyles(); 23 | Application.SetCompatibleTextRenderingDefault(false); 24 | ErrorReportForm.SetupMonitoring(new("https://0install.de/error-report/")); 25 | 26 | try 27 | { 28 | Application.Run(args switch 29 | { 30 | [] => new MainForm(machineWide: false), 31 | ["-m"] or ["--machine"] => new MainForm(machineWide: true), 32 | [var uri] => new SelectCommandDialog(new(uri)) {ShowInTaskbar = true}, 33 | _ => throw new FormatException("Unknown command-line arguments.") 34 | }); 35 | } 36 | #region Error handling 37 | catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or InvalidDataException or FormatException) 38 | { 39 | Log.Error("Central startup failed", ex); 40 | Msg.Inform(null, ex.GetMessageWithInner(), MsgSeverity.Error); 41 | return -1; 42 | } 43 | #endregion 44 | 45 | return 0; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Bootstrap.WinForms/zero-install.wsx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/Central.WinForms/CommandUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using System.Diagnostics; 5 | using ZeroInstall.Commands; 6 | 7 | namespace ZeroInstall.Central.WinForms; 8 | 9 | /// 10 | /// Helpers for running 0install-win commands. 11 | /// 12 | public class CommandUtils 13 | { 14 | private const string ExeName = "0install-win"; 15 | 16 | /// 17 | /// Starts a 0install-win command and does not wait for it to complete. 18 | /// 19 | /// Command name with arguments to execute. 20 | public static void Start(params string?[] args) 21 | { 22 | try 23 | { 24 | GetStartInfo(args).Start(); 25 | } 26 | #region Error handling 27 | catch (IOException ex) 28 | { 29 | Msg.Inform(null, ex.Message, MsgSeverity.Error); 30 | } 31 | #endregion 32 | } 33 | 34 | /// 35 | /// Runs a 0install-win command and waits for it to complete. 36 | /// 37 | /// Command name with arguments to execute. 38 | /// The command's exit code. 39 | public static async Task RunAsync(params string?[] args) 40 | { 41 | try 42 | { 43 | return await Task.Run(() => (ExitCode)GetStartInfo(args).Run()); 44 | } 45 | #region Error handling 46 | catch (Exception ex) when (ex is IOException or NotAdminException) 47 | { 48 | Msg.Inform(null, ex.Message, MsgSeverity.Error); 49 | return (ExitCode)(-1); 50 | } 51 | #endregion 52 | } 53 | 54 | private static ProcessStartInfo GetStartInfo(string?[] args) 55 | => ProcessUtils.Assembly("0install-win", args.WhereNotNull().ToArray()); 56 | } 57 | -------------------------------------------------------------------------------- /src/Central.WinForms/PortableCreatorDialog.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using NanoByte.Common.Native; 5 | using ZeroInstall.Commands.Desktop; 6 | 7 | namespace ZeroInstall.Central.WinForms; 8 | 9 | public sealed partial class PortableCreatorDialog : Form 10 | { 11 | public PortableCreatorDialog() 12 | { 13 | InitializeComponent(); 14 | Font = DefaultFonts.Modern; 15 | } 16 | 17 | private void PortableCreatorDialog_Load(object sender, EventArgs e) => this.CenterOnParent(); 18 | 19 | private void buttonBrowse_Click(object sender, EventArgs e) 20 | { 21 | using (var folderBrowserDialog = new FolderBrowserDialog {SelectedPath = textBoxTarget.Text}) 22 | { 23 | if (folderBrowserDialog.ShowDialog(this) == DialogResult.OK) 24 | textBoxTarget.Text = folderBrowserDialog.SelectedPath; 25 | } 26 | 27 | textBoxTarget.Focus(); 28 | } 29 | 30 | private void textBoxTarget_TextChanged(object sender, EventArgs e) 31 | { 32 | if (string.IsNullOrEmpty(textBoxTarget.Text)) 33 | { 34 | buttonDeploy.Enabled = false; 35 | textBoxCommandLine.Text = ""; 36 | } 37 | else 38 | { 39 | buttonDeploy.Enabled = true; 40 | textBoxCommandLine.Text = new[] {"0install", Self.Name, Self.Deploy.Name, "--portable", textBoxTarget.Text}.JoinEscapeArguments(); 41 | } 42 | } 43 | 44 | private async void buttonDeploy_Click(object sender, EventArgs e) 45 | { 46 | if (Directory.Exists(textBoxTarget.Text) && Directory.GetFileSystemEntries(textBoxTarget.Text).Length != 0) 47 | { 48 | if (!Msg.YesNo(this, string.Format(Resources.PortableDirNotEmptyAsk, textBoxTarget.Text), MsgSeverity.Warn)) 49 | return; 50 | } 51 | 52 | Enabled = false; 53 | await CommandUtils.RunAsync(Self.Name, Self.Deploy.Name, "--portable", textBoxTarget.Text, "--restart-central"); 54 | Close(); 55 | } 56 | 57 | private void buttonCancel_Click(object sender, EventArgs e) 58 | => Close(); 59 | } 60 | -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | preview 6 | net472 7 | 10.0.10240.0 8 | enable 9 | annotations 10 | True 11 | True 12 | $(NoWarn);1591 13 | $(MSBuildThisFileDirectory)..\icon.ico 14 | ..\app.manifest 15 | 16 | 17 | cs;es;el;fr;id;it;ja;ko;nl;pt-BR;pt-PT;ro;ru;tr;zh;zh-Hant 18 | False 19 | 20 | 21 | Zero Install 22 | Copyright Bastian Eicher et al. 23 | https://github.com/0install/0install-win 24 | 25 | 26 | 1.0.0-pre 27 | 28 | 29 | 2.20.4 30 | 2.28.1 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/Bootstrap/Bootstrap.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ZeroInstall 7 | 0install 8 | Downloads and runs Zero Install. 9 | Exe 10 | bin\$(Configuration)\ 11 | False 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | set ARTIFACT_DIR=$(ProjectDir)\..\..\artifacts\Bootstrap 34 | mkdir "%ARTIFACT_DIR%" 35 | 36 | pushd "$(OutDir)" 37 | "$(ILRepack)" /targetplatform:v4 /ndebug /union /noRepackRes /wildcards /out:"%ARTIFACT_DIR%\$(TargetName).exe" "$(TargetPath)" ZeroInstall.*.dll Generator.Equals.Runtime.dll NanoByte.Common.dll System.Buffers.dll System.Memory.dll System.Runtime.*.dll System.Threading.*.dll Microsoft.Bcl.HashCode.dll Newtonsoft.Json.dll INIFileParser.dll BouncyCastle.OpenPgp.dll ICSharpCode.SharpZipLib.dll NDesk.Options.dll 38 | copy /y "$(ProjectDir)\App.config" "%ARTIFACT_DIR%\$(TargetName).exe.config" 39 | copy /y BootstrapConfig.ini "%ARTIFACT_DIR%\$(TargetName).ini" 40 | popd 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/Bootstrap.WinForms/GuiBootstrapHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using NanoByte.Common.Threading; 5 | 6 | namespace ZeroInstall; 7 | 8 | /// 9 | /// Uses to show progress during the bootstrap process. 10 | /// 11 | /// This class manages a GUI thread with an independent message queue. Invoking methods on the right thread is handled automatically. 12 | public class GuiBootstrapHandler : GuiTaskHandlerBase, IBootstrapHandler 13 | { 14 | private readonly AsyncFormWrapper _wrapper; 15 | 16 | public GuiBootstrapHandler() 17 | { 18 | _wrapper = new AsyncFormWrapper(delegate 19 | { 20 | var form = new MainForm(CancellationTokenSource); 21 | form.Show(); 22 | return form; 23 | }); 24 | } 25 | 26 | public override void Dispose() 27 | { 28 | try 29 | { 30 | _wrapper.Dispose(); 31 | } 32 | finally 33 | { 34 | base.Dispose(); 35 | } 36 | } 37 | 38 | /// 39 | public override void Error(Exception exception) 40 | { 41 | _wrapper.SendLow(x => x.Enabled = false); 42 | base.Error(exception); 43 | } 44 | 45 | /// 46 | public bool IsGui => true; 47 | 48 | /// 49 | public bool Background { get; set; } 50 | 51 | /// 52 | public override void RunTask(ITask task) 53 | { 54 | #region Sanity checks 55 | if (task == null) throw new ArgumentNullException(nameof(task)); 56 | #endregion 57 | 58 | Log.Debug("Task: " + task.Name); 59 | var progress = Background ? null : _wrapper.Post(form => form.GetProgressControl(task.Name)); 60 | task.Run(CancellationToken, CredentialProvider, progress); 61 | } 62 | 63 | /// 64 | public string? GetCustomStorePath(bool machineWide, string? currentPath) 65 | { 66 | if (!IsInteractive) return currentPath; 67 | 68 | string? result = _wrapper.Post(form => form.GetCustomStorePath(machineWide, currentPath)).Result; 69 | CancellationToken.ThrowIfCancellationRequested(); 70 | return result; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Bootstrap.WinForms/Bootstrap.WinForms.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ZeroInstall 7 | zero-install 8 | Downloads and runs Zero Install optionally showing a GUI. 9 | WinExe 10 | bin\$(Configuration)\ 11 | False 12 | True 13 | 14 | 15 | ERROR_REPORT 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | set ARTIFACT_DIR=$(ProjectDir)\..\..\artifacts\Bootstrap 42 | mkdir "%ARTIFACT_DIR%" 43 | 44 | pushd "$(OutDir)" 45 | "$(ILRepack)" /targetplatform:v4 /ndebug /union /noRepackRes /wildcards /out:"%ARTIFACT_DIR%\$(TargetName).exe" "$(TargetPath)" 0install.exe ZeroInstall.*.dll Generator.Equals.Runtime.dll NanoByte.Common*.dll TaskDialog.dll System.Buffers.dll System.Memory.dll System.Runtime.*.dll System.Threading.*.dll Microsoft.Bcl.HashCode.dll Newtonsoft.Json.dll INIFileParser.dll BouncyCastle.OpenPgp.dll ICSharpCode.SharpZipLib.dll NDesk.Options.dll 46 | copy /y "$(ProjectDir)\App.config" "%ARTIFACT_DIR%\$(TargetName).exe.config" 47 | copy /y BootstrapConfig.ini "%ARTIFACT_DIR%\$(TargetName).ini" 48 | popd 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | type = RESX 4 | source_lang = en 5 | lang_map = pt_PT: pt-PT, pt_BR: pt-BR 6 | 7 | [o:eicher:p:0install-win:r:store-service] 8 | source_file = src/Store.Service/Properties/Resources.resx 9 | file_filter = src/Store.Service/Properties/Resources..o.resx 10 | 11 | [o:eicher:p:0install-win:r:central] 12 | source_file = src/Central.WinForms/Properties/Resources.resx 13 | file_filter = src/Central.WinForms/Properties/Resources..o.resx 14 | 15 | [o:eicher:p:0install-win:r:window-central_winforms_introdialog] 16 | source_file = src/Central.WinForms/IntroDialog.resx 17 | file_filter = src/Central.WinForms/IntroDialog..o.resx 18 | 19 | [o:eicher:p:0install-win:r:window-central_winforms_mainform] 20 | source_file = src/Central.WinForms/MainForm.resx 21 | file_filter = src/Central.WinForms/MainForm..o.resx 22 | 23 | [o:eicher:p:0install-win:r:window-central_winforms_portablecreatordialog] 24 | source_file = src/Central.WinForms/PortableCreatorDialog.resx 25 | file_filter = src/Central.WinForms/PortableCreatorDialog..o.resx 26 | 27 | [o:eicher:p:0install-win:r:window-central_winforms_selectcommanddialog] 28 | source_file = src/Central.WinForms/SelectCommandDialog.resx 29 | file_filter = src/Central.WinForms/SelectCommandDialog..o.resx 30 | 31 | [o:eicher:p:0install-win:r:window-central_winforms_syncwizard] 32 | source_file = src/Central.WinForms/SyncWizard.resx 33 | file_filter = src/Central.WinForms/SyncWizard..o.resx 34 | 35 | [o:eicher:p:0install-win:r:window-commands_winforms_configdialog] 36 | source_file = src/Commands.WinForms/ConfigDialog.resx 37 | file_filter = src/Commands.WinForms/ConfigDialog..o.resx 38 | 39 | [o:eicher:p:0install-win:r:window-commands_winforms_feedsearchdialog] 40 | source_file = src/Commands.WinForms/FeedSearchDialog.resx 41 | file_filter = src/Commands.WinForms/FeedSearchDialog..o.resx 42 | 43 | [o:eicher:p:0install-win:r:window-commands_winforms_integrateappform] 44 | source_file = src/Commands.WinForms/IntegrateAppForm.resx 45 | file_filter = src/Commands.WinForms/IntegrateAppForm..o.resx 46 | 47 | [o:eicher:p:0install-win:r:window-commands_winforms_interfacedialog] 48 | source_file = src/Commands.WinForms/InterfaceDialog.resx 49 | file_filter = src/Commands.WinForms/InterfaceDialog..o.resx 50 | 51 | [o:eicher:p:0install-win:r:window-commands_winforms_storemanageform] 52 | source_file = src/Commands.WinForms/StoreManageForm.resx 53 | file_filter = src/Commands.WinForms/StoreManageForm..o.resx 54 | -------------------------------------------------------------------------------- /.github/workflows/translate.yml: -------------------------------------------------------------------------------- 1 | name: Translate 2 | on: 3 | workflow_dispatch: {} 4 | schedule: 5 | - cron: '0 6 15 * *' 6 | 7 | jobs: 8 | translate: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v6 12 | with: 13 | fetch-depth: 0 14 | show-progress: false 15 | 16 | - name: Filter non-localizable WinForms resources 17 | shell: pwsh 18 | run: | 19 | foreach ($file in (Get-ChildItem src -Recurse -Filter "*Form.resx") + (Get-ChildItem src -Recurse -Filter "*Dialog.resx") + (Get-ChildItem src -Recurse -Filter "*Wizard.resx")) { 20 | [xml]$localized = Get-Content $file.FullName.Replace(".resx", ".de.resx") 21 | [xml]$source = Get-Content $file.FullName 22 | $source.root.assembly + $source.root.metadata + ($source.root.data | where { !$localized.root.data.name.Contains($_.name) }) | foreach { $source.root.RemoveChild($_) } | Out-Null 23 | $source.Save($file.FullName) 24 | git update-index --assume-unchanged $file.FullName 25 | } 26 | 27 | - name: Transifex Pull (fully translated) 28 | run: ./0install.sh run https://apps.0install.net/devel/transifex-cli.xml --token ${{secrets.TRANSIFEX_API_KEY}} pull --translations --mode translator --all --minimum-perc 100 29 | - name: Transifex Pull (partially translated) # Only languages that can be completed with Machine Translation 30 | run: ./0install.sh run https://apps.0install.net/devel/transifex-cli.xml --token ${{secrets.TRANSIFEX_API_KEY}} pull --translations --mode translator --languages cs,el,es,fr,id,it,ja,ko,nl,pl,pt_PT,ro,ru,zh 31 | 32 | - name: DeepL Cache 33 | uses: actions/cache@v5 34 | with: 35 | path: '**/*.a.resx' 36 | key: deepl 37 | - name: DeepL Translate 38 | uses: Yeah69/MrMeeseeks.ResXTranslationCombinator@main 39 | env: 40 | GITHUB_TOKEN: ${{github.token}} 41 | with: 42 | auth: ${{secrets.DEEPL_API_KEY}} 43 | source-lang: en 44 | localization-filter: cs;el;es;fr;id;it;ja;ko;nl;pl;pt-PT;ro;ru;zh 45 | glossary-name: Zero Install 46 | context: User interface for software installation with menus, buttons and progress bars. Downloads files from the internet and runs apps. 47 | excludes-regex: .*ImageResources.* 48 | 49 | - name: Create Pull Request 50 | uses: peter-evans/create-pull-request@v8 51 | with: 52 | branch: translate 53 | commit-message: Update translations 54 | title: Update translations 55 | body: Translations downloaded from Transifex and generated with DeepL 56 | -------------------------------------------------------------------------------- /src/Commands.WinForms/Commands.WinForms.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ZeroInstall.Commands.WinForms 6 | 0install-win 7 | A WinForms-based GUI for Zero Install, for installing and launching applications, managing caches, etc. 8 | WinExe 9 | ..\..\artifacts\$(Configuration)\ 10 | True 11 | 12 | 13 | ERROR_REPORT 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | ConfigDialog.cs 40 | 41 | 42 | FeedSearchDialog.cs 43 | 44 | 45 | IntegrateAppForm.cs 46 | 47 | 48 | InterfaceDialog.cs 49 | 50 | 51 | StoreManageForm.cs 52 | 53 | 54 | 55 | 56 | 57 | True 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/build.ps1: -------------------------------------------------------------------------------- 1 | Param ([String]$Version = "1.0.0-pre") 2 | $ErrorActionPreference = "Stop" 3 | pushd $PSScriptRoot 4 | 5 | function Find-MSBuild { 6 | if (Test-Path "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe") { 7 | $vsDir = . "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -products * -property installationPath -format value -version 17.13 8 | if ($vsDir) { return "$vsDir\MSBuild\Current\Bin\amd64\MSBuild.exe" } 9 | } 10 | } 11 | 12 | function Run-MSBuild { 13 | $msbuild = Find-Msbuild 14 | if (!$msbuild) { throw "You need Visual Studio 2022 v17.13 or newer to build this project" } 15 | . $msbuild @args 16 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 17 | } 18 | 19 | function SearchAndReplace($Value, $FilePath, $PatternLeft, $PatternRight) { 20 | (Get-Content $FilePath -Encoding UTF8) ` 21 | -replace "$PatternLeft.*$PatternRight", ($PatternLeft.Replace('\', '') + $Value + $PatternRight.Replace('\', '')) | 22 | Set-Content $FilePath -Encoding UTF8 23 | } 24 | 25 | function Add-Manifest($Manifest, $Binary) { 26 | mt -nologo -manifest $Manifest -outputresource:"$Binary;#101" 27 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 28 | } 29 | 30 | echo "Build binaries" 31 | if ($env:CI) { $ci = "/p:ContinuousIntegrationBuild=True /terminalLogger:off" } 32 | Run-MSBuild /v:Quiet /t:Restore /t:Build /p:Configuration=Release /p:Version=$Version $ci 33 | Out-File ..\artifacts\VERSION -Encoding ASCII -InputObject $Version 34 | 35 | echo "Prepare binaries for publishing" 36 | Run-MSBuild /v:Quiet /t:Publish /p:NoBuild=True /p:BuildProjectReferences=False /p:Configuration=Release /p:Version=$Version 37 | rm ..\artifacts\Release\net472\publish\*.pdb 38 | rm ..\artifacts\Release\net472\publish\*\Microsoft.CodeAnalysis*.resources.dll 39 | 40 | echo "Build Windows Installer package" 41 | pushd Bootstrap.WinForms 42 | dotnet tool restore 43 | dotnet wix build zero-install.wsx -o ..\..\artifacts\Bootstrap\zero-install.msi -pdbtype none 44 | if ($LASTEXITCODE -ne 0) {throw "Exit Code: $LASTEXITCODE"} 45 | popd 46 | 47 | echo "Build Chocolatey package" 48 | if (Get-Command choco -ErrorAction SilentlyContinue) { 49 | SearchAndReplace $Version Bootstrap\chocolateyInstall.ps1 -PatternLeft '--version=' -PatternRight ' self' 50 | choco pack Bootstrap\Chocolatey.nuspec --version $Version --outdir ..\artifacts 51 | move -Force ..\artifacts\0install.$Version.nupkg ..\artifacts\0install.chocolatey.$Version.nupkg 52 | SearchAndReplace "1.0.0-pre" Bootstrap\chocolateyInstall.ps1 -PatternLeft '--version=' -PatternRight ' self' 53 | } else { 54 | Write-Warning "You need choco.exe to build the 0install Chocolatey package" 55 | } 56 | 57 | popd 58 | -------------------------------------------------------------------------------- /src/Central.WinForms/Central.WinForms.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ZeroInstall.Central.WinForms 6 | ZeroInstall 7 | The main GUI for Zero Install, for discovering and installing new applications, managing and launching installed applications, etc. 8 | WinExe 9 | ..\..\artifacts\$(Configuration)\ 10 | True 11 | 12 | 13 | ERROR_REPORT 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Always 39 | 40 | 41 | Always 42 | 43 | 44 | 45 | 46 | 47 | 48 | IntroDialog.cs 49 | 50 | 51 | MainForm.cs 52 | 53 | 54 | PortableCreatorDialog.cs 55 | 56 | 57 | SelectCommandDialog.cs 58 | 59 | 60 | SyncWizard.cs 61 | 62 | 63 | 64 | 65 | 66 | True 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/Bootstrap/Chocolatey.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0install 5 | Zero Install 6 | $version$ 7 | Bastian Eicher 8 | bastian.eicher 9 | false 10 | https://opensource.org/licenses/lgpl-license 11 | https://0install.net/ 12 | https://cdn.rawgit.com/dtgm/chocolatey-packages/23daa374e2e649e33d1f4b3ffe2ce07cb1614cd3/icons/0install.png 13 | https://github.com/0install/0install-win 14 | https://github.com/0install/0install-win/tree/master/src/Bootstrap 15 | https://docs.0install.net/ 16 | https://0install.net/support.html#lists 17 | Decentralized cross-distribution software installation system 18 | [Zero Install](https://0install.net/) is a decentralized cross-platform software-installation system available under the LGPL. It allows software developers to publish programs directly from their own web-sites, while supporting features familiar from centralized distribution repositories such as shared libraries, automatic updates and digital signatures. It is intended to complement, rather than replace, the operating system’s package management. 0install packages never interfere with those provided by the distribution. 19 | 20 | Zero Install does not define a new packaging format; unmodified tarballs or zip archives can be used. Instead, it defines an XML metadata format to describe these packages and the dependencies between them. A single metadata file can be used on multiple platforms (e.g. Windows, Ubuntu, Debian, Fedora, FreeBSD and Mac OS X). 21 | 22 | Zero Install also has some [interesting features](https://docs.0install.net/features/) not often found in traditional package managers. For example, while it will share libraries whenever possible, it can always install multiple versions of a package in parallel when there are conflicting requirements. Installation is always side-effect-free (each package is unpacked to its own directory and will not touch shared directories), making it ideal for use with sandboxing technologies and virtualization. 23 | [News](https://0install.net/#news) 24 | Copyright Bastian Eicher et al. 25 | 0install Zero Install Package Manager 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zero Install for Windows 2 | 3 | [![Build status](https://img.shields.io/appveyor/ci/0install/0install-win.svg)](https://ci.appveyor.com/project/0install/0install-win) 4 | This is the Windows version of Zero Install. It extends the cross-platform core [Zero Install .NET](https://github.com/0install/0install-dotnet) with a GUI and various OS-specific integrations. 5 | 6 | Zero Install is a decentralized cross-platform software installation system. You can learn more at [0install.net](https://0install.net/). 7 | 8 | **[Download Zero Install for Windows](https://get.0install.net/#windows)** 9 | 10 | ## Building 11 | 12 | The source code is in [`src/`](src/) and generated artifacts are placed in `artifacts/`. 13 | The source code does not contain version numbers. Instead the version is determined during CI using [GitVersion](https://gitversion.net/). 14 | 15 | To build install [Visual Studio 2022 v17.13 or newer](https://www.visualstudio.com/downloads/) and run `.\build.ps1`. 16 | If you wish to deploy the build after compilation as the default Zero Install instance in your user profile run `.\build.ps1 -Deploy`. To deploy it for all users use `.\build.ps1 -Deploy -Machine`. 17 | 18 | ## Integration tests 19 | 20 | The PowerShell scripts in [`tests/`](tests/) are integration tests. 21 | 22 | You can run them individually. They will then use the version of Zero Install found in your current `PATH`. 23 | 24 | You can also run them all against: 25 | - your latest build, with `.\test.ps1` 26 | - a temporarily deployed copy of your latest build, with `.\test.ps1 -Deploy` 27 | - a temporarily deployed machine-wide copy of your latest build, with `.\test.ps1 -Deploy -Machine` 28 | - a temporarily deployed portable copy of your latest build, with `.\test.ps1 -Deploy -Portable` 29 | 30 | ## Contributing 31 | 32 | We welcome contributions to this project such as bug reports, recommendations, pull requests and [translations](https://www.transifex.com/eicher/0install-win/). If you have any questions feel free to pitch in on our [friendly mailing list](https://0install.net/support.html#lists). 33 | 34 | This repository contains an [EditorConfig](http://editorconfig.org/) file. Please make sure to use an editor that supports it to ensure consistent code style, file encoding, etc.. For full tooling support for all style and naming conventions consider using JetBrains' [ReSharper](https://www.jetbrains.com/resharper/) or [Rider](https://www.jetbrains.com/rider/) products. 35 | 36 | ## Privacy and code signing policy 37 | 38 | Zero Install for Windows contacts various servers automatically during normal operation (e.g., to check for updates). No personal information is transmitted to these systems unless specifically requested by the user (e.g., to synchronize apps between computers). See the [documentation](https://docs.0install.net/details/servers/) for details. 39 | 40 | This program uses free code signing provided by [SignPath.io](https://signpath.io?utm_source=foundation&utm_medium=github&utm_campaign=0install), and a certificate by the [SignPath Foundation](https://signpath.org?utm_source=foundation&utm_medium=github&utm_campaign=0install). Signed releases are published by [Bastian Eicher](https://github.com/bastianeicher). 41 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | signing_request_id: 6 | required: true 7 | description: Signing request ID 8 | 9 | jobs: 10 | release: 11 | runs-on: ubuntu-latest 12 | steps: 13 | # Prepare 14 | - uses: actions/checkout@v6 15 | with: 16 | fetch-depth: 0 17 | show-progress: false 18 | 19 | # Artifacts 20 | - name: Download signed artifacts 21 | id: download 22 | run: | 23 | curl -sSf -H "Authorization: Bearer ${{secrets.SIGNPATH_API_KEY}}" -o artifacts.zip https://app.signpath.io/API/v1/0e70cf92-49a1-4427-a800-b6bc5b497936/SigningRequests/${{inputs.signing_request_id}}/SignedArtifact 24 | mkdir artifacts 25 | unzip -q artifacts.zip -d artifacts 26 | echo "version=$(cat artifacts/VERSION | tr -d '\r\n')" >> $GITHUB_OUTPUT 27 | - name: Create archives 28 | run: | 29 | ./0install.sh run https://apps.0install.net/0install/0template.xml 0install-win.xml.template version=${{steps.download.outputs.version}} 30 | 31 | pushd group-policies 32 | zip -9 ../artifacts/group-policies.zip * 33 | popd 34 | 35 | pushd artifacts/Bootstrap 36 | zip -9 0install.zip 0install.exe 0install.exe.config 0install.ini 37 | zip -9 zero-install.zip zero-install.exe zero-install.exe.config zero-install.ini 38 | popd 39 | 40 | # Release 41 | - name: Get tag message 42 | id: tag_message 43 | run: | 44 | { 45 | echo "message<> "$GITHUB_OUTPUT" 50 | - name: Create GitHub Release 51 | uses: softprops/action-gh-release@v2 52 | with: 53 | tag_name: ${{steps.download.outputs.version}} 54 | body: | 55 | **[Download Zero Install for Windows](https://get.0install.net/#windows)** 56 | ## Changes 57 | ${{steps.tag_message.outputs.message}} 58 | 59 | Based on [Zero Install .NET ${{steps.download.outputs.version}}](https://github.com/0install/0install-dotnet/releases/${{steps.download.outputs.version}}). 60 | files: | 61 | 0install-win-${{steps.download.outputs.version}}.* 62 | artifacts/Bootstrap/*.exe 63 | artifacts/Bootstrap/*.zip 64 | artifacts/Bootstrap/*.msi 65 | 66 | # Publish 67 | - name: Publish feed 68 | env: 69 | GH_TOKEN: ${{secrets.PERSONAL_TOKEN}} 70 | run: > 71 | gh workflow run --repo=0install/apps Incoming 72 | -f feed_url=https://github.com/${{github.repository}}/releases/download/${{steps.download.outputs.version}}/0install-win-${{steps.download.outputs.version}}.xml 73 | -f archive_url=https://github.com/${{github.repository}}/releases/download/${{steps.download.outputs.version}}/0install-win-${{steps.download.outputs.version}}.tar.gz 74 | - name: Push Chocolatey package 75 | run: dotnet nuget push artifacts/0install.chocolatey.*.nupkg --source https://push.chocolatey.org/ --api-key ${{secrets.CHOCOLATEY_API_KEY}} 76 | -------------------------------------------------------------------------------- /src/Bootstrap/ExitCode.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using NDesk.Options; 5 | using ZeroInstall.Services.Executors; 6 | using ZeroInstall.Services.Solvers; 7 | using ZeroInstall.Model.Selection; 8 | using ZeroInstall.Store.Implementations; 9 | using ZeroInstall.Store.Trust; 10 | 11 | namespace ZeroInstall; 12 | 13 | /// 14 | /// An exit code is returned to the original caller after the application terminates, to indicate success or the reason for failure. 15 | /// 16 | public enum ExitCode 17 | { 18 | /// The operation completed without any problems. 19 | OK = 0, 20 | 21 | /// There was a network problem. This may be intermittent and resolve itself e.g. when a Wi-Fi connection is restored. 22 | /// 23 | WebError = 10, 24 | 25 | /// You have insufficient access rights. This can potentially be fixed by running the command as an Administrator/root. It may also indicate misconfigured file permissions. 26 | /// 27 | AccessDenied = 11, 28 | 29 | /// There was an IO problem. This encompasses issues such as missing files or insufficient disk space. 30 | /// 31 | IOError = 12, 32 | 33 | /// The was unable to provide that fulfill the . This can be caused by a problem with the feed, an impossible request (e.g., non-existing version) or your local configuration. 34 | /// 35 | SolverError = 20, 36 | 37 | /// The was unable to launch the desired application. This usually indicates a problem with the feed. 38 | /// 39 | ExecutorError = 21, 40 | 41 | /// A data file could not be parsed. This encompasses issues such as damaged configuration files or malformed XML documents (e.g. feeds). 42 | /// 43 | InvalidData = 25, 44 | 45 | /// The of an implementation does not match the expected value. This could be caused by a damaged download or an incorrect feed. 46 | /// 47 | DigestMismatch = 26, 48 | 49 | /// There was a problem with the digital signature of a feed. The signature may be missing, damaged or not trusted for the source the feed came from. 50 | /// 51 | InvalidSignature = 27, 52 | 53 | /// The operation could not be completed because a feature that is not (yet) supported was requested. Upgrading to a newer version may resolve this issue. 54 | /// 55 | NotSupported = 50, 56 | 57 | /// The command-line arguments passed to the application were invalid. 58 | /// 59 | /// 60 | InvalidArguments = 99, 61 | 62 | /// The user canceled the task. 63 | /// 64 | UserCanceled = 100 65 | } 66 | -------------------------------------------------------------------------------- /src/Bootstrap/BootstrapConfig.ini: -------------------------------------------------------------------------------- 1 | ;Use this to create a custom bootstrapper for a specific application. 2 | [bootstrap] 3 | 4 | ;The GnuPG key fingerprint to trust for signing self_update_uri or app_uri. 5 | key_fingerprint= 6 | 7 | ;The feed URI of the target application to bootstrap. 8 | app_uri=;--------------------------------------------------------------------------------AppUri-------------------------------------------------------------------------------- 9 | 10 | ;The name of the target application to bootstrap. 11 | app_name=;----------------------------------------AppName---------------------------------------- 12 | 13 | ;Additional command-line arguments to pass to the application. 14 | app_args= 15 | 16 | ;Command-line arguments to pass to '0install integrate'. Leave empty to not call '0install integrate' at all. 17 | integrate_args=;--------------------------------------------------------------------------------IntegrateArgs-------------------------------------------------------------------------------- 18 | 19 | ;The URI of the catalog to replace the default catalog. Only applies if Zero Install is not already deployed. 20 | catalog_uri= 21 | 22 | ;Offer the user to choose a custom path for storing implementations. 23 | customizable_store_path=false 24 | 25 | ;Show the estimated disk space required (in bytes). Only works when customizable_store_path=true. 26 | estimated_required_space= 27 | 28 | ;Use this to set Zero Install configuration options. Only overrides existing config files if Zero Install is not already deployed. 29 | [global] 30 | 31 | ;The feed URI used to download and update Zero Install itself. 32 | self_update_uri=https://apps.0install.net/0install/0install-win.xml 33 | 34 | ;The feed URI used to get the external solver. Set to empty to deactivate use of external solver. 35 | ;external_solver_uri=https://apps.0install.net/0install/0install-ocaml.xml 36 | 37 | ;The mirror server used to provide feeds when the original server is unavailable. Set to empty to deactivate use of feed mirror. 38 | ;feed_mirror=https://roscidus.com/0mirror 39 | 40 | ;The key information server used to get information about who signed a feed. Set to empty to deactivate use of key information server. 41 | ;key_info_server=https://keylookup.0install.net/ 42 | 43 | ;Automatically approve keys known by the key info server and seen the first time a feed is fetched. 44 | ;auto_approve_keys=true 45 | 46 | ;The sync server used to synchronize your app list between multiple computers. 47 | ;sync_server=https://0install.de/sync/ 48 | 49 | ;The username to authenticate with against the Sync server. Make sure to keep this file private if you decide to set this! 50 | ;sync_server_user= 51 | 52 | ;The password to authenticate with against the Sync server. Make sure to keep this file private if you decide to set this! 53 | ;sync_server_pw= 54 | 55 | ;The local key used to encrypt data before sending it to the Sync server. Make sure to keep this file private if you decide to set this! 56 | ;sync_crypto_key= 57 | 58 | ;The maximum age a cached feed may have until it is considered stale (needs to be updated) in seconds. 59 | ;freshness=604800 60 | 61 | ;Always prefer the newest versions, even if they have not been marked as stable yet. 62 | ;help_with_testing=false 63 | 64 | ;Controls how liberally network access is attempted: off-line, minimal, full 65 | ;network_use=full 66 | 67 | ;Restrict usage to feeds specified in the catalog. 68 | ;kiosk_mode=false 69 | -------------------------------------------------------------------------------- /src/Commands.WinForms/CacheNodeWithContextMenu.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using System.Diagnostics; 5 | using ZeroInstall.Store.Implementations; 6 | using ZeroInstall.Store.ViewModel; 7 | 8 | namespace ZeroInstall.Commands.WinForms; 9 | 10 | /// 11 | /// Wraps a and adds a context menu. 12 | /// 13 | /// The form this cache node is displayed on. 14 | /// The underlying containing the cache information. 15 | [SuppressMessage("Microsoft.Design", "CA1036:OverrideMethodsOnComparableTypes", Justification = "Comparison only used for string sorting in UI lists")] 16 | internal sealed class CacheNodeWithContextMenu(StoreManageForm form, CacheNode innerNode) : INamed, IContextMenu 17 | { 18 | /// 19 | /// The underlying containing the cache information. 20 | /// 21 | public CacheNode InnerNode { get; } = innerNode; 22 | 23 | /// 24 | /// The UI path name of this node. 25 | /// 26 | public string Name { get => InnerNode.Name; set => throw new NotSupportedException(); } 27 | 28 | /// 29 | public ContextMenuStrip GetContextMenu() 30 | { 31 | var menu = new ContextMenuStrip 32 | { 33 | Items = 34 | { 35 | { 36 | Resources.OpenInFileManager, null, delegate 37 | { 38 | Process.Start("explorer.exe", (InnerNode is FeedNode ? "/select," : "") + InnerNode.Path.EscapeArgument()); 39 | } 40 | }, 41 | { 42 | Resources.Remove, null, delegate 43 | { 44 | if (Msg.YesNo(form, Resources.DeleteEntry, MsgSeverity.Warn)) 45 | { 46 | try { Remove(); } 47 | catch (OperationCanceledException) {} 48 | form.RefreshList(); 49 | } 50 | } 51 | } 52 | } 53 | }; 54 | 55 | if (InnerNode is ImplementationNode) 56 | { 57 | menu.Items.Add(Resources.Verify, null, delegate 58 | { 59 | try { Verify(); } 60 | catch (OperationCanceledException) {} 61 | }); 62 | } 63 | 64 | return menu; 65 | } 66 | 67 | public void Remove() 68 | { 69 | try 70 | { 71 | InnerNode.Remove(form.Services.FeedCache, form.Services.ImplementationStore); 72 | } 73 | #region Error handling 74 | catch (Exception ex) when (ex is ImplementationNotFoundException or IOException or UnauthorizedAccessException) 75 | { 76 | Msg.Inform(null, ex.Message, MsgSeverity.Error); 77 | } 78 | #endregion 79 | } 80 | 81 | public void Verify() 82 | { 83 | try 84 | { 85 | (InnerNode as ImplementationNode)?.Verify(form.Services.ImplementationStore); 86 | } 87 | #region Error handling 88 | catch (Exception ex) when (ex is ImplementationNotFoundException or IOException or UnauthorizedAccessException) 89 | { 90 | Msg.Inform(null, ex.Message, MsgSeverity.Warn); 91 | } 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.zh.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | 开始使用 63 | Automatically translated. 64 | 65 | 66 | 关闭 67 | Automatically translated. 68 | 69 | 70 | 再次播放 71 | Automatically translated. 72 | 73 | 74 | 简介视频 75 | Automatically translated. 76 | 77 | 78 | 我的应用程序 79 | Automatically translated. 80 | 81 | 82 | 目录 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.ja.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | はじめに 63 | Automatically translated. 64 | 65 | 66 | 閉じる 67 | Automatically translated. 68 | 69 | 70 | もう一度再生 71 | Automatically translated. 72 | 73 | 74 | 短い紹介ビデオ 75 | Automatically translated. 76 | 77 | 78 | 私のアプリ 79 | Automatically translated. 80 | 81 | 82 | カタログ 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.ko.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | 시작하기 63 | Automatically translated. 64 | 65 | 66 | 닫기 67 | Automatically translated. 68 | 69 | 70 | 다시 재생 71 | Automatically translated. 72 | 73 | 74 | 짧은 소개 동영상 75 | Automatically translated. 76 | 77 | 78 | 내 앱 79 | Automatically translated. 80 | 81 | 82 | 카탈로그 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.fr.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Commencer 63 | Manually overriden. 64 | 65 | 66 | &Fermer 67 | Manually overriden. 68 | 69 | 70 | &Rejouer 71 | Manually overriden. 72 | 73 | 74 | Une courte vidéo d'introduction 75 | Manually overriden. 76 | 77 | 78 | Mes apps 79 | Manually overriden. 80 | 81 | 82 | Catalogue 83 | Manually overriden. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.el.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Εναρξη 63 | Manually overriden. 64 | 65 | 66 | Κλεισιμο 67 | Manually overriden. 68 | 69 | 70 | Αναπαραγωγη ξανα 71 | Manually overriden. 72 | 73 | 74 | Ένα σύντομο εισαγωγικό βίντεο 75 | Manually overriden. 76 | 77 | 78 | Οι εφαρμογές μου 79 | Manually overriden. 80 | 81 | 82 | Κατάλογος 83 | Manually overriden. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.tr.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Başlarken 63 | Manually overriden. 64 | 65 | 66 | &Kapat 67 | Manually overriden. 68 | 69 | 70 | Yeniden &oynat 71 | Manually overriden. 72 | 73 | 74 | Kısa bilgilendirme görüntüsü 75 | Manually overriden. 76 | 77 | 78 | Uygulamalarım 79 | Manually overriden. 80 | 81 | 82 | Katalog 83 | Manually overriden. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.de.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Erste Schritte 63 | Manually overriden. 64 | 65 | 66 | &Schließen 67 | Manually overriden. 68 | 69 | 70 | &Erneut abspielen 71 | Manually overriden. 72 | 73 | 74 | Ein kurzes Einführungsvideo 75 | Manually overriden. 76 | 77 | 78 | Meine Apps 79 | Manually overriden. 80 | 81 | 82 | Katalog 83 | Manually overriden. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.it.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Iniziare 63 | Automatically translated. 64 | 65 | 66 | Chiudere 67 | Automatically translated. 68 | 69 | 70 | Riproduzione 71 | Automatically translated. 72 | 73 | 74 | Un breve video introduttivo 75 | Automatically translated. 76 | 77 | 78 | Le mie app 79 | Manually overriden. 80 | 81 | 82 | Catalogo 83 | Manually overriden. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.cs.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Začínáme 63 | Automatically translated. 64 | 65 | 66 | Zavřít 67 | Automatically translated. 68 | 69 | 70 | Přehrát znovu 71 | Automatically translated. 72 | 73 | 74 | Krátké úvodní video 75 | Automatically translated. 76 | 77 | 78 | Moje aplikace 79 | Automatically translated. 80 | 81 | 82 | Katalog 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.pt-BR.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Vamos começar 63 | Manually overriden. 64 | 65 | 66 | Fe&char 67 | Manually overriden. 68 | 69 | 70 | Reproduzir &de novo 71 | Manually overriden. 72 | 73 | 74 | Vídeo curto de introdução 75 | Manually overriden. 76 | 77 | 78 | Meus aplicativos 79 | Manually overriden. 80 | 81 | 82 | Catálogo 83 | Manually overriden. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.id.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Memulai 63 | Automatically translated. 64 | 65 | 66 | Tutup 67 | Automatically translated. 68 | 69 | 70 | Mainkan lagi 71 | Automatically translated. 72 | 73 | 74 | Video pengenalan singkat 75 | Automatically translated. 76 | 77 | 78 | Aplikasi saya 79 | Automatically translated. 80 | 81 | 82 | Katalog 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.nl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Aan de slag 63 | Automatically translated. 64 | 65 | 66 | Sluit 67 | Automatically translated. 68 | 69 | 70 | Opnieuw afspelen 71 | Automatically translated. 72 | 73 | 74 | Een korte introductievideo 75 | Automatically translated. 76 | 77 | 78 | Mijn apps 79 | Manually overriden. 80 | 81 | 82 | Catalogus 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.es.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Primeros pasos 63 | Automatically translated. 64 | 65 | 66 | Cerrar 67 | Automatically translated. 68 | 69 | 70 | Volver a jugar 71 | Automatically translated. 72 | 73 | 74 | Un breve vídeo de introducción 75 | Automatically translated. 76 | 77 | 78 | Mis apps 79 | Manually overriden. 80 | 81 | 82 | Catálogo 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.pl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Pierwsze kroki 63 | Automatically translated. 64 | 65 | 66 | Zamknij 67 | Automatically translated. 68 | 69 | 70 | Odtwórz ponownie 71 | Automatically translated. 72 | 73 | 74 | Krótki film wprowadzający 75 | Automatically translated. 76 | 77 | 78 | Moje aplikacje 79 | Automatically translated. 80 | 81 | 82 | Katalog 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.ru.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Начало работы 63 | Automatically translated. 64 | 65 | 66 | Закрыть 67 | Automatically translated. 68 | 69 | 70 | Играть заново 71 | Automatically translated. 72 | 73 | 74 | Короткий вступительный ролик 75 | Automatically translated. 76 | 77 | 78 | Мои приложения 79 | Automatically translated. 80 | 81 | 82 | Каталог 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.ro.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Noțiuni introductive 63 | Automatically translated. 64 | 65 | 66 | Închide 67 | Automatically translated. 68 | 69 | 70 | Redă din nou 71 | Automatically translated. 72 | 73 | 74 | O scurtă introducere video 75 | Automatically translated. 76 | 77 | 78 | Aplicațiile mele 79 | Automatically translated. 80 | 81 | 82 | Catalog 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/IntroDialog.pt-PT.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Introdução 63 | Automatically translated. 64 | 65 | 66 | Fechar 67 | Automatically translated. 68 | 69 | 70 | Reproduzir novamente 71 | Automatically translated. 72 | 73 | 74 | Um pequeno vídeo de introdução 75 | Automatically translated. 76 | 77 | 78 | As minhas aplicações 79 | Automatically translated. 80 | 81 | 82 | Catálogo de produtos 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Central.WinForms/AppDropDown.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using ZeroInstall.Commands; 5 | using ZeroInstall.Commands.Desktop; 6 | using ZeroInstall.DesktopIntegration; 7 | 8 | namespace ZeroInstall.Central.WinForms; 9 | 10 | /// 11 | /// Drop-down for adding/removing/integrating an app. 12 | /// 13 | public sealed partial class AppDropDown : DropDownContainer 14 | { 15 | private readonly FeedUri _interfaceUri; 16 | private readonly bool _machineWide; 17 | private AppTileStatus _status; 18 | 19 | /// 20 | /// Creates a new app popup. 21 | /// 22 | /// The interface URI of the application. 23 | /// Describes whether the application is listed in the and if so whether it is integrated. 24 | /// Apply operations machine-wide instead of just for the current user. 25 | public AppDropDown(FeedUri interfaceUri, AppTileStatus status, bool machineWide) 26 | { 27 | InitializeComponent(); 28 | Font = DefaultFonts.Modern; 29 | 30 | HandleCreated += delegate { RefreshStatus(); }; 31 | 32 | _interfaceUri = interfaceUri; 33 | _machineWide = machineWide; 34 | _status = status; 35 | } 36 | 37 | private void RefreshStatus() 38 | { 39 | var scale = this.GetScaleFactor(); 40 | 41 | void ShowButtons() 42 | { 43 | buttonIntegrate.Image = AppResources.IntegratedImage.Get(scale); 44 | buttonRemove.Image = AppResources.CandidateImage.Get(scale); 45 | buttonRemove.Show(); 46 | if (!Locations.IsPortable) 47 | { 48 | buttonIntegrate.Show(); 49 | buttonIntegrate.Focus(); 50 | } 51 | } 52 | 53 | switch (_status) 54 | { 55 | case AppTileStatus.Candidate: 56 | AddApp(); 57 | break; 58 | 59 | case AppTileStatus.Added: 60 | labelStatus.Text = AppResources.AddedText; 61 | buttonIntegrate.Text = AppResources.IntegrateText; 62 | buttonRemove.Text = AppResources.RemoveText; 63 | ShowButtons(); 64 | break; 65 | 66 | case AppTileStatus.Integrated: 67 | labelStatus.Text = AppResources.IntegratedText; 68 | buttonIntegrate.Text = AppResources.ModifyText; 69 | buttonRemove.Text = AppResources.RemoveText; 70 | ShowButtons(); 71 | break; 72 | } 73 | } 74 | 75 | private async void AddApp() 76 | { 77 | labelStatus.Text = AppResources.Working; 78 | 79 | if (await RunCommandAsync(Commands.Desktop.AddApp.Name, "--background") == ExitCode.OK) 80 | { 81 | _status = AppTileStatus.Added; 82 | RefreshStatus(); 83 | } 84 | else Close(); 85 | } 86 | 87 | private async void buttonIntegrate_Click(object sender, EventArgs e) 88 | { 89 | labelStatus.Text = AppResources.Working; 90 | Enabled = false; 91 | await RunCommandAsync(IntegrateApp.Name); 92 | Close(); 93 | } 94 | 95 | private async void buttonRemove_Click(object sender, EventArgs e) 96 | { 97 | labelStatus.Text = AppResources.Working; 98 | Enabled = false; 99 | await RunCommandAsync(RemoveApp.Name); 100 | Close(); 101 | } 102 | 103 | private Task RunCommandAsync(params string[] args) 104 | => CommandUtils.RunAsync(_machineWide 105 | ? [..args, "--machine", _interfaceUri.ToStringRfc()] 106 | : [..args, _interfaceUri.ToStringRfc()]); 107 | } 108 | -------------------------------------------------------------------------------- /src/Store.Service/Properties/Resources.zh.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | 用户 "{0}"未能将执行 "{1}"添加到 "{2}"。 63 | Automatically translated. 64 | 65 | 66 | 在 "{1}"中为用户 "{0}"创建临时目录失败。 67 | Automatically translated. 68 | 69 | 70 | 删除临时目录 "{1}"(为用户 "{0}"创建)失败。 71 | Automatically translated. 72 | 73 | 74 | 该服务无法在便携模式下运行! 75 | Automatically translated. 76 | 77 | 78 | 设置文件权限 79 | Automatically translated. 80 | 81 | 82 | 用户 "{0}"成功地将执行程序 "{1}"添加到了 "{2}"。 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Commands.WinForms/FeedSearchDialog.cs: -------------------------------------------------------------------------------- 1 | // Copyright Bastian Eicher et al. 2 | // Licensed under the GNU Lesser Public License 3 | 4 | using System.Diagnostics; 5 | using ZeroInstall.Commands.Basic; 6 | using ZeroInstall.Commands.Desktop; 7 | using ZeroInstall.Store.Configuration; 8 | using ZeroInstall.Store.Feeds; 9 | 10 | namespace ZeroInstall.Commands.WinForms; 11 | 12 | /// 13 | /// Displays the results of a feed search to the user and allows them to perform additional searches. 14 | /// 15 | public sealed partial class FeedSearchDialog : Form 16 | { 17 | private List _results; 18 | 19 | /// 20 | /// Creates a new feed search dialog. 21 | /// 22 | /// The keywords that were searched for. 23 | /// The results of the search. 24 | public FeedSearchDialog(string? keywords, IEnumerable results) 25 | { 26 | InitializeComponent(); 27 | Font = DefaultFonts.Modern; 28 | this.PreventPinningIfNotIntegrated(); 29 | 30 | textKeywords.Text = keywords ?? ""; 31 | textKeywords.TextChanged += textKeywords_TextChanged; 32 | 33 | dataGrid.AutoGenerateColumns = false; 34 | dataGrid.DataSource = _results = results.ToList(); 35 | } 36 | 37 | private async void textKeywords_TextChanged(object sender, EventArgs e) 38 | { 39 | var cancellationToken = PreventConcurrentRequests(); 40 | string keywords = textKeywords.Text; 41 | 42 | try 43 | { 44 | await Task.Delay(200, cancellationToken); 45 | dataGrid.DataSource = _results = await Task.Run(() => SearchResults.Query(Config.Load(), keywords), cancellationToken); 46 | } 47 | catch (OperationCanceledException) 48 | {} 49 | catch (Exception ex) 50 | { 51 | errorProvider.SetIconAlignment(textKeywords, ErrorIconAlignment.MiddleLeft); 52 | errorProvider.SetError(textKeywords, ex.Message); 53 | } 54 | } 55 | 56 | private CancellationTokenSource _cts = new(); 57 | 58 | private CancellationToken PreventConcurrentRequests() 59 | { 60 | _cts.Cancel(); 61 | _cts = new(); 62 | return _cts.Token; 63 | } 64 | 65 | private void dataGrid_CellContentClick(object sender, DataGridViewCellEventArgs e) 66 | { 67 | if (e.ColumnIndex == columnUri.Index) 68 | contextMenu.Show(Cursor.Position); 69 | } 70 | 71 | private void buttonRun_Click(object sender, EventArgs e) 72 | { 73 | if (dataGrid.CurrentRow == null) return; 74 | var result = _results[dataGrid.CurrentRow.Index]; 75 | 76 | CommandUtils.Start(Run.Name, "--no-wait", result.Uri!.ToStringRfc()); 77 | } 78 | 79 | private void buttonAdd_Click(object sender, EventArgs e) 80 | { 81 | if (dataGrid.CurrentRow == null) return; 82 | var result = _results[dataGrid.CurrentRow.Index]; 83 | 84 | CommandUtils.Start(AddApp.Name, result.Uri!.ToStringRfc()); 85 | } 86 | 87 | private void buttonIntegrate_Click(object sender, EventArgs e) 88 | { 89 | if (dataGrid.CurrentRow == null) return; 90 | var result = _results[dataGrid.CurrentRow.Index]; 91 | 92 | CommandUtils.Start(IntegrateApp.Name, result.Uri!.ToStringRfc()); 93 | } 94 | 95 | private void buttonDetails_Click(object sender, EventArgs e) 96 | { 97 | if (dataGrid.CurrentRow == null) return; 98 | var result = _results[dataGrid.CurrentRow.Index]; 99 | 100 | try 101 | { 102 | Process.Start(result.Uri!.ToStringRfc()); 103 | } 104 | #region Error handling 105 | catch (Exception ex) 106 | { 107 | Msg.Inform(this, ex.Message, MsgSeverity.Error); 108 | } 109 | #endregion 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/Store.Service/Properties/Resources.ko.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | 사용자 '{0}' 구현 '{1}' 을 '{2}' 에 추가하지 못했습니다. 63 | Automatically translated. 64 | 65 | 66 | '{1}' 에 '{0}' 사용자에 대한 임시 디렉터리를 만들지 못했습니다. 67 | Automatically translated. 68 | 69 | 70 | 임시 디렉터리 '{1}'(사용자 '{0}' 용으로 생성됨)를 제거하지 못했습니다. 71 | Automatically translated. 72 | 73 | 74 | 휴대용 모드에서는 서비스를 실행할 수 없습니다! 75 | Automatically translated. 76 | 77 | 78 | 파일 권한 설정 79 | Automatically translated. 80 | 81 | 82 | '{0}' 사용자가 '{1}' 구현을 '{2}' 에 성공적으로 추가했습니다. 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Store.Service/Properties/Resources.ja.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | ユーザー '{0}' は、実装 '{1}' を '{2}' に追加できませんでした。 63 | Automatically translated. 64 | 65 | 66 | {1}' のユーザー '{0}' のテンポラリディレクトリの作成に失敗しました。 67 | Automatically translated. 68 | 69 | 70 | 一時ディレクトリ '{1}' (ユーザー '{0}' 用に作成) の削除に失敗しました。 71 | Automatically translated. 72 | 73 | 74 | ポータブルモードでは実行できません! 75 | Automatically translated. 76 | 77 | 78 | ファイルパーミッションの設定 79 | Automatically translated. 80 | 81 | 82 | ユーザー '{0}' は、実装 '{1}' を '{2}' に追加することに成功しました。 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Store.Service/Properties/Resources.tr.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | '{0}' kullanıcısı '{1}' uyarlamasını '{2}' üzerine ekleyemedi. 63 | Manually overriden. 64 | 65 | 66 | '{0}' kullanıcısı için '{1}' üzerinde bir geçici klasör oluşturulamadı. 67 | Manually overriden. 68 | 69 | 70 | ('{0}' kullanıcısı için) '{1}' üzerinde oluşturulan geçici klasör kaldırılamadı. 71 | Manually overriden. 72 | 73 | 74 | Bu hizmet taşınabilir kipte çalıştırılamaz! 75 | Manually overriden. 76 | 77 | 78 | Dosya izinleri ayarlanıyor 79 | Manually overriden. 80 | 81 | 82 | '{0}' kullanıcısı '{1}' uyarlamasını '{2}' üzerine ekledi. 83 | Manually overriden. 84 | 85 | -------------------------------------------------------------------------------- /src/Store.Service/Properties/Resources.pt-BR.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | O usuário '{0}' falhou ao adicionar a implementação '{1}' em '{2}'. 63 | Manually overriden. 64 | 65 | 66 | Falha ao criar pasta temporária para o usuário '{0}' em '{1}'. 67 | Manually overriden. 68 | 69 | 70 | Falha ao remover a pasta temporária '{1}' (criada para o usuário '{0}'). 71 | Manually overriden. 72 | 73 | 74 | O serviço não pode ser executado no modo portátil! 75 | Manually overriden. 76 | 77 | 78 | Configurando permissões de arquivo 79 | Manually overriden. 80 | 81 | 82 | O usuário '{0}' adicionou com sucesso a implementação '{1}' em '{2}'. 83 | Manually overriden. 84 | 85 | -------------------------------------------------------------------------------- /src/Store.Service/Properties/Resources.id.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Pengguna '{0}' gagal menambahkan implementasi '{1}' ke '{2}'. 63 | Automatically translated. 64 | 65 | 66 | Gagal membuat direktori sementara untuk pengguna '{0}' di '{1}'. 67 | Automatically translated. 68 | 69 | 70 | Gagal menghapus direktori sementara '{1}' (dibuat untuk pengguna '{0}'). 71 | Automatically translated. 72 | 73 | 74 | Layanan ini tidak dapat berjalan dalam mode portabel! 75 | Automatically translated. 76 | 77 | 78 | Mengatur izin file 79 | Automatically translated. 80 | 81 | 82 | Pengguna '{0}' berhasil menambahkan implementasi '{1}' ke '{2}'. 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Store.Service/Properties/Resources.cs.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Uživateli '{0}' se nepodařilo přidat implementaci '{1}' do '{2}'. 63 | Automatically translated. 64 | 65 | 66 | Nepodařilo se vytvořit dočasný adresář pro uživatele '{0}' v '{1}'. 67 | Automatically translated. 68 | 69 | 70 | Nepodařilo se odstranit dočasný adresář '{1}' (vytvořený pro uživatele '{0}'). 71 | Automatically translated. 72 | 73 | 74 | Službu nelze spustit v přenosném režimu! 75 | Automatically translated. 76 | 77 | 78 | Nastavení oprávnění k souborům 79 | Automatically translated. 80 | 81 | 82 | Uživatel '{0}' úspěšně přidal implementaci '{1}' do '{2}'. 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Store.Service/Properties/Resources.pl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Użytkownik '{0}' nie dodał implementacji '{1}' do '{2}'. 63 | Automatically translated. 64 | 65 | 66 | Nie udało się utworzyć katalogu tymczasowego dla użytkownika '{0}' w '{1}'. 67 | Automatically translated. 68 | 69 | 70 | Nie udało się usunąć katalogu tymczasowego '{1}' (utworzonego dla użytkownika '{0}'). 71 | Automatically translated. 72 | 73 | 74 | Usługa nie może działać w trybie przenośnym! 75 | Automatically translated. 76 | 77 | 78 | Ustawianie uprawnień do plików 79 | Automatically translated. 80 | 81 | 82 | Użytkownik '{0}' pomyślnie dodał implementację '{1}' do '{2}'. 83 | Automatically translated. 84 | 85 | -------------------------------------------------------------------------------- /src/Store.Service/Properties/Resources.ru.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Пользователю '{0}' не удалось добавить реализацию '{1}' в '{2}'. 63 | Automatically translated. 64 | 65 | 66 | Не удалось создать временный каталог для пользователя '{0}' в '{1}'. 67 | Automatically translated. 68 | 69 | 70 | Не удалось удалить временный каталог '{1}' (созданный для пользователя '{0}'). 71 | Automatically translated. 72 | 73 | 74 | Служба не может работать в портативном режиме! 75 | Automatically translated. 76 | 77 | 78 | Установка прав доступа к файлам 79 | Automatically translated. 80 | 81 | 82 | Пользователь '{0}' успешно добавил реализацию '{1}' на '{2}'. 83 | Automatically translated. 84 | 85 | --------------------------------------------------------------------------------