Beispiel #1
0
        public InstallStatus InstallFiles()
        {
            var status = InstallStatus.Success;
            bool restartRequired = false;
            string oldFilesPath = Path.Combine("_update", "oldfiles");
            string newFilesPath = Path.Combine("_update", "files", "HomeGenie_update");
            string fullReleaseFolder = Path.Combine("_update", "files", "homegenie");
            if (Directory.Exists(fullReleaseFolder))
            {
                Directory.Move(fullReleaseFolder, newFilesPath);
            }
            Utility.FolderCleanUp(oldFilesPath);
            if (Directory.Exists(newFilesPath))
            {
                LogMessage("= Copying new files...");
                foreach (string file in Directory.EnumerateFiles(newFilesPath, "*", SearchOption.AllDirectories))
                {
                    bool doNotCopy = false;

                    string destinationFolder = Path.GetDirectoryName(file).Replace(newFilesPath, "").TrimStart('/').TrimStart('\\');
                    string destinationFile = Path.Combine(destinationFolder, Path.GetFileName(file)).TrimStart(Directory.GetDirectoryRoot(Directory.GetCurrentDirectory()).ToArray()).TrimStart('/').TrimStart('\\');

                    // Update file only if different from local one
                    bool processFile = false;
                    if (File.Exists(destinationFile))
                    {
                        using (var md5 = MD5.Create())
                        {
                            string localHash, remoteHash = "";
                            try
                            {
                                // Try getting files' hash
                                using (var stream = File.OpenRead(destinationFile))
                                {
                                    localHash = BitConverter.ToString(md5.ComputeHash(stream));
                                }
                                using (var stream = File.OpenRead(file))
                                {
                                    remoteHash = BitConverter.ToString(md5.ComputeHash(stream));
                                }
                                if (localHash != remoteHash)
                                {
                                    processFile = true;
                                    //Console.WriteLine("CHANGED {0}", destinationFile);
                                    //Console.WriteLine("   - LOCAL  {0}", localHash);
                                    //Console.WriteLine("   - REMOTE {0}", remoteHash);
                                }
                            }
                            catch (Exception e)
                            {
                                // this mostly happen if the destinationFile is un use and cannot be opened,
                                // file is then ignored if hash cannot be calculated
                            }
                        }
                    }
                    else
                    {
                        processFile = true;
                        //Console.WriteLine("NEW FILE {0}", file);
                    }

                    if (!processFile) continue;

                    // Some files needs to be handled differently than just copying
                    if (destinationFile.EndsWith(".xml") && File.Exists(destinationFile))
                    {
                        switch (destinationFile)
                        {
                            case "automationgroups.xml":
                                doNotCopy = true;
                                status = UpdateAutomationGroups(file) ? InstallStatus.Success : InstallStatus.Error;;
                                break;
                            case "groups.xml":
                                doNotCopy = true;
                                status = UpdateGroups(file) ? InstallStatus.Success : InstallStatus.Error;
                                break;
                            case "lircconfig.xml":
                                doNotCopy = true;
                                break;
                            case "modules.xml":
                                doNotCopy = true;
                                break;
                            case "programs.xml":
                                doNotCopy = true;
                                status = UpdatePrograms(file) ? InstallStatus.Success : InstallStatus.Error;;
                                break;
                            case "scheduler.xml":
                                doNotCopy = true;
                                status = UpdateScheduler(file) ? InstallStatus.Success : InstallStatus.Error;;
                                break;
                            case "systemconfig.xml":
                                doNotCopy = true;
                                status = UpdateSystemConfig(file) ? InstallStatus.Success : InstallStatus.Error;;
                                break;
                        }
                        if (status == InstallStatus.Error)
                        {
                            break;
                        }
                    }
                    else if (destinationFile.EndsWith("homegenie_stats.db"))
                    {
                        doNotCopy = true;
                    }

                    if (doNotCopy) continue;
                    
                    // Update the file
                    if (destinationFile.EndsWith(".exe") || destinationFile.EndsWith(".dll") || destinationFile.EndsWith(".so"))
                        restartRequired = true;

                    if (!String.IsNullOrWhiteSpace(destinationFolder) && !Directory.Exists(destinationFolder))
                    {
                        Directory.CreateDirectory(destinationFolder);
                    }

                    // backup current file before replacing it
                    if (File.Exists(destinationFile))
                    {
                        string oldFile = Path.Combine(oldFilesPath, destinationFile);
                        Directory.CreateDirectory(Path.GetDirectoryName(oldFile));

                        LogMessage("+ Backup file '" + oldFile + "'");

                        // TODO: delete oldFilesPath before starting update
                        //File.Delete(oldFile); 

                        if (destinationFile.EndsWith(".exe") || destinationFile.EndsWith(".dll"))
                        {
                            // this will allow replace of new exe and dll files
                            File.Move(destinationFile, oldFile);
                        }
                        else
                        {
                            File.Copy(destinationFile, oldFile);
                        }
                    }

                    try
                    {
                        LogMessage("+ Copying file '" + destinationFile + "'");
                        if (!string.IsNullOrWhiteSpace(Path.GetDirectoryName(destinationFile)) && !Directory.Exists(Path.GetDirectoryName(destinationFile)))
                        {
                            try
                            {
                                Directory.CreateDirectory(Path.GetDirectoryName(destinationFile));
                                LogMessage("+ Created folder '" + Path.GetDirectoryName(destinationFile) + "'");
                            }
                            catch
                            {
                            }
                        }
                        File.Copy(file, destinationFile, true);
                    }
                    catch (Exception e)
                    {
                        LogMessage("! Error copying file '" + destinationFile + "' (" + e.Message + ")");
                        status = InstallStatus.Error;
                        break;
                    }

                }

                if (status == InstallStatus.Error)
                {
                    // TODO: should revert!
                    LogMessage("! ERROR update aborted.");
                }
                else if (restartRequired)
                {
                    status = InstallStatus.RestartRequired;
                }

            }

            return status;
        }
Beispiel #2
0
        public bool UpdatePrograms(string file)
        {
            bool success = true;
            try
            {
                var serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                var reader = new StreamReader(file);
                var newProgramList = (List<ProgramBlock>)serializer.Deserialize(reader);
                reader.Close();
                //
                if (newProgramList.Count > 0)
                {
                    bool configChanged = false;
                    foreach (var program in newProgramList)
                    {

                        // Only system programs are to be updated
                        if (program.Address < ProgramManager.USERSPACE_PROGRAMS_START)
                        {
                            ProgramBlock oldProgram = homegenie.ProgramManager.Programs.Find(p => p.Address == program.Address);
                            if (oldProgram != null)
                            {

                                // Check new program against old one to find out if they differ
                                bool changed = ProgramsDiff(oldProgram, program);
                                if (!changed)
                                    continue;

                                // Preserve IsEnabled status if program already exist
                                program.IsEnabled = oldProgram.IsEnabled;
                                LogMessage("* Updating Automation Program: " + program.Name + " (" + program.Address + ")");
                                homegenie.ProgramManager.ProgramRemove(oldProgram);

                            }
                            else
                            {
                                LogMessage("+ Adding Automation Program: " + program.Name + " (" + program.Address + ")");
                            }

                            // Try copying the new program files if it's an arduino sketch
                            if (program.Type.ToLower() == "arduino")
                            {
                                try
                                {
                                    // copy arduino project files...
                                    // TODO: this is untested yet
                                    string sourceFolder = Path.Combine(UpdateBaseFolder, "programs", "arduino", program.Address.ToString());
                                    string arduinoFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", "arduino", program.Address.ToString());
                                    Utility.FolderCleanUp(arduinoFolder);
                                    foreach (string newPath in Directory.GetFiles(sourceFolder))
                                    {
                                        File.Copy(newPath, newPath.Replace(sourceFolder, arduinoFolder), true);
                                        LogMessage("* Updating Automation Program: " + program.Name + " (" + program.Address + ") - " + Path.GetFileName(newPath));
                                    }
                                }
                                catch
                                {
                                    // TODO: should report exception
                                }
                            }

                            // Add the new program to the ProgramEngine
                            homegenie.ProgramManager.ProgramAdd(program);
                            
                            // Compile C# programs in order to generate new binary file
                            if (program.Type.ToLower() == "csharp")
                            {
                                homegenie.ProgramManager.CompileScript(program);
                            }

                            if (!configChanged)
                                configChanged = true;
                        }

                    }

                    if (configChanged)
                    {
                        // Save new programs config
                        homegenie.UpdateProgramsDatabase();
                    }
                }
                //
                File.Delete(file);
                if (Directory.Exists(Path.Combine(homegenie.UpdateChecker.UpdateBaseFolder, "programs")))
                {
                    Directory.Delete(Path.Combine(homegenie.UpdateChecker.UpdateBaseFolder, "programs"), true);
                }
            }
            catch
            {
                success = false;
            }

            if (!success)
            {
                LogMessage("+ ERROR updating Automation Programs");
            }
            return success;
        }
Beispiel #3
0
        public List<string> DownloadAndUncompress(ReleaseInfo releaseInfo)
        {
            if (ArchiveDownloadUpdate != null)
                ArchiveDownloadUpdate(this, new ArchiveDownloadEventArgs(releaseInfo, ArchiveDownloadStatus.DOWNLOADING));
            //
            string destinationFolder = Path.Combine(updateFolder, "files");
            string archiveName = Path.Combine(updateFolder, "archives", "hg_update_" + releaseInfo.Version.Replace(" ", "_").Replace(".", "_") + ".zip");
            if (!Directory.Exists(Path.GetDirectoryName(archiveName)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(archiveName));
            }
            using (var client = new WebClientPx())
            {
                client.Headers.Add("user-agent", "HomeGenieUpdater/1.0 (compatible; MSIE 7.0; Windows NT 6.0)");
                try
                {
                    client.DownloadFile(releaseInfo.DownloadUrl, archiveName);
                }
                catch (Exception)
                {
                    if (ArchiveDownloadUpdate != null)
                        ArchiveDownloadUpdate(this, new ArchiveDownloadEventArgs(releaseInfo, ArchiveDownloadStatus.ERROR));
                    return null;
                    //                throw;
                }
                finally
                {
                    client.Dispose();
                }
            }

            // Unarchive (unzip)
            if (ArchiveDownloadUpdate != null)
                ArchiveDownloadUpdate(this, new ArchiveDownloadEventArgs(releaseInfo, ArchiveDownloadStatus.DECOMPRESSING));

            bool errorOccurred = false;
            var files = Utility.UncompressTgz(archiveName, destinationFolder);
            errorOccurred = (files.Count == 0);

            if (ArchiveDownloadUpdate != null)
            {
                if (errorOccurred)
                    ArchiveDownloadUpdate(this, new ArchiveDownloadEventArgs(releaseInfo, ArchiveDownloadStatus.ERROR));
                else
                    ArchiveDownloadUpdate(this, new ArchiveDownloadEventArgs(releaseInfo, ArchiveDownloadStatus.COMPLETED));
            }

            // update release_info.xml file with last releaseInfo ReleaseDate field in order to reflect github release date
            if (files.Contains(Path.Combine("homegenie", releaseFile)))
            {
                var ri = GetReleaseFile(Path.Combine(destinationFolder, "homegenie", releaseFile));
                ri.ReleaseDate = releaseInfo.ReleaseDate.ToUniversalTime();
                XmlSerializer serializer = new XmlSerializer(typeof(ReleaseInfo)); 
                using (TextWriter writer = new StreamWriter(Path.Combine(destinationFolder, "homegenie", releaseFile)))
                {
                    serializer.Serialize(writer, ri); 
                } 
            }

            return files;
        }