コード例 #1
0
        public void Run()
        {
            try
            {
                DirectoryEx.EnsureExists(this.PackagesBackupPath);

                IList <PackageEdit> edits;
                using (var connection = this.PackageDatabase.ConnectTo())
                {
                    edits = connection.Query <PackageEdit>(GetEditsBaseSql).ToList();
                }

                Log.Info("Fetched {2} queued edits from {0}/{1}", PackageDatabase.DataSource, PackageDatabase.InitialCatalog, edits.Count);

                // Group by package and take just the most recent edit for each package
                edits = edits.GroupBy(e => e.PackageKey)
                        .Select(g => g.OrderByDescending(e => e.Timestamp).FirstOrDefault())
                        .Where(e => e != null)
                        .ToList();

                foreach (var edit in edits)
                {
                    Exception thrown = null;
                    try
                    {
                        this.ApplyEdit(edit);
                    }
                    catch (Exception ex)
                    {
                        thrown = ex;
                    }

                    if (thrown != null)
                    {
                        using (var connection = this.PackageDatabase.ConnectTo())
                        {
                            connection.Query <int>(@"
                            UPDATE  PackageEdits
                            SET
                                    TriedCount = TriedCount + 1,
                                    LastError = @error
                            WHERE   [Key] = @key", new { error = thrown.ToString(), key = edit.Key });
                        }
                    }
                }
            }
            finally
            {
                DirectoryEx.TryDelete(this.PackagesTempPath);
            }
        }
コード例 #2
0
        private void MainForm_Load(object sender, EventArgs e)
        {
            // Check internet connection
            if (!Network.InternetIsAvailable)
            {
                Environment.ExitCode = 1;
                Application.Exit();
                return;
            }

            // Get update infos from GitHub if enabled
            if (Settings.UpdateChannel == Settings.UpdateChannelOptions.Beta)
            {
                if (!NetEx.IPv4IsAvalaible && NetEx.IPv6IsAvalaible)
                {
                    Environment.ExitCode = 1;
                    Application.Exit();
                    return;
                }
                SetUpdateInfo(false, CorePaths.RepoSnapshotsUrl);
            }

            // Get update infos if not already set
            if (string.IsNullOrWhiteSpace(HashInfo))
            {
                DownloadMirrors.AddRange(new[]
                {
                    "https://port-a.de",
                    "https://p-able.de",

                    // Backup
                    "https://dl.si13n7.de/Port-Able",
                    "https://dl.si13n7.com/Port-Able",

                    // Reserved
                    "http://dl-0.de/Port-Able",
                    "http://dl-1.de/Port-Able",
                    "http://dl-2.de/Port-Able",
                    "http://dl-3.de/Port-Able",
                    "http://dl-4.de/Port-Able",
                    "http://dl-5.de/Port-Able"
                });
                if (!DownloadMirrors.Any())
                {
                    Environment.ExitCode = 1;
                    Application.Exit();
                    return;
                }
                SetUpdateInfo(true, DownloadMirrors.ToArray());
            }
            if (string.IsNullOrWhiteSpace(HashInfo))
            {
                Environment.ExitCode = 1;
                Application.Exit();
                return;
            }

            // Compare hashes
            var updateAvailable = false;

            try
            {
                foreach (var key in Ini.GetKeys("SHA256", HashInfo))
                {
                    var file = PathEx.Combine(PathEx.LocalDir, $"{key}.exe");
                    if (!File.Exists(file))
                    {
                        file = Path.Combine(CorePaths.HomeDir, $"{key}.exe");
                    }
                    if (Ini.Read("SHA256", key, HashInfo).EqualsEx(file.EncryptFile(ChecksumAlgorithm.Sha256)))
                    {
                        continue;
                    }
                    updateAvailable = true;
                    break;
                }
            }
            catch (Exception ex) when(ex.IsCaught())
            {
                Log.Write(ex);
                Environment.ExitCode = 1;
                Application.Exit();
                return;
            }

            // Install updates
            if (updateAvailable)
            {
                if (string.IsNullOrEmpty(CorePaths.FileArchiver))
                {
                    if (MessageBox.Show(Language.GetText(nameof(en_US.RequirementsErrorMsg)), Text, MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.Yes)
                    {
                        Process.Start(CorePaths.RepoReleasesUrl);
                    }
                    Environment.ExitCode = 1;
                    Environment.Exit(Environment.ExitCode);
                }
                if (MessageBox.Show(Language.GetText(nameof(en_US.UpdateAvailableMsg)), Text, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                {
                    SetChangeLog(DownloadMirrors.ToArray());
                    ShowInTaskbar = true;
                    FormEx.Dockable(this);
                    return;
                }
                DirectoryEx.TryDelete(CachePaths.UpdateDir);
            }

            // Exit the application if no updates were found
            Environment.ExitCode = 2;
            Application.Exit();
        }
コード例 #3
0
        private static void UpdateAppInfoFile()
        {
            ResetAppInfoFile();
            if (_appInfo?.Count > 430)
            {
                goto Shareware;
            }

            foreach (var mirror in AppSupply.GetMirrors(AppSuppliers.Internal))
            {
                var link = PathEx.AltCombine(mirror, ".free", "AppInfo.ini");
                if (Log.DebugMode > 0)
                {
                    Log.Write($"Cache: Looking for '{link}'.");
                }
                if (NetEx.FileIsAvailable(link, 30000, UserAgents.Internal))
                {
                    NetEx.Transfer.DownloadFile(link, CachePaths.AppInfo, 60000, UserAgents.Internal, false);
                }
                if (!File.Exists(CachePaths.AppInfo))
                {
                    continue;
                }
                break;
            }

            var blacklist = Array.Empty <string>();

            if (File.Exists(CachePaths.AppInfo))
            {
                blacklist = Ini.GetSections(CachePaths.AppInfo).Where(x => Ini.Read(x, "Disabled", false, CachePaths.AppInfo)).ToArray();
                UpdateAppInfoData(CachePaths.AppInfo, blacklist);
            }

            var tmpDir = Path.Combine(CorePaths.TempDir, PathEx.GetTempDirName());

            if (!DirectoryEx.Create(tmpDir))
            {
                return;
            }
            var tmpZip = Path.Combine(tmpDir, "AppInfo.7z");

            foreach (var mirror in AppSupply.GetMirrors(AppSuppliers.Internal))
            {
                var link = PathEx.AltCombine(mirror, ".free", "AppInfo.7z");
                if (Log.DebugMode > 0)
                {
                    Log.Write($"Cache: Looking for '{link}'.");
                }
                if (NetEx.FileIsAvailable(link, 30000, UserAgents.Internal))
                {
                    NetEx.Transfer.DownloadFile(link, tmpZip, 60000, UserAgents.Internal, false);
                }
                if (!File.Exists(tmpZip))
                {
                    continue;
                }
                break;
            }
            if (!File.Exists(tmpZip))
            {
                var link = PathEx.AltCombine(AppSupplierHosts.PortableApps, "updater", "update.7z");
                if (Log.DebugMode > 0)
                {
                    Log.Write($"Cache: Looking for '{link}'.");
                }
                if (NetEx.FileIsAvailable(link, 60000, UserAgents.Empty))
                {
                    NetEx.Transfer.DownloadFile(link, tmpZip, 60000, UserAgents.Empty, false);
                }
            }
            if (File.Exists(tmpZip))
            {
                using (var process = Compaction.SevenZipHelper.Unzip(tmpZip, tmpDir))
                    if (process?.HasExited == false)
                    {
                        process.WaitForExit();
                    }
                FileEx.TryDelete(tmpZip);
            }
            var tmpIni = DirectoryEx.GetFiles(tmpDir, "*.ini").FirstOrDefault();

            if (!File.Exists(tmpIni))
            {
                DirectoryEx.TryDelete(tmpDir);
                return;
            }
            UpdateAppInfoData(tmpIni, blacklist);

            FileEx.Serialize(CachePaths.AppInfo, AppInfo, true);
            DirectoryEx.TryDelete(tmpDir);

Shareware:
            if (!Shareware.Enabled)
            {
                return;
            }

            foreach (var srv in Shareware.GetAddresses())
            {
                var key = Shareware.FindAddressKey(srv);
                var usr = Shareware.GetUser(srv);
                var pwd = Shareware.GetPassword(srv);
                var url = PathEx.AltCombine(srv, "AppInfo.ini");
                if (Log.DebugMode > 0)
                {
                    Log.Write($"Shareware: Looking for '{{{key.Encode()}}}/AppInfo.ini'.");
                }
                if (!NetEx.FileIsAvailable(url, usr, pwd, 60000, UserAgents.Default))
                {
                    continue;
                }
                var appInfo = NetEx.Transfer.DownloadString(url, usr, pwd, 60000, UserAgents.Default);
                if (string.IsNullOrWhiteSpace(appInfo))
                {
                    continue;
                }
                UpdateAppInfoData(appInfo, null, key.Decode(BinaryToTextEncodings.Base85));
            }
        }
コード例 #4
0
        public static void Find(out string javaPath)
        {
            // Read saved path from config.
            javaPath = null;
            if (File.Exists(Attributes.ConfigPath))
            {
                javaPath = Ini.ReadDirect("Java", "Path", Attributes.ConfigPath);
                if (!string.IsNullOrWhiteSpace(javaPath))
                {
                    javaPath = PathEx.Combine(javaPath);
                }
                if (File.Exists(javaPath))
                {
                    goto Found;
                }
            }

            // Try getting the default path from Portable Apps Suite JRE installation.
            try
            {
                var dir = EnvironmentEx.GetVariableValue("AppsSuiteDir");
                if (Directory.Exists(dir))
                {
#if x86
                    dir = Path.Combine(dir, "Apps", "CommonFiles", "Java");
#else
                    dir = Path.Combine(dir, "Apps", "CommonFiles", "Java64");
                    if (!Directory.Exists(dir))
                    {
                        Path.Combine(dir, "Apps", "CommonFiles", "Java");
                    }
#endif
                    if (Directory.Exists(dir))
                    {
                        javaPath = GetPath(dir);
                        if (File.Exists(javaPath))
                        {
                            goto Found;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Write(ex);
            }

            // Start searching for the portable JRE, starting in the current directory.
            try
            {
                var dir = PathEx.LocalDir;
                var drive = new DriveInfo(dir).RootDirectory.Root.Name;
                int count = 0, length = dir.Split(Path.DirectorySeparatorChar).Length;
                var subs = new[]
                {
#if x64
                    "_CommonFiles\\Java64",
                    "CommonFiles\\Java64",
#endif
                    "_CommonFiles\\Java",
                    "CommonFiles\\Java"
                };
                while (!drive.ContainsEx(dir) && ++count < length)
                {
                    foreach (var sub in subs)
                    {
                        var tmp = Path.Combine(dir, sub);
                        if (!Directory.Exists(tmp))
                        {
                            continue;
                        }
                        javaPath = GetPath(tmp);
                        if (File.Exists(javaPath))
                        {
                            goto Found;
                        }
                    }
                    dir = PathEx.Combine(dir, "..").TrimEnd(Path.DirectorySeparatorChar);
                }
            }
            catch (Exception ex)
            {
                Log.Write(ex);
            }

            // Try getting the default path from the global JRE installation.
            try
            {
                var dirs = new[]
                {
                    "%ProgramFiles%\\Java",
#if x64
                    "%ProgramFiles(x86)%\\Java",
#endif
                    "%ProgramData%\\Oracle\\Java\\javapath"
                };
                foreach (var dir in dirs.Select(PathEx.Combine))
                {
                    if (!Directory.Exists(dir))
                    {
                        continue;
                    }
                    javaPath = GetPath(dir);
                    if (File.Exists(javaPath))
                    {
                        goto Found;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Write(ex);
            }

            // If JRE was not found.
            MessageBox.Show(Strings.JavaWarnMessage, AssemblyInfo.Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
            Environment.ExitCode = 1;
            Environment.Exit(Environment.ExitCode);

            // Else
Found:
            var envPath = EnvironmentEx.GetVariablePathFull(javaPath);
            Ini.WriteDirect(nameof(JavaHandler), "Path", envPath, Attributes.ConfigPath);

            var usageDir = PathEx.Combine("%UserProfile%\\.oracle_jre_usage");
            try
            {
                if (!Directory.Exists(usageDir))
                {
                    Directory.CreateDirectory(usageDir);
                }
                DirectoryEx.SetAttributes(usageDir, FileAttributes.Hidden);
            }
            catch (Exception ex)
            {
                Log.Write(ex);
            }
            AppDomain.CurrentDomain.ProcessExit += (s, e) => DirectoryEx.TryDelete(usageDir);
        }
コード例 #5
0
        private void ApplyEdit(PackageEdit edit)
        {
            // copy the original file
            string packageName  = $"{edit.Id}.{edit.Version}.nupkg".ToLower(CultureInfo.InvariantCulture);
            string originalPath = Path.Combine(this.PackagesPath, packageName);
            string backupPath   = Path.Combine(this.PackagesBackupPath, packageName);

            var    tempDir   = Path.Combine(this.PackagesTempPath, "HandlePackageEdits");
            string directory = Path.Combine(tempDir, edit.Id, edit.Version);
            string tempPath  = Path.Combine(directory, packageName);

            try
            {
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                Log.Info("Downloaded original copy of {0} {1}", edit.Id, edit.Version);
                File.Copy(originalPath, tempPath, true);

                // Load the zip file and find the manifest
                using (var originalStream = File.Open(tempPath, FileMode.Open, FileAccess.ReadWrite))
                    using (var archive = new ZipArchive(originalStream, ZipArchiveMode.Update))
                    {
                        // Find the nuspec
                        var nuspecEntries = archive.Entries.Where(e => ManifestSelector.IsMatch(e.FullName)).ToArray();
                        if (nuspecEntries.Length == 0)
                        {
                            throw new InvalidDataException(
                                      string.Format(
                                          CultureInfo.CurrentCulture,
                                          "Package has no manifest: {0} {1} (URL: {2})",
                                          edit.Id,
                                          edit.Version,
                                          tempPath));
                        }

                        if (nuspecEntries.Length > 1)
                        {
                            throw new InvalidDataException(
                                      string.Format(
                                          CultureInfo.CurrentCulture,
                                          "Package has multiple manifests: {0} {1} (URL: {2})",
                                          edit.Id,
                                          edit.Version,
                                          tempPath));
                        }

                        // We now have the nuspec
                        var manifestEntry = nuspecEntries.Single();

                        // Load the manifest with a constrained stream
                        Log.Info("Rewriting package file for {0} {1}", edit.Id, edit.Version);
                        using (var manifestStream = manifestEntry.Open())
                        {
                            var manifest = Manifest.ReadFrom(manifestStream, validateSchema: false);

                            // Modify the manifest as per the edit
                            edit.ApplyTo(manifest.Metadata);

                            // Save the manifest back
                            manifestStream.Seek(0, SeekOrigin.Begin);
                            manifestStream.SetLength(0);
                            manifest.Save(manifestStream);
                        }

                        Log.Info("Rewrote package file for {0} {1}", edit.Id, edit.Version);
                    }

                // replace original file and back it up
                Log.Info("Replacing original package file for {0} {1} ({2}, backup location {3}).", edit.Id, edit.Version, originalPath, backupPath);
                File.Replace(tempPath, originalPath, backupPath);

                // Calculate new size and hash
                string hash;
                long   size;
                using (var originalStream = File.OpenRead(originalPath))
                {
                    size = originalStream.Length;

                    var hashAlgorithm = HashAlgorithm.Create(HashAlgorithmName);
                    if (hashAlgorithm == null)
                    {
                        throw new InvalidOperationException($"Failed to create instance of hash algorithm {HashAlgorithmName}.");
                    }

                    hash = Convert.ToBase64String(hashAlgorithm.ComputeHash(originalStream));
                }

                // Update the database
                Log.Info("Updating package record for {0} {1}", edit.Id, edit.Version);
                using (var connection = this.PackageDatabase.ConnectTo())
                {
                    var parameters =
                        new DynamicParameters(
                            new
                    {
                        edit.Authors,
                        edit.Copyright,
                        edit.Description,
                        edit.IconUrl,
                        edit.LicenseUrl,
                        edit.ProjectUrl,
                        edit.ReleaseNotes,
                        edit.RequiresLicenseAcceptance,
                        edit.Summary,
                        edit.Title,
                        edit.Tags,
                        edit.Key,
                        edit.PackageKey,
                        edit.UserKey,
                        PackageFileSize = size,
                        Hash            = hash,
                        HashAlgorithm   = HashAlgorithmName
                    });

                    // Prep SQL for merging in authors
                    StringBuilder loadAuthorsSql = new StringBuilder();
                    var           authors        = edit.Authors.Split(',');
                    for (int i = 0; i < authors.Length; i++)
                    {
                        loadAuthorsSql.Append("INSERT INTO [PackageAuthors]([PackageKey],[Name]) VALUES(@PackageKey, @Author" + i + ")");
                        parameters.Add("Author" + i, authors[i]);
                    }

                    connection.Query <int>(@"
                            BEGIN TRANSACTION
                                -- Form a comma-separated list of authors
                                DECLARE @existingAuthors nvarchar(MAX)
                                SELECT @existingAuthors = COALESCE(@existingAuthors + ',', '') + Name
                                FROM PackageAuthors
                                WHERE PackageKey = @PackageKey

                                -- Copy packages data to package history table
                                INSERT INTO [PackageHistories]
                                SELECT      [Key] AS PackageKey,
                                            @UserKey AS UserKey,
                                            GETUTCDATE() AS Timestamp,
                                            Title,
                                            @existingAuthors AS Authors,
                                            Copyright,
                                            Description,
                                            IconUrl,
                                            LicenseUrl,
                                            ProjectUrl,
                                            ReleaseNotes,
                                            RequiresLicenseAcceptance,
                                            Summary,
                                            Tags,
                                            Hash,
                                            HashAlgorithm,
                                            PackageFileSize,
                                            LastUpdated,
                                            Published
                                FROM        [Packages]
                                WHERE       [Key] = @PackageKey

                                -- Update the packages table
                                UPDATE  [Packages]
                                SET     Copyright = @Copyright,
                                        Description = @Description,
                                        IconUrl = @IconUrl,
                                        LicenseUrl = @LicenseUrl,
                                        ProjectUrl = @ProjectUrl,
                                        ReleaseNotes = @ReleaseNotes,
                                        RequiresLicenseAcceptance = @RequiresLicenseAcceptance,
                                        Summary = @Summary,
                                        Title = @Title,
                                        Tags = @Tags,
                                        LastEdited = GETUTCDATE(),
                                        LastUpdated = GETUTCDATE(),
                                        UserKey = @UserKey,
                                        Hash = @Hash,
                                        HashAlgorithm = @HashAlgorithm,
                                        PackageFileSize = @PackageFileSize,
                                        FlattenedAuthors = @Authors
                                WHERE   [Key] = @PackageKey

                                -- Update Authors
                                DELETE FROM [PackageAuthors] 
                                WHERE PackageKey = @PackageKey

                                " + loadAuthorsSql + @"
                            
                                -- Clean this edit and all previous edits.
                                DELETE FROM [PackageEdits]
                                WHERE [PackageKey] = @PackageKey
                                AND [Key] <= @Key

                                COMMIT TRANSACTION", parameters);
                }

                Log.Info("Updated package record for {0} {1}", edit.Id, edit.Version);
            }
            catch (Exception ex)
            {
                Log.Error("Failed to update package information. Package {0} {1}. Exception {2}", edit.Id, edit.Version, ex.Message);
                throw;
            }
            finally
            {
                DirectoryEx.TryDelete(directory);
            }
        }