├── .gitignore
├── LICENSE
├── Plugin.EmbeddedResource
├── Plugin.EmbeddedResource.csproj
├── Plugin.EmbeddedResource.nuspec
├── Properties
│ └── AssemblyInfo.cs
├── ResourceLoader.cs
├── ResourceWriter.cs
└── packages.config
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | [Rr]eleases/
14 | x64/
15 | x86/
16 | build/
17 | bld/
18 | [Bb]in/
19 | [Oo]bj/
20 |
21 | # Roslyn cache directories
22 | *.ide/
23 |
24 | # MSTest test Results
25 | [Tt]est[Rr]esult*/
26 | [Bb]uild[Ll]og.*
27 |
28 | #NUNIT
29 | *.VisualState.xml
30 | TestResult.xml
31 |
32 | # Build Results of an ATL Project
33 | [Dd]ebugPS/
34 | [Rr]eleasePS/
35 | dlldata.c
36 |
37 | *_i.c
38 | *_p.c
39 | *_i.h
40 | *.ilk
41 | *.meta
42 | *.obj
43 | *.pch
44 | *.pdb
45 | *.pgc
46 | *.pgd
47 | *.rsp
48 | *.sbr
49 | *.tlb
50 | *.tli
51 | *.tlh
52 | *.tmp
53 | *.tmp_proj
54 | *.log
55 | *.vspscc
56 | *.vssscc
57 | .builds
58 | *.pidb
59 | *.svclog
60 | *.scc
61 |
62 | # Chutzpah Test files
63 | _Chutzpah*
64 |
65 | # Visual C++ cache files
66 | ipch/
67 | *.aps
68 | *.ncb
69 | *.opensdf
70 | *.sdf
71 | *.cachefile
72 |
73 | # Visual Studio profiler
74 | *.psess
75 | *.vsp
76 | *.vspx
77 |
78 | # TFS 2012 Local Workspace
79 | $tf/
80 |
81 | # Guidance Automation Toolkit
82 | *.gpState
83 |
84 | # ReSharper is a .NET coding add-in
85 | _ReSharper*/
86 | *.[Rr]e[Ss]harper
87 | *.DotSettings.user
88 |
89 | # JustCode is a .NET coding addin-in
90 | .JustCode
91 |
92 | # TeamCity is a build add-in
93 | _TeamCity*
94 |
95 | # DotCover is a Code Coverage Tool
96 | *.dotCover
97 |
98 | # NCrunch
99 | _NCrunch_*
100 | .*crunch*.local.xml
101 |
102 | # MightyMoose
103 | *.mm.*
104 | AutoTest.Net/
105 |
106 | # Web workbench (sass)
107 | .sass-cache/
108 |
109 | # Installshield output folder
110 | [Ee]xpress/
111 |
112 | # DocProject is a documentation generator add-in
113 | DocProject/buildhelp/
114 | DocProject/Help/*.HxT
115 | DocProject/Help/*.HxC
116 | DocProject/Help/*.hhc
117 | DocProject/Help/*.hhk
118 | DocProject/Help/*.hhp
119 | DocProject/Help/Html2
120 | DocProject/Help/html
121 |
122 | # Click-Once directory
123 | publish/
124 |
125 | # Publish Web Output
126 | *.[Pp]ublish.xml
127 | *.azurePubxml
128 | # TODO: Comment the next line if you want to checkin your web deploy settings
129 | # but database connection strings (with potential passwords) will be unencrypted
130 | *.pubxml
131 | *.publishproj
132 |
133 | # NuGet Packages
134 | *.nupkg
135 | # The packages folder can be ignored because of Package Restore
136 | **/packages/*
137 | # except build/, which is used as an MSBuild target.
138 | !**/packages/build/
139 | # If using the old MSBuild-Integrated Package Restore, uncomment this:
140 | #!**/packages/repositories.config
141 |
142 | # Windows Azure Build Output
143 | csx/
144 | *.build.csdef
145 |
146 | # Windows Store app package directory
147 | AppPackages/
148 |
149 | # Others
150 | sql/
151 | *.Cache
152 | ClientBin/
153 | [Ss]tyle[Cc]op.*
154 | ~$*
155 | *~
156 | *.dbmdl
157 | *.dbproj.schemaview
158 | *.pfx
159 | *.publishsettings
160 | node_modules/
161 |
162 | # RIA/Silverlight projects
163 | Generated_Code/
164 |
165 | # Backup & report files from converting an old project file
166 | # to a newer Visual Studio version. Backup files are not needed,
167 | # because we have git ;-)
168 | _UpgradeReport_Files/
169 | Backup*/
170 | UpgradeLog*.XML
171 | UpgradeLog*.htm
172 |
173 | # SQL Server files
174 | *.mdf
175 | *.ldf
176 |
177 | # Business Intelligence projects
178 | *.rdl.data
179 | *.bim.layout
180 | *.bim_*.settings
181 |
182 | # Microsoft Fakes
183 | FakesAssemblies/
184 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Joseph Hill
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Plugin.EmbeddedResource/Plugin.EmbeddedResource.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
7 | 8.0.30703
8 | 2.0
9 | {AC1ABE2A-1B90-49C1-A723-742AE6BE4D4E}
10 | Library
11 | Plugin.EmbeddedResource
12 | Plugin.EmbeddedResource
13 | Profile78
14 | v4.5
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug
21 | DEBUG;
22 | prompt
23 | 4
24 | false
25 |
26 |
27 | full
28 | true
29 | bin\Release
30 | prompt
31 | 4
32 | false
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | ..\..\PortableRazorStarterKit\PortableCongress\packages\PCLStorage.1.0.0\lib\portable-net45+wp8+wpa81+win8+monoandroid+monotouch+Xamarin.iOS+Xamarin.Mac\PCLStorage.dll
43 |
44 |
45 | ..\..\PortableRazorStarterKit\PortableCongress\packages\PCLStorage.1.0.0\lib\portable-net45+wp8+wpa81+win8+monoandroid+monotouch+Xamarin.iOS+Xamarin.Mac\PCLStorage.Abstractions.dll
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Plugin.EmbeddedResource/Plugin.EmbeddedResource.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Xam.Plugin.EmbeddedResource
5 | 1.0.1.0
6 | EmbeddedResource Plugin for Xamarin and Windows
7 | Joseph Hill
8 | Joseph Hill
9 | https://github.com/JosephHill/EmbeddedResourcePlugin/blob/master/LICENSE
10 | https://github.com/JosephHill/EmbeddedResourcePlugin
11 | https://files.xamarin.com/~joseph/EmbeddedResource_128.png
12 | false
13 |
14 | A cross-platform convenience library for unpacking embedded resources.
15 |
16 |
17 | Mobile applications often need to bundle files with the app, such as a SQLite database or static HTML or images, that will later be accessed from the file system.
18 |
19 | The EmbeddedResource Plugin for Xamarin and Windows is a Portable Class Library (PCL) that provides a cross-platform API to read files embedded in a .NET assembly and write these files to disk via [PCL Storage](https://pclstorage.codeplex.com/).
20 |
21 | Fix path handling on Windows Phone
22 | Copyright 2015, Xamarin Inc.
23 | xamarin, pcl, xam.pcl, windows phone, winphone, wp8, winrt, android, xamarin.forms, ios
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Plugin.EmbeddedResource/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 |
4 | // Information about this assembly is defined by the following attributes.
5 | // Change them to the values specific to your project.
6 |
7 | [assembly: AssemblyTitle ("Plugin.EmbeddedResource")]
8 | [assembly: AssemblyDescription ("")]
9 | [assembly: AssemblyConfiguration ("")]
10 | [assembly: AssemblyCompany ("")]
11 | [assembly: AssemblyProduct ("")]
12 | [assembly: AssemblyCopyright ("joseph")]
13 | [assembly: AssemblyTrademark ("")]
14 | [assembly: AssemblyCulture ("")]
15 |
16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision,
18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision.
19 |
20 | [assembly: AssemblyVersion ("1.0.*")]
21 |
22 | // The following attributes are used to specify the signing key for the assembly,
23 | // if desired. See the Mono documentation for more information about signing.
24 |
25 | //[assembly: AssemblyDelaySign(false)]
26 | //[assembly: AssemblyKeyFile("")]
27 |
28 |
--------------------------------------------------------------------------------
/Plugin.EmbeddedResource/ResourceLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Reflection;
5 |
6 | namespace Plugin.EmbeddedResource
7 | {
8 |
9 | ///
10 | /// Utility class that can be used to find and load embedded resources into memory.
11 | ///
12 | public static class ResourceLoader
13 | {
14 | ///
15 | /// Attempts to find and return the given resource from within the specified assembly.
16 | ///
17 | /// The embedded resource stream.
18 | /// containing embedded resources.
19 | /// Full name of embedded resource in .
20 | public static Stream GetEmbeddedResourceStream(Assembly assembly, string resource)
21 | {
22 | var resourceNames = assembly.GetManifestResourceNames();
23 |
24 | var resourcePaths = resourceNames
25 | .Where(x => x.EndsWith(resource, StringComparison.CurrentCultureIgnoreCase))
26 | .ToArray();
27 |
28 | if (!resourcePaths.Any())
29 | {
30 | throw new Exception(string.Format("Resource ending with {0} not found.", resource));
31 | }
32 |
33 | if (resourcePaths.Count() > 1)
34 | {
35 | throw new Exception(string.Format("Multiple resources ending with {0} found: {1}{2}", resource, Environment.NewLine, string.Join(Environment.NewLine, resourcePaths)));
36 | }
37 |
38 | return assembly.GetManifestResourceStream(resourcePaths.Single());
39 | }
40 |
41 | ///
42 | /// Attempts to find and return the given resource from within the specified assembly.
43 | ///
44 | /// The embedded resource as a byte array.
45 | /// containing embedded resources.
46 | /// Full name of embedded resource in .
47 | public static byte[] GetEmbeddedResourceBytes(Assembly assembly, string resource)
48 | {
49 | var stream = GetEmbeddedResourceStream(assembly, resource);
50 |
51 | using (var memoryStream = new MemoryStream())
52 | {
53 | stream.CopyTo(memoryStream);
54 | return memoryStream.ToArray();
55 | }
56 | }
57 |
58 | ///
59 | /// Attempts to find and return the given resource from within the specified assembly.
60 | ///
61 | /// The embedded resource as a string.
62 | /// containing embedded resources.
63 | /// Full name of embedded resource in .
64 | public static string GetEmbeddedResourceString(Assembly assembly, string resource)
65 | {
66 | var stream = GetEmbeddedResourceStream(assembly, resource);
67 |
68 | using (var streamReader = new StreamReader(stream))
69 | {
70 | return streamReader.ReadToEnd();
71 | }
72 | }
73 | }
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/Plugin.EmbeddedResource/ResourceWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using System.Threading.Tasks;
5 | using PCLStorage;
6 |
7 | namespace Plugin.EmbeddedResource
8 | {
9 | public class ResourceWriter
10 | {
11 | private Assembly Assembly { get; set; }
12 |
13 | ///
14 | /// Creates a new
15 | ///
16 | /// containing embedded resources.
17 | public ResourceWriter (Assembly assembly)
18 | {
19 | this.Assembly = assembly;
20 | }
21 |
22 | ///
23 | /// Writes all of the embedded resources in a project folder to the target directory
24 | ///
25 | /// Path to embedded resources in assembly.
26 | /// Path to folder where resources will be written.
27 | /// Descend into subdirectories to retrieve resources.
28 | /// Recursive writes will treat "." as path delimiters (excluding a final "." for the file extension).
29 | /// Non-recursive treats all "." as part of the file name.
30 | ///
31 | /// A which will complete after the folder is written
32 | ///
33 | public async Task WriteFolder (string sourceDirectory, string targetDirectory = "", bool recursive = true, CreationCollisionOption option = CreationCollisionOption.ReplaceExisting) {
34 | await WriteFolder (
35 | this.Assembly,
36 | sourceDirectory,
37 | targetDirectory,
38 | recursive,
39 | option);
40 | }
41 |
42 | ///
43 | /// Writes an embedded resource to the file system
44 | ///
45 | /// containing embedded resources.
46 | /// Relative path to embedded resource in .
47 | /// Path to folder where resources will be written.
48 | ///
49 | /// A which will complete after the file is written
50 | ///
51 | public async Task WriteFile (string source, string targetDirectory = "", CreationCollisionOption option = CreationCollisionOption.ReplaceExisting) {
52 | await WriteFile (
53 | this.Assembly,
54 | source,
55 | targetDirectory,
56 | option);
57 | }
58 |
59 | ///
60 | /// Writes an embedded resource to the file system
61 | ///
62 | /// Path and name to write the resource to the filesystem.
63 | /// Full name of embedded resource in .
64 | ///
65 | /// A which will complete after the file is written
66 | ///
67 | public async Task WriteResource (string fileName, string resource, CreationCollisionOption option = CreationCollisionOption.ReplaceExisting) {
68 | await WriteResource (
69 | this.Assembly,
70 | fileName,
71 | resource,
72 | option);
73 | }
74 |
75 |
76 | ///
77 | /// Writes all of the embedded resources in a project folder to the target directory
78 | ///
79 | /// containing embedded resources.
80 | /// Path to embedded resources in assembly.
81 | /// Path to folder where resources will be written.
82 | /// Descend into subdirectories to retrieve resources.
83 | /// Recursive writes will treat "." as path delimiters (excluding a final "." for the file extension).
84 | /// Non-recursive treats all "." as part of the file name.
85 | ///
86 | /// A which will complete after the folder is written
87 | ///
88 | public static async Task WriteFolder (Assembly assembly, string sourceDirectory, string targetDirectory = "", bool recursive = true, CreationCollisionOption option = CreationCollisionOption.ReplaceExisting) {
89 | var sourcePrefix = String.Format ("{0}.{1}.",
90 | assembly.GetName ().Name,
91 | ConvertPathToResourceName (sourceDirectory));
92 |
93 | foreach (var resource in assembly.GetManifestResourceNames()
94 | .Where(a => a.StartsWith(sourcePrefix))
95 | .Select(b => b)) {
96 |
97 | // strip assembly name from resource
98 | var relativePathAndFilename = resource.Substring (sourcePrefix.Length);
99 |
100 | // .NET embedded resources replace path delimiters with "."
101 | // on recursive write, turn "." into directory separators
102 |
103 | if (recursive) {
104 | // assume that the last "." is the file extension delimiter
105 | var lastDot = relativePathAndFilename.LastIndexOf (".");
106 |
107 | // treat any other "." as a path delimiter
108 | if (lastDot > -1)
109 | relativePathAndFilename =
110 | relativePathAndFilename.Substring (0, lastDot).Replace ('.', PortablePath.DirectorySeparatorChar) +
111 | "." +
112 | relativePathAndFilename.Substring (lastDot + 1);
113 | }
114 |
115 | await WriteResource (
116 | assembly,
117 | PortablePath.Combine (targetDirectory, relativePathAndFilename),
118 | resource,
119 | option);
120 | }
121 | }
122 |
123 | ///
124 | /// Writes an embedded resource to the file system
125 | ///
126 | /// containing embedded resources.
127 | /// Relative path to embedded resource in .
128 | /// Path to folder where resources will be written.
129 | ///
130 | /// A which will complete after the file is written
131 | ///
132 | public static async Task WriteFile (Assembly assembly, string source, string targetDirectory = "", CreationCollisionOption option = CreationCollisionOption.ReplaceExisting) {
133 | var resource = String.Format ("{0}.{1}",
134 | assembly.GetName ().Name,
135 | ConvertPathToResourceName (source));
136 |
137 | // handle either slash as path delimiter
138 | source = source.Replace("\\", "/");
139 |
140 | var fileName = source.Substring (
141 | source.LastIndexOf ("/") + 1);
142 |
143 | await WriteResource (
144 | assembly,
145 | PortablePath.Combine(targetDirectory, fileName),
146 | resource,
147 | option);
148 | }
149 |
150 | ///
151 | /// Writes an embedded resource to the file system
152 | ///
153 | /// containing embedded resources.
154 | /// Path and name to write the resource to the filesystem.
155 | /// Full name of embedded resource in .
156 | ///
157 | /// A which will complete after the file is written
158 | ///
159 | public static async Task WriteResource (Assembly assembly, string fileName, string resource, CreationCollisionOption option = CreationCollisionOption.ReplaceExisting) {
160 | var folderName = fileName.Substring (
161 | 0,
162 | fileName.LastIndexOf (PortablePath.DirectorySeparatorChar));
163 |
164 | var folder = GetStorageFromPath (folderName);
165 |
166 | if (folder == null)
167 | folder = FileSystem.Current.LocalStorage;
168 | else
169 | if (folderName != folder.Path)
170 | // need to create subfolder
171 | folder = await folder.CreateFolderAsync (
172 | folderName.Substring (folder.Path.Length + 1),
173 | CreationCollisionOption.OpenIfExists);
174 |
175 | var file = await folder.CreateFileAsync(
176 | fileName.Substring(fileName.LastIndexOf (PortablePath.DirectorySeparatorChar) + 1),
177 | option);
178 |
179 | using (var input = ResourceLoader.GetEmbeddedResourceStream(assembly, resource))
180 | using (var output = await file.OpenAsync(FileAccess.ReadAndWrite)) {
181 | byte[] buffer = new byte[1024];
182 | int length;
183 | while ((length = input.Read (buffer, 0, 1024)) > 0)
184 | output.Write (buffer, 0, length);
185 | output.Flush ();
186 | }
187 | }
188 |
189 | ///
190 | /// Converts file system style path to resource name
191 | ///
192 | /// Path to be parsed.
193 | ///
194 | /// Resource name with path delimiters replaced with "."
195 | ///
196 | private static string ConvertPathToResourceName (string path) {
197 | return path.Replace ('/','.').Replace ('\\','.');
198 | }
199 |
200 | ///
201 | /// Determines which storage in FileSystem.Current that is represented by the path
202 | ///
203 | /// Path to be parsed.
204 | ///
205 | /// IFolder that contains path. Returns null if there is no matching storage
206 | ///
207 | private static IFolder GetStorageFromPath (string path) {
208 | if (path.StartsWith (FileSystem.Current.LocalStorage.Path))
209 | return FileSystem.Current.LocalStorage;
210 |
211 | if (path.StartsWith (FileSystem.Current.RoamingStorage.Path))
212 | return FileSystem.Current.RoamingStorage;
213 |
214 | return null;
215 | }
216 | }
217 | }
218 |
219 |
--------------------------------------------------------------------------------
/Plugin.EmbeddedResource/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | EmbeddedResourcePlugin
2 | ======================
3 | Mobile applications often need to bundle files with the app, such as a SQLite database or static HTML or images, that will later be accessed from the file system.
4 |
5 | The EmbeddedResource Plugin for Xamarin and Windows is a Portable Class Library (PCL) that provides a cross-platform API to read files embedded in a .NET assembly and write these files to disk via [PCL Storage](https://pclstorage.codeplex.com/).
6 |
7 | ## Using EmbeddedResource Plugin
8 | Files included in .NET projects can be included as Embedded Resources by setting the Build Action for the file to `EmbeddedResource`. EmbeddedResource Plugin provides two main methods for writing these resources: `ResourceWriter.WriteFile` and `ResourceWriter.WriteFolder`.
9 |
10 | The full name for a resource in the root of a project will be comprised of the assembly followed by the name of the file. An embedded resource located in a subdirectory of a project will include the relative path to the file in the name, using "." as a path delimeter.
11 |
12 | For example:
13 | ```
14 | db.sqlite
15 | ```
16 | in the root of MyProject.dll becomes
17 | ```
18 | MyProject.db.sqlite
19 | ```
20 |
21 | and
22 | ```
23 | images\icon.png
24 | ```
25 | in the images subdirectory of MyProject.dll becomes
26 | ```
27 | MyProject.images.icon.png
28 | ```
29 |
30 | The `WriteFile` and `WriteFolder` methods simplify decoding this naming scheme by allowing you to provide paths to a resource in a project, along with an output path, so that writing an embedded resource feels more like performing a copy operation. E.g. `writer.WriteFile("www\index.html", "webroot");`
31 |
32 | A simple C# class that uses EmbeddedResource Plugin for Xamarin and Windows to initialize data for an app might look like:
33 | ```csharp
34 | using PCLStorage;
35 | using Plugin.EmbeddedResource;
36 |
37 | namespace Sample
38 | {
39 | public class SampleLib
40 | {
41 | public SampleLib ()
42 | {
43 | }
44 |
45 | public static async Task Init(Assembly assembly) {
46 | var rootFolder = FileSystem.Current.LocalStorage;
47 |
48 | var writer = new ResourceWriter (assembly);
49 |
50 | // Only need to write the bundled files once.
51 | if(await rootFolder.CheckExistsAsync("db.sqlite") == ExistenceCheckResult.NotFound) {
52 | await writer.WriteFile ("App_data/db.sqlite", rootFolder.Path);
53 | await writer.WriteFolder ("images", rootFolder.Path);
54 | }
55 | }
56 | }
57 | }
58 | ```
59 |
60 | Notes on usage
61 | ==============
62 | When a file is embedded as a resource, it becomes impossible to differentiate a path delimiter "." from a file extension ".". For example, www/images/big.button.png looks just like www/images/big/button.png. For this reason, `WriteFolder` always treats the final "." in a resource name as the file extension delimiter by default. Calling `WriteFolder` with `recursive = false` will do a non-recursive copy of all resources in the specified source path (i.e., all instances of "." will be treated as part of the filename for every file in the specified folder).
63 |
64 | Because some platforms^H supported by PCL Storage provide only asynchronous file access, the `ResourceWriter.WriteFile` and `ResourceWriter.WriteFolder` APIs are also asynchronous. Anything you want to do in your app that depends on these resources having been written to disk (such as showing the data from the database) will need to await the completion of these calls.
65 |
--------------------------------------------------------------------------------