@@ -17,22 +17,160 @@ sealed class WindowsFileSystem : IOPath.FileSystemBase
1717 /// <inheritdoc cref="FileSystem2.InitFileSystem"/>
1818 public static void InitFileSystem ( )
1919 {
20+ var isPrivilegedProcess = WindowsPlatformServiceImpl . IsPrivilegedProcess ;
21+ if ( isPrivilegedProcess )
22+ {
23+ // 删除早期版本在根目录下的本机库,避免因旧版本文件存在,可能从根目录上加载了旧的本机库
24+ var rootDeleteFiles = new [ ]
25+ {
26+ "7z.dll" ,
27+ "aspnetcorev2_inprocess.dll" ,
28+ "av_libglesv2.dll" ,
29+ "e_sqlite3.dll" ,
30+ "libHarfBuzzSharp.dll" ,
31+ "libSkiaSharp.dll" ,
32+ "WebView2Loader.dll" ,
33+ "WinDivert.dll" ,
34+ "WinDivert64.sys" ,
35+ } ;
36+ foreach ( var item in rootDeleteFiles )
37+ {
38+ var path = Path . Combine ( IOPath . AppDataDirectory , item ) ;
39+ IOPath . FileTryDelete ( path ) ;
40+ }
41+ }
42+
2043 if ( WindowsPlatformServiceImpl . CurrentAppIsInstallVersion )
2144 {
2245 /* 安装版将使用以下路径,但如果根目录上有文件夹则会优先使用根目录上的文件夹(从 2.7.0+ 开始)
2346 * Environment.SpecialFolder.LocalApplicationData
2447 * Path.GetTempPath()
2548 */
26- InitFileSystemUseDestFirst (
27- AppDataDirectory ,
28- CacheDirectory ,
29- FileSystem2 . BaseDirectory . AppDataDirectory ,
30- FileSystem2 . BaseDirectory . CacheDirectory ) ;
49+ InitFileSystemByInstallVersion ( ) ;
3150 return ;
3251 }
3352 FileSystem2 . InitFileSystem ( ) ;
3453 }
3554
55+ /// <summary>
56+ /// 初始化文件系统,将旧目录上的文件夹复制到新的上,并使用新的
57+ /// </summary>
58+ /// <param name="destAppDataPath">新的 AppData 文件夹路径</param>
59+ /// <param name="destCachePath">新的 Cache 文件夹路径</param>
60+ /// <param name="sourceAppDataPath">旧的 AppData 文件夹路径</param>
61+ /// <param name="sourceCachePath">旧的 Cache 文件夹路径</param>
62+ static void InitFileSystemByInstallVersion ( )
63+ {
64+ var appDataDirectory = AppDataDirectory ;
65+ var cacheDirectory = CacheDirectory ;
66+
67+ DirectoryInfo oldAppDataDirectoryInfo = new ( FileSystem2 . BaseDirectory . AppDataDirectory ) ;
68+ if ( oldAppDataDirectoryInfo . Exists )
69+ {
70+ static void EnumerateDbFiles (
71+ string oldAppData ,
72+ string newAppData ,
73+ string [ ] dbFiles ,
74+ bool isCopyOrDelete )
75+ {
76+ var item = dbFiles [ 0 ] ;
77+ var dbFilePath = Path . Combine ( oldAppData , item ) ;
78+ if ( File . Exists ( dbFilePath ) )
79+ {
80+ var destFilePath = Path . Combine ( newAppData , item ) ;
81+ var hashFilePath = destFilePath + "_hash.tmp" ;
82+ if ( isCopyOrDelete )
83+ {
84+ if ( File . Exists ( destFilePath ) )
85+ {
86+ return ; // 数据库文件存在时,忽略
87+ }
88+ else
89+ {
90+ // 复制文件并记录 Hash
91+ if ( File . Exists ( hashFilePath ) )
92+ {
93+ // Hash 文件存在,也忽略
94+ return ;
95+ }
96+ var hash = CalcHashData ( dbFilePath ) ;
97+ File . WriteAllBytes ( hashFilePath , hash ) ;
98+ File . Copy ( dbFilePath , destFilePath , true ) ;
99+ foreach ( var item2 in dbFiles . Skip ( 1 ) )
100+ {
101+ dbFilePath = Path . Combine ( oldAppData , item2 ) ;
102+ destFilePath = Path . Combine ( newAppData , item2 ) ;
103+ File . Copy ( dbFilePath , destFilePath , true ) ;
104+ }
105+ }
106+ }
107+ else
108+ {
109+ if ( File . Exists ( hashFilePath ) )
110+ {
111+ var hash = CalcHashData ( dbFilePath ) ;
112+ var hash2 = File . ReadAllBytes ( hashFilePath ) ;
113+ if ( hash . SequenceEqual ( hash2 ) )
114+ {
115+ IOPath . FileTryDelete ( dbFilePath ) ;
116+ foreach ( var item2 in dbFiles . Skip ( 1 ) )
117+ {
118+ dbFilePath = Path . Combine ( oldAppData , item2 ) ;
119+ IOPath . FileTryDelete ( dbFilePath ) ;
120+ }
121+ IOPath . FileTryDelete ( hashFilePath ) ;
122+ }
123+ }
124+ }
125+
126+ static byte [ ] CalcHashData ( string path )
127+ {
128+ using var fs = IOPath . OpenRead ( path ) ;
129+ var hashData = fs == null ? Array . Empty < byte > ( ) : Hashs . ByteArray . SHA384 ( fs ) ;
130+ return hashData ;
131+ }
132+ }
133+ }
134+
135+ bool ? isCopyOrDelete = null ;
136+ var isMainProcess = Startup . Instance . IsMainProcess ;
137+ var isPrivilegedProcess = WindowsPlatformServiceImpl . IsPrivilegedProcess ;
138+ if ( isMainProcess )
139+ {
140+ // 主进程将数据库文件复制到当前存储目录,并标记
141+ isCopyOrDelete = true ;
142+
143+ }
144+ else if ( isPrivilegedProcess )
145+ {
146+ // 有标记的情况则删除
147+ isCopyOrDelete = false ;
148+ }
149+
150+ if ( isCopyOrDelete . HasValue )
151+ {
152+ string [ ] db1Files = new [ ]
153+ {
154+ "application2.dbf" ,
155+ "application2.dbf-shm" ,
156+ "application2.dbf-wal" ,
157+ } ;
158+ EnumerateDbFiles ( oldAppDataDirectoryInfo . FullName , appDataDirectory , db1Files , isCopyOrDelete . Value ) ;
159+ string [ ] db2Files = new [ ]
160+ {
161+ "application2.dbf" ,
162+ "application2.dbf-shm" ,
163+ "application2.dbf-wal" ,
164+ } ;
165+ EnumerateDbFiles ( oldAppDataDirectoryInfo . FullName , appDataDirectory , db2Files , isCopyOrDelete . Value ) ;
166+ }
167+ }
168+
169+ InitFileSystem ( GetAppDataDirectory , GetCacheDirectory ) ;
170+ string GetAppDataDirectory ( ) => appDataDirectory ;
171+ string GetCacheDirectory ( ) => cacheDirectory ;
172+ }
173+
36174 static string AppDataDirectory
37175 {
38176 get
0 commit comments