コード例 #1
0
            public override Task <object> ExecuteAsync(CancellationToken cancellationToken)
            {
                this.SetProgress(cancellationToken, "ensuring target directory exists");
                DirectoryEx.Create(this.TargetRootPath);

                int index = 0;

                if (this.DeleteExtra)
                {
                    this.SetProgress(cancellationToken, "checking existing files");
                    var remoteFileList = DirectoryEx.GetFileSystemInfos(this.TargetRootPath, MaskingContext.IncludeAll);

                    foreach (var file in remoteFileList)
                    {
                        index++;
                        this.SetProgress(cancellationToken, "checking existing files", 100 * index / remoteFileList.Count);

                        var relativeName = file.FullName.Substring(this.TargetRootPath.Length).Replace('\\', '/').Trim('/');
                        if (file is SlimDirectoryInfo)
                        {
                            if (!this.ExpectedDirectories.Contains(relativeName))
                            {
                                this.LogDebug("Deleting extra directory: " + relativeName);
                                DirectoryEx.Delete(file.FullName);
                            }
                        }
                        else
                        {
                            if (!this.ExpectedFiles.Contains(relativeName))
                            {
                                this.LogDebug($"Deleting extra file: " + relativeName);
                                FileEx.Delete(file.FullName);
                            }
                        }
                    }
                }

                index = 0;
                foreach (var relativeName in this.ExpectedDirectories)
                {
                    index++;
                    this.SetProgress(cancellationToken, "ensuring target subdirectories exist", 100 * index / this.ExpectedDirectories.Length);

                    DirectoryEx.Create(PathEx.Combine(Path.DirectorySeparatorChar, this.TargetRootPath, relativeName));
                }

                index = 0;
                foreach (var relativeName in this.ExpectedFiles)
                {
                    var sourcePath = PathEx.Combine(PathEx.Combine(Path.DirectorySeparatorChar, this.TempDirectoryName, "package"), relativeName);
                    var targetPath = PathEx.Combine(Path.DirectorySeparatorChar, this.TargetRootPath, relativeName);

                    index++;
                    this.SetProgress(cancellationToken, "moving files to target directory", 100 * index / this.ExpectedFiles.Length);

                    FileEx.Move(sourcePath, targetPath, true);
                }

                return(InedoLib.NullTask);
            }
コード例 #2
0
        public void Initialize()
        {
            string asmDir = PathEx.GetDirectoryName(typeof(GitTests).Assembly.Location);

            this.rootDir = PathEx.Combine(asmDir, "test-root");
            DirectoryEx.Create(this.rootDir);
            DirectoryEx.Clear(this.rootDir);

            if (FileEx.Exists(credentialsFilePath))
            {
                var lines = File.ReadAllLines(credentialsFilePath);
                this.userName = lines[0];
                this.password = SecureStringExtensions.ToSecureString(lines[1]);
            }

            var fileOps = new TestFileOperationsExecuter(Path.Combine(this.rootDir, "agent"));

            //var fileOps = new SimulatedFileOperationsExecuter(fileOps);
            //fileOps.MessageLogged += (s, e) => TestLogger.Instance.Log(e.Level, e.Message);

            this.fileOps = fileOps;

            this.processExecuter = new TestRemoteProcessExecuter();
            this.jobExecuter     = new TestRemoteJobExecuter();
        }
コード例 #3
0
        protected override Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context)
        {
            var sourcePath = context.ResolvePath(this.SourceDirectory);

            this.LogInformation($"Finding matching files in {sourcePath}...");
            if (!DirectoryEx.Exists(sourcePath))
            {
                this.LogError($"Directory {sourcePath} does not exist.");
                return(Complete);
            }

            var mask    = new MaskingContext(this.Includes, this.Excludes);
            var matches = DirectoryEx.GetFileSystemInfos(sourcePath, mask)
                          .OfType <SlimFileInfo>()
                          .Where(f => f.FullName.EndsWith(".sql", StringComparison.OrdinalIgnoreCase))
                          .ToList();

            if (matches.Count == 0)
            {
                this.LogError($"No matching .sql files were found in {sourcePath}.");
                return(Complete);
            }

            var outputFileName = context.ResolvePath(this.OutputFile);

            DirectoryEx.Create(PathEx.GetDirectoryName(outputFileName));

            using (var buffer = new TemporaryStream())
            {
                using (var zip = new ZipArchive(buffer, ZipArchiveMode.Create, true))
                {
                    foreach (var f in matches)
                    {
                        var entryName = getEntryName(f.FullName);
                        this.LogDebug($"Adding {entryName}...");
                        zip.CreateEntryFromFile(f.FullName, entryName, CompressionLevel.Optimal);
                    }
                }

                buffer.Position = 0;

                using (var outputStream = FileEx.Open(outputFileName, FileMode.Create, FileAccess.Write, FileShare.None, FileOptions.SequentialScan))
                {
                    using (var inedoSqlStream = typeof(BundleSqlScriptsOperation).Assembly.GetManifestResourceStream("Inedo.Extensions.SqlServer.Operations.inedosql.exe"))
                    {
                        inedoSqlStream.CopyTo(outputStream);
                    }

                    buffer.CopyTo(outputStream);
                }
            }

            this.LogInformation($"{outputFileName} created.");
            return(Complete);

            string getEntryName(string fullName) => fullName.Substring(0, sourcePath.Length).TrimStart('\\', '/').Replace('\\', '/');
        }
コード例 #4
0
        public async Task ExecuteAsync()
        {
            var startTime = DateTime.UtcNow;

            this.ExecutionId            = RompDb.CreateExecution(startTime, Domains.ExecutionStatus.Normal, Domains.ExecutionRunState.Executing, this.Simulation);
            this.DefaultExternalContext = new RompExecutionContext(this);

            this.Executer = new ExecuterThread(new AnonymousBlockStatement(this.plan), this);

            var result = ExecutionStatus.Error;

            try
            {
                await RompSessionVariable.ExpandValuesAsync(this.DefaultExternalContext);

                var targetDir = RompSessionVariable.GetSessionVariable(new RuntimeVariableName("TargetDirectory", RuntimeValueType.Scalar))?.GetValue().AsString();
                if (string.IsNullOrWhiteSpace(targetDir) || !PathEx.IsPathRooted(targetDir))
                {
                    this.Executer.RootLogScope.Log(LogLevel.Error, "Invalid value for $TargetDirectory.");
                    result = ExecutionStatus.Error;
                }
                else
                {
                    PackageInstaller.TargetDirectory = targetDir;
                    DirectoryEx.Create(targetDir);
                    result = await this.Executer.ExecuteAsync();
                }
            }
            catch (Exception ex)
            {
                if (!(ex is ExecutionFailureException))
                {
                    Logger.Log(MessageLevel.Error, "Unhandled exception in executer: " + ex.ToString());
                }

                result = ExecutionStatus.Error;
            }
            finally
            {
                try
                {
                    this.CleanTempDirectory();
                }
                catch
                {
                }

                await this.RootExecutionLog.CompleteAllAsync();

                RompDb.CompleteExecution(
                    executionId: this.ExecutionId.Value,
                    endDate: DateTime.UtcNow,
                    statusCode: result >= ExecutionStatus.Error ? Domains.ExecutionStatus.Error : result >= ExecutionStatus.Warning ? Domains.ExecutionStatus.Warning : Domains.ExecutionStatus.Normal
                    );
            }
        }
コード例 #5
0
        protected override Repository OpenRepository()
        {
            if (DirectoryEx.Exists(this.LocalRepositoryPath))
            {
                if (Repository.IsValid(this.LocalRepositoryPath))
                {
                    var repository = new Repository(this.LocalRepositoryPath);

                    if (!string.IsNullOrEmpty(this.RemoteRepositoryUrl))
                    {
                        Commands.Fetch(repository, "origin", Enumerable.Empty <string>(),
                                       new FetchOptions {
                            CredentialsProvider = CredentialsHandler
                        }, null);
                        if (repository.Refs["refs/heads/" + this.BranchName] == null)
                        {
                            //Must use an ObjectId to create a DirectReference (SymbolicReferences will cause an error when committing)
                            var objId = new ObjectId(repository.Refs["refs/remotes/origin/" + this.BranchName].TargetIdentifier);
                            repository.Refs.Add("refs/heads/" + this.BranchName, objId);
                        }
                        repository.Refs.UpdateTarget("refs/heads/" + this.BranchName, "refs/remotes/origin/" + this.BranchName);
                    }

                    return(repository);
                }

                if (DirectoryEx.GetFileSystemInfos(this.LocalRepositoryPath, MaskingContext.Default).Any())
                {
                    throw new InvalidOperationException("The specified local repository path does not appear to be a Git repository but already contains files or directories.");
                }
            }
            else
            {
                DirectoryEx.Create(this.LocalRepositoryPath);
            }

            if (!string.IsNullOrEmpty(this.RemoteRepositoryUrl))
            {
                Repository.Clone(
                    this.RemoteRepositoryUrl,
                    this.LocalRepositoryPath,
                    new CloneOptions
                {
                    CredentialsProvider = this.CredentialsHandler,
                    IsBare = true
                }
                    );
            }
            else
            {
                Repository.Init(this.LocalRepositoryPath, true);
            }

            return(new Repository(this.LocalRepositoryPath));
        }
コード例 #6
0
        private void CreateFile(string relativePath, Blob target)
        {
            string path      = PathEx.Combine(this.rootPath, relativePath);
            string directory = PathEx.GetDirectoryName(path);

            DirectoryEx.Create(directory);

            using (var targetStream = target.GetContentStream())
                using (var file = FileEx.Open(path, FileMode.Create, FileAccess.Write, FileShare.Read))
                {
                    targetStream.CopyTo(file);
                }
        }
コード例 #7
0
        public bool Save()
        {
            bool IsOk = true;

            DirectoryEx.Delete(ParaPath);
            if (!DirectoryEx.Exist(ParaPath))
            {
                DirectoryEx.Create(ParaPath);
            }
            IsOk = IsOk && XML <BindingList <CameraPara> > .Write(CameraParaList, ParaPath + @"\" + "CameraParaList.xml");

            return(IsOk);
        }
コード例 #8
0
        public bool  Save()
        {
            bool IsOk = true;

            DirectoryEx.DeleteFolder1(Path);
            if (!DirectoryEx.Exist(Path))
            {
                DirectoryEx.Create(Path);
            }
            IsOk = IsOk && XML <LightCrlParaManager> .Write(this, Path + @"\" + "LightCrlParaManager.xml");

            return(IsOk);
        }
コード例 #9
0
ファイル: Settings.cs プロジェクト: Port-Able/Port-Able-Suite
        internal static void Initialize()
        {
            WinApi.NativeHelper.SetProcessDPIAware();

            if (Log.DebugMode > 0)
            {
                Log.FileDir = Path.Combine(CorePaths.TempDir, "Logs");
                DirectoryEx.Create(Log.FileDir);
            }

            Ini.SetFile(CorePaths.HomeDir, "Settings.ini");
            Ini.SortBySections = new[]
            {
                "Downloader",
                Resources.ConfigSection
            };

            Log.AllowLogging(Ini.FilePath);
        }
コード例 #10
0
        public static void Init()
        {
            if (loadedModules != null)
            {
                return;
            }

            loadedModules = new List <Assembly>();

            // Safe
            DirectoryEx.Create("Plugins");

            foreach (string fileName in Directory.GetFiles("Plugins", "*.dll", SearchOption.TopDirectoryOnly))
            {
                var moduleAssembly = Assembly.LoadFile(Path.GetFullPath(fileName));

                loadedModules.Add(moduleAssembly);
            }
        }
コード例 #11
0
        public Task BackupDatabaseAsync(string databaseName, string destinationPath, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(databaseName))
            {
                throw new ArgumentNullException(nameof(databaseName));
            }
            if (string.IsNullOrWhiteSpace(destinationPath))
            {
                throw new ArgumentNullException(nameof(destinationPath));
            }

            var destinationDir = PathEx.GetDirectoryName(destinationPath);

            if (!string.IsNullOrEmpty(destinationDir))
            {
                DirectoryEx.Create(destinationDir);
            }

            return(this.ExecuteQueryAsync($"BACKUP DATABASE [{EscapeName(databaseName)}] TO DISK = N'{EscapeString(destinationPath)}' WITH FORMAT", cancellationToken));
        }
コード例 #12
0
        public bool Save()
        {
            bool   IsOk    = true;
            string ExePath = System.Environment.CurrentDirectory;

            DirectoryEx.DeleteFolder1(ExePath + @"\" + ParaPath);
            if (!DirectoryEx.Exist(ExePath + @"\" + ParaPath))
            {
                DirectoryEx.Create(ExePath + @"\" + ParaPath);
            }
            IsOk = IsOk && XML <List <ProjectMsg> > .Write(this.ProjectMsgList, ExePath + @"\" + ParaPath + @"\" + "ProjectMsgList.xml");

            ProjectPara ProjectParaI = new ProjectPara();

            for (int i = 0; i < this.ProjectMsgList.Count(); i++)
            {
                ProjectParaI = this.ProjectParaList[i];
                IsOk         = IsOk && ProjectParaI.Save(ExePath + @"\" + ParaPath + @"\" + i.ToString() + this.ProjectMsgList[i].ProjectDescribe + @"\");
            }
            return(IsOk);
        }
コード例 #13
0
ファイル: CaliParaManager.cs プロジェクト: Gz1d/Gz
        public bool Save()
        {
            bool IsOk = true;

            //DirectoryEx.Delete(ParaPath);
            if (!DirectoryEx.Exist(ParaPath))
            {
                DirectoryEx.Create(ParaPath);
            }
            int Index = 0;

            foreach (CaliParam item in CaliParaList)
            {
                string Pathi = ParaPath + @"\" + Index.ToString() + @"\";
                if (!FileLib.DirectoryEx.Exist(Pathi))
                {
                    FileLib.DirectoryEx.Create(Pathi);
                }
                IsOk = IsOk && item.Save(ParaPath + @"\" + Index.ToString() + @"\");
                Index++;
            }
            return(IsOk);
        }
コード例 #14
0
        protected override async Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context)
        {
            var fullPath = context.ResolvePath(this.FileName);

            this.LogInformation($"Changing \"{fullPath}\" package version to {AH.CoalesceString(this.NewVersion, "remove pre-release label")}...");

            var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("n"));

            try
            {
                DirectoryEx.Create(tempPath);
                UniversalPackageMetadata currentMetadata;
                using (var upack = new UniversalPackage(fullPath))
                {
                    currentMetadata = upack.GetFullMetadata();
                    await upack.ExtractAllItemsAsync(tempPath, context.CancellationToken);

                    FileEx.Delete(PathEx.Combine(tempPath, "upack.json"));
                }

                var newMetadata = currentMetadata.Clone();
                if (string.IsNullOrEmpty(this.NewVersion))
                {
                    newMetadata.Version = new UniversalPackageVersion(currentMetadata.Version.Major, currentMetadata.Version.Minor, currentMetadata.Version.Patch);
                }
                else
                {
                    newMetadata.Version = UniversalPackageVersion.Parse(this.NewVersion);
                }

                if (currentMetadata.Version == newMetadata.Version)
                {
                    this.LogWarning($"Current package version {currentMetadata.Version} and the new version {newMetadata.Version} are the same; nothing to do.");
                    return(null);
                }

                this.LogInformation("New version: " + newMetadata.Version);

                this.LogDebug("Adding repacking entry...");
                newMetadata.RepackageHistory.Add(
                    new RepackageHistoryEntry
                {
                    Id     = new UniversalPackageId(currentMetadata.Group, currentMetadata.Name) + ":" + currentMetadata.Version,
                    Date   = DateTimeOffset.Now,
                    Using  = SDK.ProductName + "/" + SDK.ProductVersion,
                    Reason = this.Reason
                }
                    );

                using (var builder = new UniversalPackageBuilder(fullPath, newMetadata))
                {
                    await builder.AddRawContentsAsync(tempPath, string.Empty, true, c => true, context.CancellationToken);
                }

                this.LogInformation("Package version changed.");

                return(null);
            }
            finally
            {
                try
                {
                    this.LogDebug($"Deleting temporary files from {tempPath}...");
                    DirectoryEx.Clear(tempPath);
                    DirectoryEx.Delete(tempPath);
                }
                catch (Exception ex)
                {
                    this.LogWarning("Unable to delete temporary files: " + ex.Message);
                }
            }
        }
コード例 #15
0
        public override async Task <DXCompileResult> Compile(DXCompileParameter parameter)
        {
            const double TotalOnReport = 8;
            int          OnReport      = 0;

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            var sw = new Stopwatch();

            sw.Start();

            // Result
            var result = new DXCompileResult(parameter.Option);

            // NameContainer
            var sharedNameContainer     = new NameContainer();
            var sharedCallbackContainer = new NameContainer();

            // CodeDom
            var provider = new CSharpCodeProvider();

            var compileParam = new CompilerParameters()
            {
                GenerateExecutable    = true,
                GenerateInMemory      = false,
                TreatWarningsAsErrors = false,
#if DEBUG
                IncludeDebugInformation = false
#else
                IncludeDebugInformation = true
#endif
            };

            // Add WPF Referenced Assembly
            Assembly[] dependencyLibs = GetReferencedAssemblyNames(parameter).ToArray();

            AddReferencedAssemblies(compileParam, dependencyLibs);

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            // Mapper
            var mapper = new DXMapper <CSharpCodeMapAttribute>(
                new WPFMappingProvider(sharedCallbackContainer),
                sharedNameContainer);

            // Generator
            WPFLayoutGenerator layoutGenerator = CreateLayoutGenerator(parameter);
            CSharpGenerator    logicGenerator  = CreateLogicGenerator(parameter);

            layoutGenerator.SetNameContainer(sharedNameContainer);        // 공유 이름 컨테이너 설정
            logicGenerator.SetNameContainer(sharedNameContainer);         // 공유 이름 컨테이너 설정
            logicGenerator.SetCallbackContainer(sharedCallbackContainer); // 공유 콜밸 컨테이너 설정
            logicGenerator.SetMapper(mapper);                             // 코드 매핑 설정

            // WPF Code Builder
            var wpfCodeBuilder = new WPFCodeBuilder(parameter, logicGenerator);

            // 임시 파일 경로
            string tempIconPath    = compileParam.TempFiles.AddExtension("ico");
            string tempResFileName = Path.Combine(Path.GetTempPath(), $"{parameter.Option.ApplicationName}.g.resources");
            //                              기본 디렉터리 / Build / 어플리케이션이름 / 플랫폼
            string directory = Path.Combine(parameter.Option.Directory, "Build", parameter.Option.ApplicationName, parameter.Option.TargetPlatform.ToString());
            string exePath   = Path.Combine(directory, $"{parameter.Option.ApplicationName}.exe");

            compileParam.TempFiles.AddFile(tempResFileName, false);

            // 출력 폴더 생성
            DirectoryEx.Create(directory);

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            // Generate Native Code
            string[] screensXaml = layoutGenerator.Generate().ToArray();
            var      csSources   = new List <string>();

            foreach (string cs in WPFCompiler.CodeResources.Values)
            {
                DXMappingResult mappingResult = wpfCodeBuilder.Build(cs);

                csSources.Add(mappingResult.Source);
            }

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            // 리소스 생성
            if (provider.Supports(GeneratorSupport.Resources))
            {
                using (var fs = File.Create(tempResFileName))
                {
                    var res = new WPFResourceWriter(fs);

                    // 이미지 리소스 추가
                    foreach (string img in layoutGenerator.Images)
                    {
                        res.AddImage(img, "");
                    }

                    // 레이아웃 xaml 추가
                    for (int i = 0; i < parameter.Screens.Length; i++)
                    {
                        res.AddXaml($"{parameter.Screens[i].GetPageName()}.xaml", "", screensXaml[i]);
                    }

                    res.Close();
                }

                compileParam.EmbeddedResources.Add(tempResFileName);
            }

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            // 임시 아이콘 생성
            Stream iconStream = GetStreamResource("Resources/IconLogo.ico");

            byte[] iconBin = new byte[iconStream.Length];

            iconStream.Read(iconBin, 0, iconBin.Length);

            File.WriteAllBytes(tempIconPath, iconBin);

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            // 출력 및 컴파일 커맨드라인 설정
            compileParam.OutputAssembly  = exePath;
            compileParam.CompilerOptions = $"/target:winexe /win32icon:{tempIconPath}";

#if DEBUG
            UI.SpacingStackPanel s;

            var w = new Window()
            {
                WindowStartupLocation = WindowStartupLocation.CenterScreen,
                Content = new ScrollViewer()
                {
                    Content = (s = new UI.SpacingStackPanel()
                    {
                        Spacing = 40
                    })
                }
            };

            foreach (string xaml in screensXaml)
            {
                s.Children.Add(
                    new TextBox()
                {
                    VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                    IsReadOnly = true,
                    Text       = xaml
                });
            }

            foreach (string code in csSources)
            {
                s.Children.Add(
                    new TextBox()
                {
                    VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                    IsReadOnly = true,
                    Text       = code
                });
            }

            w.Show();
#endif
            // Compile Binary
            CompilerResults compileResult = provider.CompileAssemblyFromSource(compileParam, csSources.ToArray());
            compileParam.TempFiles.Delete();

            // 컴파일 시간 기록
            sw.Stop();
            result.Elapsed = sw.Elapsed;

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            if (compileResult.Errors.Count > 0)
            {
                result.Errors.AddRange(compileResult.Errors.Cast <object>());
            }
            else
            {
                result.Outputs.Add(exePath);

                // Referenced DLL Export
                foreach (string assemblyFileName in compileParam.ReferencedAssemblies)
                {
                    if (File.Exists(assemblyFileName) &&
                        assemblyFileName.StartsWith(Environment.CurrentDirectory))
                    {
                        // DLL 복사
                        File.Copy(
                            assemblyFileName,
                            Path.Combine(directory, Path.GetFileName(assemblyFileName)),
                            true);

                        result.Outputs.Add(assemblyFileName);
                    }
                }

                result.IsSuccess = true;
            }

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            return(result);
        }
コード例 #16
0
        private static void SecureOverrides(IReadOnlyDictionary <string, Dictionary <string, string> > regMap, bool elevated = false)
        {
            if (regMap?.Any() != true)
            {
                return;
            }
            var file = PathEx.Combine(Attributes.DataDir, $"Temp\\overwrite-{{{EnvironmentEx.MachineId}}}.reg");

            try
            {
                var dir = Path.GetDirectoryName(file);
                if (string.IsNullOrEmpty(dir))
                {
                    throw new ArgumentNullException(dir);
                }
                DirectoryEx.Create(dir);
                FileEx.Delete(file);
            }
            catch (Exception ex)
            {
                Log.Write(ex);
                return;
            }
            using (var sw = new StreamWriter(file, true, Encoding.GetEncoding(1252)))
            {
                sw.WriteLine("Windows Registry Editor Version 5.00");
                sw.WriteLine();
                foreach (var data in regMap)
                {
                    var section = data.Key;
                    if (!section.ContainsEx('\\'))
                    {
                        continue;
                    }
                    var levels = section.Split('\\');
                    var first  = levels.FirstOrDefault();
                    switch (first?.TrimStart('[', '-'))
                    {
                    case "HKEY_CLASSES_ROOT":
                    case "HKEY_CURRENT_CONFIG":
                    case "HKEY_CURRENT_USER":
                    case "HKEY_LOCAL_MACHINE":
                    case "HKEY_PERFORMANCE_DATA":
                    case "HKEY_USERS":
                        break;

                    case "HKCR":
                        levels[0] = "HKEY_CLASSES_ROOT";
                        break;

                    case "HKCC":
                        levels[0] = "HKEY_CURRENT_CONFIG";
                        break;

                    case "HKCU":
                        levels[0] = "HKEY_CURRENT_USER";
                        break;

                    case "HKLM":
                        levels[0] = "HKEY_LOCAL_MACHINE";
                        break;

                    case "HKPD":
                        levels[0] = "HKEY_PERFORMANCE_DATA";
                        break;

                    case "HKU":
                        levels[0] = "HKEY_USERS";
                        break;

                    default:
                        continue;
                    }
                    if (!first.Equals(levels[0]))
                    {
                        if (first.StartsWithEx("[-", "-"))
                        {
                            levels[0] = $"-{levels[0]}";
                        }
                        section = levels.Join('\\');
                    }
                    if (!section.StartsWith("["))
                    {
                        section = $"[{section}";
                    }
                    if (!section.EndsWith("]"))
                    {
                        section = $"{section}]";
                    }
                    sw.WriteLine(section);
                    if (regMap[data.Key]?.Any() != true)
                    {
                        sw.WriteLine();
                        continue;
                    }
                    foreach (var pair in regMap[data.Key])
                    {
                        var key   = !string.IsNullOrWhiteSpace(pair.Key) && !pair.Key.Equals("@") ? $"\"{pair.Key}\"" : "@";
                        var value = pair.Value;
                        if (string.IsNullOrWhiteSpace(value))
                        {
                            value = "-";
                        }
                        sw.WriteLine($"{key}={value}");
                    }
                    sw.WriteLine();
                }
                sw.WriteLine();
            }
            Reg.ImportFile(file, elevated || Elevation.IsAdministrator);
            ProcessEx.SendHelper.WaitThenDelete(file, 10, Elevation.IsAdministrator);
        }
コード例 #17
0
        internal static void RepairAppsSuiteDirs()
        {
            if (!Elevation.WritableLocation())
            {
                Elevation.RestartAsAdministrator(ActionGuid.RepairDirs);
            }

            foreach (var dirs in new[]
            {
                CorePaths.AppDirs,
                CorePaths.UserDirs
            })
            {
                foreach (var dir in dirs)
                {
                    if (!DirectoryEx.Create(dir))
                    {
                        Elevation.RestartAsAdministrator(ActionGuid.RepairDirs);
                    }
                }
            }

            var iniMap = new[]
            {
                new[]
                {
                    CorePaths.AppDirs.First(),
                    "IconResource=..\\Assets\\FolderIcons.dll,3"
                },
                new[]
                {
                    CorePaths.AppDirs.Second(),
                    "LocalizedResourceName=\"Port-Able\" - Freeware",
                    "IconResource=..\\..\\Assets\\FolderIcons.dll,4"
                },
                new[]
                {
                    CorePaths.AppDirs.Third(),
                    "LocalizedResourceName=\"PortableApps\" - Repacks",
                    "IconResource=..\\..\\Assets\\FolderIcons.dll,2"
                },
                new[]
                {
                    CorePaths.AppDirs.Last(),
                    "LocalizedResourceName=\"Custom\" - Shareware",
                    "IconResource=..\\..\\Assets\\FolderIcons.dll,1"
                },
                new[]
                {
                    PathEx.Combine(PathEx.LocalDir, "Assets"),
                    "IconResource=FolderIcons.dll,5"
                },
                new[]
                {
                    PathEx.Combine(PathEx.LocalDir, "Binaries"),
                    "IconResource=..\\Assets\\FolderIcons.dll,5"
                },
                new[]
                {
                    CorePaths.UserDirs.First(),
                    "LocalizedResourceName=Profile",
                    "IconResource=%SystemRoot%\\system32\\imageres.dll,117",
                    "IconFile=%SystemRoot%\\system32\\shell32.dll",
                    "IconIndex=-235"
                },
                new[]
                {
                    PathEx.Combine(PathEx.LocalDir, "Documents", ".cache"),
                    "IconResource=%SystemRoot%\\system32\\imageres.dll,112"
                },
                new[]
                {
                    CorePaths.UserDirs.Second(),
                    "LocalizedResourceName=@%SystemRoot%\\system32\\shell32.dll,-21770",
                    "IconResource=%SystemRoot%\\system32\\imageres.dll,-112",
                    "IconFile=%SystemRoot%\\system32\\shell32.dll",
                    "IconIndex=-235"
                },
                new[]
                {
                    CorePaths.UserDirs.Third(),
                    "LocalizedResourceName=@%SystemRoot%\\system32\\shell32.dll,-21790",
                    "IconResource=%SystemRoot%\\system32\\imageres.dll,-108",
                    "IconFile=%SystemRoot%\\system32\\shell32.dll",
                    "IconIndex=-237",
                    "InfoTip=@%SystemRoot%\\system32\\shell32.dll,-12689"
                },
                new[]
                {
                    CorePaths.UserDirs.Fourth(),
                    "LocalizedResourceName=@%SystemRoot%\\system32\\shell32.dll,-21779",
                    "IconResource=%SystemRoot%\\system32\\imageres.dll,-113",
                    "IconFile=%SystemRoot%\\system32\\shell32.dll",
                    "IconIndex=-236",
                    "InfoTip=@%SystemRoot%\\system32\\shell32.dll,-12688"
                },
                new[]
                {
                    CorePaths.UserDirs.Last(),
                    "LocalizedResourceName=@%SystemRoot%\\system32\\shell32.dll,-21791",
                    "IconResource=%SystemRoot%\\system32\\imageres.dll,-189",
                    "IconFile=%SystemRoot%\\system32\\shell32.dll",
                    "IconIndex=-238",
                    "InfoTip=@%SystemRoot%\\system32\\shell32.dll,-12690"
                },
                new[]
                {
                    PathEx.Combine(PathEx.LocalDir, "Help"),
                    "IconResource=..\\Assets\\FolderIcons.dll,4"
                }
            };

            for (var i = 0; i < iniMap.Length; i++)
            {
                var array = iniMap[i];
                var dir   = array.FirstOrDefault();
                if (!PathEx.IsValidPath(dir) || i >= iniMap.Length - 2 && !Directory.Exists(dir))
                {
                    continue;
                }
                if (!Elevation.WritableLocation(dir))
                {
                    Elevation.RestartAsAdministrator(ActionGuid.RepairDirs);
                }
                var path = PathEx.Combine(dir, "desktop.ini");
                foreach (var str in array.Skip(1))
                {
                    var ent = str?.Split('=');
                    if (ent?.Length != 2)
                    {
                        continue;
                    }
                    var key = ent.FirstOrDefault();
                    if (string.IsNullOrEmpty(key))
                    {
                        continue;
                    }
                    var val = ent.LastOrDefault();
                    if (string.IsNullOrEmpty(val))
                    {
                        continue;
                    }
                    Ini.WriteDirect(".ShellClassInfo", key, val, path);
                }
                FileEx.SetAttributes(path, FileAttributes.System | FileAttributes.Hidden);
                DirectoryEx.SetAttributes(dir, FileAttributes.ReadOnly);
            }
        }
コード例 #18
0
        public async Task <int?> RunAsync(string script, Dictionary <string, RuntimeValue> variables = null, Dictionary <string, RuntimeValue> parameters = null, Dictionary <string, RuntimeValue> outVariables = null, string workingDirectory = null, CancellationToken cancellationToken = default)
        {
            variables ??= new Dictionary <string, RuntimeValue>();
            parameters ??= new Dictionary <string, RuntimeValue>();
            outVariables ??= new Dictionary <string, RuntimeValue>();

            var runspace = this.Runspace;

            var powerShell = System.Management.Automation.PowerShell.Create();

            powerShell.Runspace = runspace;

            foreach (var var in variables)
            {
                this.LogDebug($"Importing {var.Key}...");
                runspace.SessionStateProxy.SetVariable(var.Key, ConvertToPSValue(var.Value));
            }

            if (this.DebugLogging)
            {
                runspace.SessionStateProxy.SetVariable("DebugPreference", "Continue");
            }

            if (this.VerboseLogging)
            {
                runspace.SessionStateProxy.SetVariable("VerbosePreference", "Continue");
            }

            var output = new PSDataCollection <PSObject>();

            output.DataAdded +=
                (s, e) =>
            {
                var rubbish = output[e.Index];
                this.OnOutputReceived(rubbish);
            };

            powerShell.Streams.Progress.DataAdded += (s, e) => this.OnProgressUpdate(powerShell.Streams.Progress[e.Index]);

            powerShell.Streams.AttachLogging(this);

            if (!string.IsNullOrWhiteSpace(workingDirectory))
            {
                DirectoryEx.Create(workingDirectory);
                powerShell.AddCommand("Set-Location");
                powerShell.AddParameter("Path", workingDirectory);
                powerShell.AddStatement();
            }

            powerShell.AddScript(script);

            foreach (var p in parameters)
            {
                this.LogDebug($"Assigning parameter {p.Key}...");
                powerShell.AddParameter(p.Key, ConvertToPSValue(p.Value));
            }

            int?exitCode = null;

            this.pshost.ShouldExit += handleShouldExit;
            using (var registration = cancellationToken.Register(powerShell.Stop))
            {
                try
                {
                    await Task.Factory.FromAsync(powerShell.BeginInvoke((PSDataCollection <PSObject>)null, output), powerShell.EndInvoke);

                    foreach (var var in outVariables.Keys.ToList())
                    {
                        outVariables[var] = PSUtil.ToRuntimeValue(unwrapReference(powerShell.Runspace.SessionStateProxy.GetVariable(var)));
                    }
                }
                finally
                {
                    this.pshost.ShouldExit -= handleShouldExit;
                }
            }

            void handleShouldExit(object s, ShouldExitEventArgs e) => exitCode = e.ExitCode;

            object unwrapReference(object value) => value is PSReference reference ? reference.Value : value;

            return(exitCode);
        }
コード例 #19
0
ファイル: WPFCompiler.cs プロジェクト: sunfom/DeXign
        public override async Task <DXCompileResult> Compile(DXCompileParameter parameter)
        {
            const double TotalOnReport = 8;
            int          OnReport      = 0;

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            var sw = new Stopwatch();

            sw.Start();

            // Result
            var result = new DXCompileResult(parameter.Option);

            // NameContainer
            var sharedLayoutContainer = new ModelNameContainer();

            var mainNameContainer     = new ModelNameContainer();
            var mainCallbackContainer = new ModelNameContainer();

            var templateNameContainer     = new ModelNameContainer();
            var templateCallbackContainer = new ModelNameContainer();

            // CodeDom
            var provider = new CSharpCodeProvider(
                new Dictionary <string, string>()
            {
                { "CompilerVersion", "v4.0" }
            });

            var compileParam = new CompilerParameters()
            {
                GenerateExecutable    = true,
                GenerateInMemory      = false,
                TreatWarningsAsErrors = false,
#if RELEASE
                IncludeDebugInformation = false
#else
                IncludeDebugInformation = true
#endif
            };

            // Add WPF Referenced Assembly
            Assembly[] dependencyLibs = GetReferencedAssemblyNames(parameter).ToArray();

            AddReferencedAssemblies(compileParam, dependencyLibs);

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            // Mapper
            var mapper = new DXMapper <CSharpCodeMapAttribute>(
                new WPFMappingProvider(mainCallbackContainer),
                mainNameContainer)
            {
                SharedConatiner = sharedLayoutContainer
            };

            var templateMapper = new DXMapper <CSharpCodeMapAttribute>(
                new WPFMappingProvider(templateCallbackContainer),
                templateNameContainer)
            {
                SharedConatiner = sharedLayoutContainer
            };

            // Generator
            WPFLayoutGenerator layoutGenerator   = CreateLayoutGenerator(parameter);
            WPFLayoutGenerator templateGenerator = CreateTemplateGenerator(parameter);

            CSharpGenerator logicGenerator         = CreateLogicGenerator(parameter);
            CSharpGenerator templateLogicGenerator = CreateTemplateLogicGenerator(parameter);

            // 이름 컨테이너 설정
            layoutGenerator.NameContainer   = mainNameContainer;
            templateGenerator.NameContainer = templateNameContainer;

            logicGenerator.NameContainer         = mainNameContainer;
            templateLogicGenerator.NameContainer = templateNameContainer;

            // 콜백 컨테이너 설정
            logicGenerator.CallbackContainer         = mainCallbackContainer;
            templateLogicGenerator.CallbackContainer = templateCallbackContainer;

            // 공유 이름 컨테이너 설정
            layoutGenerator.SharedContainer   = sharedLayoutContainer;
            templateGenerator.SharedContainer = sharedLayoutContainer;

            // 코드 매퍼 할당
            logicGenerator.Mapper         = mapper;
            templateLogicGenerator.Mapper = templateMapper;

            // WPF Code Builder
            var wpfCodeBuilder         = new WPFCodeBuilder(parameter, logicGenerator);
            var wpfTemplateCodeBuilder = new WPFTemplateCodeBuilder(parameter, templateLogicGenerator);
            var wpfTemplateBuilder     = new WPFTemplateBuilder();

            // 임시 파일 경로
            string tempIconPath        = compileParam.TempFiles.AddExtension("ico");
            string tempResFileName     = Path.Combine(Path.GetTempPath(), $"{parameter.Option.ApplicationName}.g.resources");
            string tempAssmResFileName = Path.Combine(Path.GetTempPath(), $"{parameter.Option.ApplicationName}.assembly.g.resources");

            //                              기본 디렉터리 / Build / 어플리케이션이름 / 플랫폼
            string directory = Path.Combine(parameter.Option.Directory, "Build", parameter.Option.ApplicationName, parameter.Option.TargetPlatform.ToString());
            string exePath   = Path.Combine(directory, $"{parameter.Option.ApplicationName}.exe");

            compileParam.TempFiles.AddFile(tempResFileName, false);
            compileParam.TempFiles.AddFile(tempAssmResFileName, false);

            // 출력 폴더 생성
            DirectoryEx.Create(directory);

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            // Generate Native Code
            string[] templatesXaml = templateGenerator.Generate().ToArray();
            string[] screensXaml   = layoutGenerator.Generate().ToArray();
            var      csSources     = new List <string>();

            // DataTemplate Patch
            string[] templateNames = parameter.Templates
                                     .Select(t => $"_{t.GetPageName()}")
                                     .ToArray();

            for (int i = 0; i < templatesXaml.Length; i++)
            {
                templatesXaml[i] = Regex.Replace(templatesXaml[i], $@"\w+:DeXignTemplatePage", $"local:{templateNames[i]}");
                templatesXaml[i] = Regex.Replace(templatesXaml[i], @"<\?xml.*?\?>[\r\n]+", "");
            }

            // Create DataTemplate Resources
            wpfTemplateBuilder.TemplateContents = templatesXaml;
            wpfTemplateBuilder.TemplateNames    = templateNames;

            string resourceXaml = templateMapper.Build(wpfTemplateBuilder, WPFCompiler.CodeResources["DXResources.xaml"]).Source;

            resourceXaml = templateMapper.Build(parameter.Option, resourceXaml).Source;

            // Main Sources
            foreach (string csName in CSFiles)
            {
                DXMappingResult mappingResult = wpfCodeBuilder.Build(WPFCompiler.CodeResources[csName]);

                csSources.Add(mappingResult.Source);
            }

            // Template Sources
            foreach (string templateName in templateNames)
            {
                DXMappingResult mappingResult = wpfTemplateCodeBuilder.Build(WPFCompiler.CodeResources["DXUserControl.cs"]);

                csSources.Add(mappingResult.Source);
            }

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            // 리소스 생성
            if (provider.Supports(GeneratorSupport.Resources))
            {
                // 디자인 리소스
                using (var fs = File.Create(tempResFileName))
                {
                    var res = new WPFResourceWriter(fs);

                    // 이미지 리소스 추가
                    foreach (string img in layoutGenerator.Images.Concat(templateGenerator.Images).Distinct())
                    {
                        res.AddImage(img, $"{MD5.GetHash(Path.GetFileName(img))}{Path.GetExtension(img)}", "");
                    }

                    // 레이아웃 xaml 추가
                    for (int i = 0; i < parameter.Screens.Length; i++)
                    {
                        res.AddXaml($"{parameter.Screens[i].GetPageName()}.xaml", "", screensXaml[i]);
                    }

                    // 리소스 xaml 추가
                    res.AddXaml("DXResources.xaml", "", resourceXaml);

                    res.Close();
                }

                // 어셈블리 리소스
                using (var fs = File.Create(tempAssmResFileName))
                {
                    var res = new WPFResourceWriter(fs);

                    foreach (string dllName in DynamicLibraries)
                    {
                        if (File.Exists(dllName))
                        {
                            res.AddBinary(dllName, "", File.ReadAllBytes(dllName));
                        }
                    }

                    res.Close();
                }

                compileParam.EmbeddedResources.Add(tempResFileName);
                compileParam.EmbeddedResources.Add(tempAssmResFileName);
            }

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            // 임시 아이콘 생성
            Stream iconStream = GetStreamResource("Resources/IconLogo.ico");

            byte[] iconBin = new byte[iconStream.Length];

            iconStream.Read(iconBin, 0, iconBin.Length);

            File.WriteAllBytes(tempIconPath, iconBin);

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            // 출력 및 컴파일 커맨드라인 설정
            compileParam.OutputAssembly  = exePath;
            compileParam.CompilerOptions = $"/target:winexe /win32icon:{tempIconPath}";

            // Generate Debugging
            if (Keyboard.IsKeyDown(Key.LeftShift))
            {
                ShowGeneratedSources(
                    screensXaml
                    .Concat(new[] { resourceXaml })
                    .Concat(csSources));
            }

            // Compile Binary
            CompilerResults compileResult = provider.CompileAssemblyFromSource(compileParam, csSources.ToArray());

            compileParam.TempFiles.Delete();

            // 컴파일 시간 기록
            sw.Stop();
            result.Elapsed = sw.Elapsed;

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            if (compileResult.Errors.Count > 0)
            {
                result.Errors.AddRange(compileResult.Errors.Cast <object>());
            }
            else
            {
                result.Outputs.Add(exePath);

                // Referenced DLL Export
                foreach (string assemblyFileName in compileParam.ReferencedAssemblies
                         .Cast <string>()
                         .Where(fileName => File.Exists(fileName) && fileName.StartsWith(Environment.CurrentDirectory)))
                {
                    if (assemblyFileName.StartsWith(Environment.CurrentDirectory))
                    {
                        string dllFileName = Path.Combine(directory, Path.GetFileName(assemblyFileName));

                        if (!DynamicLibraries.Contains(Path.GetFileName(assemblyFileName)))
                        {
                            // DLL 복사
                            File.Copy(
                                assemblyFileName,
                                dllFileName,
                                true);

                            result.Outputs.Add(assemblyFileName);
                        }
                        else if (File.Exists(dllFileName))
                        {
                            File.Delete(dllFileName);
                        }
                    }
                }

                result.IsSuccess = true;
            }

            // * OnReport Progress
            await this.OnReport(++OnReport / TotalOnReport);

            return(result);
        }
コード例 #20
0
        public AppTransferor(AppData appData)
        {
            AppData  = appData ?? throw new ArgumentNullException(nameof(appData));
            DestPath = default;
            SrcData  = new List <Tuple <string, string, string, bool> >();
            UserData = Tuple.Create(default(string), default(string));

            var downloadCollection = AppData.DownloadCollection;
            var packageVersion     = default(string);

            if (ActionGuid.IsUpdateInstance && AppData?.UpdateCollection?.SelectMany(x => x.Value).All(x => x?.Item1?.StartsWithEx("http") == true) == true)
            {
                var appIniDir  = Path.Combine(appData.InstallDir, "App", "AppInfo");
                var appIniPath = Path.Combine(appIniDir, "appinfo.ini");
                if (!File.Exists(appIniPath))
                {
                    appIniPath = Path.Combine(appIniDir, "plugininstaller.ini");
                }
                packageVersion = Ini.Read("Version", nameof(appData.PackageVersion), default(string), appIniPath);
                if (!string.IsNullOrEmpty(packageVersion) && AppData?.UpdateCollection?.ContainsKey(packageVersion) == true)
                {
                    downloadCollection = AppData.UpdateCollection;
                }
            }

            foreach (var pair in downloadCollection)
            {
                if (!pair.Key.EqualsEx(AppData.Settings.ArchiveLang) && (string.IsNullOrEmpty(packageVersion) || !pair.Key.EqualsEx(packageVersion)))
                {
                    continue;
                }

                foreach (var(item1, item2) in pair.Value)
                {
                    var srcUrl = item1;
                    if (srcUrl.StartsWith("{", StringComparison.InvariantCulture) && srcUrl.EndsWith("}", StringComparison.InvariantCulture))
                    {
                        srcUrl = FindArchivePath(srcUrl).Item2;
                    }

                    if (DestPath == default)
                    {
                        if (!DirectoryEx.Create(Settings.TransferDir))
                        {
                            continue;
                        }
                        var fileName = Path.GetFileName(srcUrl);
                        if (string.IsNullOrEmpty(fileName))
                        {
                            continue;
                        }
                        DestPath = PathEx.Combine(Settings.TransferDir, fileName);
                    }

                    var           shortHost = NetEx.GetShortHost(srcUrl);
                    var           redirect  = Settings.ForceTransferRedirection || !NetEx.IPv4IsAvalaible && !string.IsNullOrWhiteSpace(shortHost) && !shortHost.EqualsEx(AppSupplierHosts.Internal);
                    string        userAgent;
                    List <string> mirrors;
                    switch (shortHost)
                    {
                    case AppSupplierHosts.Internal:
                        userAgent = UserAgents.Internal;
                        mirrors   = AppSupply.GetMirrors(AppSuppliers.Internal);
                        break;

                    case AppSupplierHosts.PortableApps:
                        userAgent = UserAgents.Empty;
                        mirrors   = AppSupply.GetMirrors(AppSuppliers.PortableApps);
                        break;

                    case AppSupplierHosts.SourceForge:
                        userAgent = UserAgents.Default;
                        mirrors   = AppSupply.GetMirrors(AppSuppliers.SourceForge);
                        break;

                    default:
                        userAgent = UserAgents.Default;
                        if (AppData.ServerKey != default)
                        {
                            var srv = Shareware.GetAddresses().FirstOrDefault(x => Shareware.FindAddressKey(x) == AppData.ServerKey.ToArray().Encode(BinaryToTextEncoding.Base85));
                            if (srv != default)
                            {
                                if (!srcUrl.StartsWithEx("http://", "https://"))
                                {
                                    srcUrl = PathEx.AltCombine(srv, srcUrl);
                                }
                                UserData = Tuple.Create(Shareware.GetUser(srv), Shareware.GetPassword(srv));
                            }
                        }
                        SrcData.Add(Tuple.Create(srcUrl, item2, userAgent, false));
                        continue;
                    }

                    var sHost = NetEx.GetShortHost(srcUrl);
                    var fhost = srcUrl.Substring(0, srcUrl.IndexOf(sHost, StringComparison.OrdinalIgnoreCase) + sHost.Length);
                    foreach (var mirror in mirrors)
                    {
                        if (!fhost.EqualsEx(mirror))
                        {
                            srcUrl = srcUrl.Replace(fhost, mirror);
                        }
                        if (SrcData.Any(x => x.Item1.EqualsEx(srcUrl)))
                        {
                            continue;
                        }
                        if (redirect)
                        {
                            userAgent = UserAgents.Internal;
                            srcUrl    = CorePaths.RedirectUrl + srcUrl.Encode();
                        }
                        SrcData.Add(Tuple.Create(srcUrl, item2, userAgent, false));
                        if (Log.DebugMode > 1)
                        {
                            Log.Write($"Transfer: '{srcUrl}' has been added.");
                        }
                    }
                }
                break;
            }
            Transfer = new WebTransferAsync();
        }
コード例 #21
0
        private void CopyDirectoryLocal(string sourcePath, string targetPath)
        {
            var entry = Util.Files.GetDirectoryEntry(
                new GetDirectoryEntryCommand
            {
                IncludeRootPath = true,
                Path            = sourcePath,
                Recurse         = this.Recursive
            }
                ).Entry;

            IEnumerable <SystemEntryInfo> matches;

            if (this.HasMasks)
            {
                matches = Util.Files.Comparison.GetMatches(sourcePath, entry, this.IncludeFileMasks);
            }
            else
            {
                matches = entry.Files.AsEnumerable <SystemEntryInfo>().Concat(entry.SubDirectories);
            }

            matches = matches.Where(m => m.Path != entry.Path);

            var files = matches.OfType <FileEntryInfo>();

            foreach (var file in files)
            {
                var targetFileName = PathEx.Combine(targetPath, file.Path.Substring(sourcePath.Length).TrimStart('/', '\\'));
                if (this.VerboseLogging)
                {
                    this.LogDebug($"Copying {file.Path} to {targetFileName}...");
                }

                try
                {
                    Inedo.IO.FileEx.Copy(file.Path, targetFileName, this.Overwrite);
                    this.filesCopied++;
                }
                catch (Exception ex)
                {
                    this.LogError($"Cannot copy {file.Path}: {ex.Message}");
                }
            }

            // ToArray is just to make entries subject to GC sooner
            var dirs = matches.OfType <DirectoryEntryInfo>().ToArray();

            foreach (var dir in dirs)
            {
                var targetDir = PathEx.Combine(targetPath, dir.Path.Substring(sourcePath.Length).TrimStart('/', '\\'));
                if (this.VerboseLogging)
                {
                    this.LogDebug($"Creating directory {targetDir}...");
                }

                DirectoryEx.Create(targetDir);
                this.directoriesCopied++;
                this.CopyDirectoryLocal(dir.Path, targetDir);
            }
        }