所以我在这里修改了一个示例代码https://code.msdn.microsoft.com/windowsdesktop/File-Synchronization-516e3ad7,以满足我的需求。这是一个控制台应用程序,它接受2个参数,第一个是源,第二个是目标。它是目标文件夹的单向同步源。
// <copyright file="SyncMain.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <summary>Sample code for using the MSF File Sync Provider</summary>
using System;
using System.IO;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Files;
public class FileSyncProviderSample
{
public static void Main(string[] args)
{
if (args.Length < 2 ||
string.IsNullOrEmpty(args[0]) || string.IsNullOrEmpty(args[1]) ||
!Directory.Exists(args[0]) || !Directory.Exists(args[1]))
{
Console.WriteLine(
"Usage: FileSyncSample [valid directory path 1] [valid directory path 2]");
return;
}
string replica1RootPath = args[0];
string replica2RootPath = args[1];
try
{
// Set options for the sync operation
FileSyncOptions options =
FileSyncOptions.ExplicitDetectChanges |
FileSyncOptions.RecycleDeletedFiles |
FileSyncOptions.RecyclePreviousFileOnUpdates |
FileSyncOptions.RecycleConflictLoserFiles;
FileSyncScopeFilter filter = new FileSyncScopeFilter();
filter.FileNameExcludes.Add("*.lnk"); // Exclude all *.lnk files
// Explicitly detect changes on both replicas upfront, to avoid two change
// detection passes for the two-way sync
DetectChangesOnFileSystemReplica(
replica1RootPath, filter, options);
DetectChangesOnFileSystemReplica(
replica2RootPath, filter, options);
// Sync in both directions
SyncFileSystemReplicasOneWay(replica1RootPath, replica2RootPath, null, options);
//SyncFileSystemReplicasOneWay(replica2RootPath, replica1RootPath, null, options);
}
catch (Exception e)
{
Console.WriteLine("\nException from File Sync Provider:\n" + e.ToString());
}
}
public static void DetectChangesOnFileSystemReplica(
string replicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider provider = null;
try
{
provider = new FileSyncProvider(replicaRootPath, filter, options);
provider.DetectChanges();
}
finally
{
// Release resources
if (provider != null)
provider.Dispose();
}
}
public static void SyncFileSystemReplicasOneWay(
string sourceReplicaRootPath, string destinationReplicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider sourceProvider = null;
FileSyncProvider destinationProvider = null;
try
{
sourceProvider = new FileSyncProvider(
sourceReplicaRootPath, filter, options);
destinationProvider = new FileSyncProvider(
destinationReplicaRootPath, filter, options);
destinationProvider.AppliedChange +=
new EventHandler<AppliedChangeEventArgs>(OnAppliedChange);
destinationProvider.SkippedChange +=
new EventHandler<SkippedChangeEventArgs>(OnSkippedChange);
SyncOrchestrator agent = new SyncOrchestrator();
agent.LocalProvider = sourceProvider;
agent.RemoteProvider = destinationProvider;
agent.Direction = SyncDirectionOrder.Upload; // Sync source to destination
Console.WriteLine("Synchronizing changes to replica: " +
destinationProvider.RootDirectoryPath);
agent.Synchronize();
}
finally
{
// Release resources
if (sourceProvider != null) sourceProvider.Dispose();
if (destinationProvider != null) destinationProvider.Dispose();
}
}
public static void OnAppliedChange(object sender, AppliedChangeEventArgs args)
{
switch(args.ChangeType)
{
case ChangeType.Create:
Console.WriteLine("-- Applied CREATE for file " + args.NewFilePath);
break;
case ChangeType.Delete:
Console.WriteLine("-- Applied DELETE for file " + args.OldFilePath);
break;
case ChangeType.Update:
Console.WriteLine("-- Applied OVERWRITE for file " + args.OldFilePath);
break;
case ChangeType.Rename:
Console.WriteLine("-- Applied RENAME for file " + args.OldFilePath +
" as " + args.NewFilePath);
break;
}
}
public static void OnSkippedChange(object sender, SkippedChangeEventArgs args)
{
Console.WriteLine("-- Skipped applying " + args.ChangeType.ToString().ToUpper()
+ " for " + (!string.IsNullOrEmpty(args.CurrentFilePath) ?
args.CurrentFilePath : args.NewFilePath) + " due to error");
if (args.Exception != null)
Console.WriteLine(" [" + args.Exception.Message + "]");
}
}
它的工作原理与预期的一样,但是当我修改代码并在Unity中使用它时,它会在编辑器播放模式中崩溃,并且在运行构建时不会执行任何操作。崩溃似乎源于agent.Synchronize();
Unity中的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Files;
using System;
using System.IO;
public class FileSyncTest : MonoBehaviour
{
[SerializeField] private string replica1RootPath;
[SerializeField] private string replica2RootPath;
[SerializeField] private KeyCode activateSyncKey = KeyCode.Keypad5;
private void Update()
{
if (Input.GetKeyDown(activateSyncKey))
{
if (Directory.Exists(replica1RootPath) || Directory.Exists(replica2RootPath))
{
try
{
// Set options for the sync operation
FileSyncOptions options =
FileSyncOptions.ExplicitDetectChanges |
FileSyncOptions.RecycleDeletedFiles |
FileSyncOptions.RecyclePreviousFileOnUpdates |
FileSyncOptions.RecycleConflictLoserFiles;
FileSyncScopeFilter filter = new FileSyncScopeFilter();
filter.FileNameExcludes.Add("*.lnk"); // Exclude all *.lnk files
// Explicitly detect changes on both replicas upfront, to avoid two change
// detection passes for the two-way sync
DetectChangesOnFileSystemReplica(
replica1RootPath, filter, options);
DetectChangesOnFileSystemReplica(
replica2RootPath, filter, options);
// Sync in both directions
SyncFileSystemReplicasOneWay(replica1RootPath, replica2RootPath, null, options);
//SyncFileSystemReplicasOneWay(replica2RootPath, replica1RootPath, null, options);
}
catch (Exception e)
{
Debug.Log("\nException from File Sync Provider:\n" + e.ToString());
}
}
else
{
Debug.Log("One of the dir doesn't exist");
}
}
}
public void DetectChangesOnFileSystemReplica(
string replicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider provider = null;
try
{
provider = new FileSyncProvider(replicaRootPath, filter, options);
provider.DetectChanges();
}
finally
{
// Release resources
if (provider != null)
provider.Dispose();
}
}
private void SyncFileSystemReplicasOneWay(
string sourceReplicaRootPath, string destinationReplicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider sourceProvider = null;
FileSyncProvider destinationProvider = null;
try
{
sourceProvider = new FileSyncProvider(
sourceReplicaRootPath, filter, options);
destinationProvider = new FileSyncProvider(
destinationReplicaRootPath, filter, options);
destinationProvider.AppliedChange +=
new EventHandler<AppliedChangeEventArgs>(OnAppliedChange);
destinationProvider.SkippedChange +=
new EventHandler<SkippedChangeEventArgs>(OnSkippedChange);
SyncOrchestrator agent = new SyncOrchestrator();
agent.LocalProvider = sourceProvider;
agent.RemoteProvider = destinationProvider;
agent.Direction = SyncDirectionOrder.Upload; // Sync source to destination
Debug.Log("Synchronizing changes to replica: " +
destinationProvider.RootDirectoryPath);
agent.Synchronize();
}
finally
{
// Release resources
if (sourceProvider != null) sourceProvider.Dispose();
if (destinationProvider != null) destinationProvider.Dispose();
}
}
private void OnAppliedChange(object sender, AppliedChangeEventArgs args)
{
switch (args.ChangeType)
{
case ChangeType.Create:
Debug.Log("-- Applied CREATE for file " + args.NewFilePath);
break;
case ChangeType.Delete:
Debug.Log("-- Applied DELETE for file " + args.OldFilePath);
break;
case ChangeType.Update:
Debug.Log("-- Applied OVERWRITE for file " + args.OldFilePath);
break;
case ChangeType.Rename:
Debug.Log("-- Applied RENAME for file " + args.OldFilePath +
" as " + args.NewFilePath);
break;
}
}
private void OnSkippedChange(object sender, SkippedChangeEventArgs args)
{
Debug.Log("-- Skipped applying " + args.ChangeType.ToString().ToUpper()
+ " for " + (!string.IsNullOrEmpty(args.CurrentFilePath) ?
args.CurrentFilePath : args.NewFilePath) + " due to error");
if (args.Exception != null)
Debug.Log(" [" + args.Exception.Message + "]");
}
}
我已将所需的DLL复制到项目文件夹中,下面是我复制的DLL。
Editor.log - https://pastebin.com/3MnNFY4z
任何帮助将不胜感激!