Esempio n. 1
0
        /// <summary>
        /// 执行进度条动画
        /// </summary>
        private void SetProgess(MainWindowStatusNotify notify)
        {
            //如果状态栏有正在执行的任务, 标识任务正在执行, 且隐藏清除消息按钮
            if (notify.nowProgress < MainProgressBar.Maximum && !mIsProgressRunning)
            {
                mIsProgressRunning = true;
                ClearStatusBarTextButton.Visibility = Visibility.Collapsed;
                StopTaskButton.Visibility           = Visibility.Visible;
            }

            //如果一个任务已经执行完毕, 则显示清除按钮
            if (notify.nowProgress == MainProgressBar.Maximum && mIsProgressRunning)
            {
                mIsProgressRunning = false;
                ClearStatusBarTextButton.Visibility = Visibility.Visible;
                StopTaskButton.Visibility           = Visibility.Collapsed;
            }

            //标识需要动画才会执行进度条动画
            //if (notify.animateProgress)
            //{
            //MainProgressBar.IsIndeterminate = true;
            Duration        duration        = new Duration(TimeSpan.FromMilliseconds(notify.progressDuration));
            DoubleAnimation doubleanimation = new DoubleAnimation(notify.oldProgress, notify.nowProgress, duration);

            MainProgressBar.BeginAnimation(ProgressBar.ValueProperty, doubleanimation);
            //}
            //else
            //{
            //    //没有动画则直接赋值
            //    MainProgressBar.Dispatcher.Invoke(new Action<DependencyProperty, object>(MainProgressBar.SetValue), DispatcherPriority.Background, ProgressBar.ValueProperty, notify.nowProgress);
            //}
        }
Esempio n. 2
0
 /// <summary>
 /// 发送进度到主信息栏
 /// </summary>
 /// <param name="notify"></param>
 /// <param name="message"></param>
 /// <param name="value"></param>
 /// <returns></returns>
 public static MainWindowStatusNotify CalcProgress(MainWindowStatusNotify notify, string message, double value)
 {
     notify.message     = message;
     notify.oldProgress = notify.nowProgress;
     notify.nowProgress = value;
     return(notify);
 }
Esempio n. 3
0
 /// <summary>
 /// 设置主窗口状态栏文及进度
 /// </summary>
 /// <param name="notify"></param>
 public void SetStatustProgess(MainWindowStatusNotify notify)
 {
     MainProgressBar.Dispatcher.Invoke(() =>
     {
         SetStatusBarText(notify.alertLevel, notify.message);
         SetProgess(notify);
     });
     //this.Dispatcher.BeginInvoke((Action)delegate ()
     //{
     //    SetStatusBarText(notify.alertLevel, notify.message);
     //    SetProgess(notify);
     //});
 }
        /// <summary>
        /// 读取文件工作任务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DoReadDeviceFileTask(object sender, DoWorkEventArgs workArgs)
        {
            var args         = (DeviceSyncReadArgs)workArgs.Argument;
            var resultNotify = new MainWindowStatusNotify()
            {
                message = "文件读取完成"
            };

            workArgs.Result = resultNotify;
            //多设备且未手动选择设备
            if (null == args.Device)
            {
                resultNotify.message    = "没有待同步的目标设备";
                resultNotify.alertLevel = AlertLevel.ERROR;
                return;
            }
            //多盘符且未手动选择盘符
            if (null == args.MediaDrive)
            {
                resultNotify.message    = "没有待同步的目标盘符";
                resultNotify.alertLevel = AlertLevel.ERROR;
                return;
            }

            //进度通知
            var progressEvent = new DeviceSyncReadProgressItem
            {
                ProgressType = ReadSyncFileTaskProgressType.TEXT_ONLY,
                Notify       = new MainWindowStatusNotify
                {
                    message     = "正在读取路径配置...",
                    alertLevel  = AlertLevel.RUN,
                    nowProgress = 99
                }
            };

            mReadDeviceFileWorker.ReportProgress(0, progressEvent);
            //从数据库读取
            var dataSet = SQLite.SqlTable("SELECT pc_path, mobile_path FROM media_sync_config where enable = 1", null);

            if (null == dataSet || dataSet.Rows.Count == 0)
            {
                resultNotify.message    = "无法读取路径配置";
                resultNotify.alertLevel = AlertLevel.WARN;
                return;
            }
            //封装进对象
            var syncPathList = new List <MediaSyncConfig>();

            foreach (DataRow dataRow in dataSet.Rows)
            {
                syncPathList.Add(new SyncConfigViewModel()
                {
                    PcPath     = Convert.ToString(dataRow["pc_path"]),
                    MobilePath = Convert.ToString(dataRow["mobile_path"]),
                });
            }
            progressEvent.Notify.message = "正在连接到设备...";
            mReadDeviceFileWorker.ReportProgress(0, progressEvent);
            //筛选WPD设备
            using (args.Device)
            {
                args.Device.Connect();
                foreach (var e in syncPathList)
                {
                    bool isPcPathExists         = Directory.Exists(e.PcPath),
                             isMobilePathExists = args.Device.DirectoryExists(Path.Combine(args.MediaDrive.NameView, e.MobilePath));

                    if (!isPcPathExists && !isMobilePathExists)
                    {
                        //如果两端都不存在目标文件夹, 则跳过
                        continue;
                    }

                    progressEvent.Notify.message = string.Format("正在读取文件列表[{0}]...", e.PcPath);
                    mReadDeviceFileWorker.ReportProgress(0, progressEvent);
                    //读取PC目录下的文件列表
                    var pcFiles = isPcPathExists ? FileUtil.GetFileNameFromFullPath(Directory.GetFiles(e.PcPath)) : new string[0];
                    //读取移动设备下的文件列表
                    //var xxx = args.Device.GetFileSystemEntries(Path.Combine(args.MediaDrive.NameView, e.MobilePath));
                    //isMobilePathExists ? FileUtil.GetFileNameFromFullPath(args.Device.GetFiles(Path.Combine(args.MediaDrive.NameView, e.MobilePath))) :
                    var mobileFileList = new List <string>();
                    if (isMobilePathExists)
                    {
                        var fullMobileFolderPath = Path.Combine(args.MediaDrive.NameView, e.MobilePath);
                        var fullNames            = args.Device.EnumerateFiles(fullMobileFolderPath);
                        foreach (var fullName in fullNames)
                        {
                            //使用Win函数读取文件名
                            var winSupportName = Path.GetFileName(fullName);
                            //通过路径裁剪方式获得文件名
                            var substringName = fullName.Replace(fullMobileFolderPath + Path.DirectorySeparatorChar, string.Empty);
                            //如果两种方式取得的文件名不一致, 说明这个文件名在windows上是不合法的
                            if (!winSupportName.Equals(substringName))
                            {
                                //如果路径包含windows路径符, 记录错误并跳过
                                if (substringName.Contains(Path.DirectorySeparatorChar))
                                {
                                    //发送win10通知, 提醒人工处理此文件
                                    //通知官方文档  https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/send-local-toast-desktop
                                    new ToastContentBuilder()
                                    .AddText("文件收集失败")
                                    .AddText("不支持的文件名")
                                    .AddText(fullName)
                                    .Show();
                                    continue;
                                }
                                //取得后缀名
                                var extendName = Path.GetExtension(substringName);
                                //重命名移动设备上的文件名, 使用随机文件名
                                var newName = string.Format("{0}{1}{2}{3}", DateTime.Now.ToString("yyyyMMddHHmmss"), "_auto_rename_", RandomUtil.MakeSring(false, 6), extendName);
                                args.Device.Rename(fullName, newName);
                                mobileFileList.Add(newName);
                                //发送win10通知, 提醒文件已改名
                                new ToastContentBuilder()
                                .AddText("文件重命名提醒")
                                .AddText(fullMobileFolderPath)
                                .AddText(substringName + " -> " + newName)
                                .Show();
                                continue;
                            }
                            mobileFileList.Add(winSupportName);
                        }
                    }
                    var mobileFilesArr = mobileFileList.ToArray();
                    //找出差异文件
                    var filesOnlyInMobile = DataUtil.FindDiffEls(pcFiles, mobileFilesArr);
                    var filesOnlyInPc     = DataUtil.FindDiffEls(mobileFilesArr, pcFiles);
                    //不存在差异则直接跳过当前文件夹
                    if (DataUtil.IsEmptyCollection(filesOnlyInMobile) && DataUtil.IsEmptyCollection(filesOnlyInPc))
                    {
                        continue;
                    }
                    if (!DataUtil.IsEmptyCollection(filesOnlyInPc))
                    {
                        if (!CollectAndNotify(filesOnlyInPc, workArgs, e, SyncDeviceType.PC))
                        {
                            //不成功通常是任务中断
                            args.Device.Disconnect();
                            resultNotify.message = "已停止";
                            return;
                        }
                    }
                    if (!DataUtil.IsEmptyCollection(filesOnlyInMobile))
                    {
                        if (!CollectAndNotify(filesOnlyInMobile, workArgs, e, SyncDeviceType.PHONE))
                        {
                            args.Device.Disconnect();
                            resultNotify.message = "已停止";
                            return;
                        }
                    }
                }
                args.Device.Disconnect();
            }
        }
        /// <summary>
        /// 执行同步文件的后台任务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DoSyncFileTask(object sender, DoWorkEventArgs e)
        {
            var winProgress = new MainWindowStatusNotify()
            {
                alertLevel       = AlertLevel.RUN,
                animateProgress  = true,
                progressDuration = 100,
                nowProgress      = 0
            };
            var isTaskStop = false;
            //当前执行的队列编号
            var curTaskNo = 1;
            //当前队列最大元素数量
            var maxedQueueCount = mSyncTaskQueue.Count;

            while (mSyncTaskQueue.Count > 0)
            {
                var arg    = new DeviceSyncTaskArgs();
                var isPick = mSyncTaskQueue.TryDequeue(out arg);
                if (!isPick)
                {
                    continue;
                }
                //每个队列的分片进度
                double eachBaseProgress = 0;
                //筛选WPD设备
                using (var device = arg.Device)
                {
                    device.Connect();

                    //检查目标文件夹是否存在, 不存在则创建
                    if (!Directory.Exists(arg.Item.PcFolderNameView))
                    {
                        FileUtil.CreateFolder(arg.Item.PcFolderNameView);
                    }
                    var targetMobileFolder = Path.Combine(arg.DevicePath, arg.Item.MobileFolderNameView);
                    if (!device.DirectoryExists(targetMobileFolder))
                    {
                        device.CreateDirectory(targetMobileFolder);
                    }

                    //将两端的文件合并到一个集合
                    var allItems = arg.Item.PcItemList.ToList();
                    allItems.AddRange(arg.Item.MobileItemList.ToList());
                    var fileCounter = 1;
                    allItems.ForEach((syncFile) => {
                        //检查任务是否取消
                        if (mSyncFileBgWorker.CancellationPending)
                        {
                            isTaskStop = true;
                            return;
                        }
                        //如果队列数量增大超过初始量, 记录一个最大数量
                        if (mSyncTaskQueue.Count + 1 > maxedQueueCount)
                        {
                            maxedQueueCount = mSyncTaskQueue.Count + 1;
                        }
                        //当前队列数量=此队列拥有过的最大数量
                        var curQueueCount = maxedQueueCount;
                        //计算每个队列的分片进度
                        eachBaseProgress = 100 / curQueueCount;
                        //每个队列的基础进度, 从0开始, 以分片进度递增
                        double baseProgress = 100 - (mSyncTaskQueue.Count + 1) * eachBaseProgress;
                        //计算每个文件的分片进度
                        double eachFileProgress = eachBaseProgress / allItems.Count;
                        //文件的执行进度, 从0开始递增
                        double fileProgress = eachFileProgress * fileCounter - eachFileProgress;
                        //总进度 = 基础进度 + 文件进度
                        WindowUtil.CalcProgress(winProgress,
                                                string.Format("主任务 [{0}/{1}], 子任务 [{2}/{3}], 正在复制 [ {4} ]", curTaskNo, curQueueCount, fileCounter, allItems.Count, syncFile.NameView),
                                                baseProgress + fileProgress);
                        arg.Progress     = winProgress;
                        arg.ProgressType = SyncTaskProgressType.SUB_ITEM_FINISH;
                        mSyncFileBgWorker.ReportProgress(0, arg);
                        //执行同步
                        if (syncFile.SourceView == SyncDeviceType.PC)
                        {
                            //电脑端, 需要复制到移动端
                            var targetFolder = Path.Combine(arg.DevicePath, arg.Item.MobileFolderNameView);
                            using (FileStream stream = System.IO.File.OpenRead(Path.Combine(arg.Item.PcFolderNameView, syncFile.NameView)))
                            {
                                device.UploadFile(stream, Path.Combine(targetFolder, syncFile.NameView));
                            }
                        }
                        else
                        {
                            MediaFileInfo fileInfo = device.GetFileInfo(Path.Combine(arg.DevicePath, arg.Item.MobileFolderNameView, syncFile.NameView));
                            fileInfo.CopyTo(Path.Combine(arg.Item.PcFolderNameView, syncFile.NameView));
                        }
                        fileProgress = eachFileProgress * fileCounter;
                        WindowUtil.CalcProgress(winProgress,
                                                string.Format("主任务 [{0}/{1}], 子任务 [{2}/{3}], 正在复制 [ {4} ]", curTaskNo, curQueueCount, fileCounter, allItems.Count, syncFile.NameView),
                                                baseProgress + fileProgress);
                        arg.Source         = syncFile.SourceView;
                        arg.DeviceSyncItem = syncFile;
                        mSyncFileBgWorker.ReportProgress(0, arg);
                        fileCounter++;
                    });
                    device.Disconnect();
                }
                arg.IsOk         = !isTaskStop;
                arg.ProgressType = SyncTaskProgressType.QUEUE_FINISH;
                if (!isTaskStop)
                {
                    //一个队列执行完之后, 发送当前队列进度
                    WindowUtil.CalcProgress(arg.Progress, string.Format("主任务 [{0}/{1}]同步完成", curTaskNo, maxedQueueCount), curTaskNo * eachBaseProgress);
                    mSyncFileBgWorker.ReportProgress(0, arg);
                    curTaskNo++;
                }
                else
                {
                    mSyncFileBgWorker.ReportProgress(0, arg);
                }
            }
            e.Result = !isTaskStop;
        }