What is the recommended path to save auto - generated files in? - windows

I am currently building a WinForms app and I need to create a bin file
in which I will serialize data. I let the user choose in which folder he wants the file to be saved in, but if he doesn't choose anything I want to save the file in a default path.
The thing is, I am not so familiar with windows' file system, and I am unable to find a good folder to save the file in.
My requirements from such folder are:
All windows computers should have it
The path to this folder all windows computer is the same
Is used for programs' auto-generated files as an "international default"
Not used frequently by the user (a "just don't touch" folder)
what is the common solution for such things?

You cas use a dedicated common ProgramData folder:
string CommonAppDataFolderPath
= Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
+ Path.DirectorySeparatorChar
+ AssemblyCompany
+ Path.DirectorySeparatorChar
+ AssemblyTitle
+ Path.DirectorySeparatorChar;
public string AssemblyCompany
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if ( attributes.Length == 0 )
{
return "";
}
return ((AssemblyCompanyAttribute)attributes[0]).Company;
}
}
public string AssemblyTitle
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if ( attributes.Length > 0 )
{
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
if ( titleAttribute.Title != "" )
{
return titleAttribute.Title;
}
}
return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
}
}

It is AppData and you can get it with Environment.GetFolderPath:
(Environment is in System.IO namespace)
string binPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SomeAppName");
// this will return something like this:
// C:\Users\SomeUserName\AppData\Roaming\SomeAppName

You can use System.Reflection to identify a path in the debug or release folder of your assembly:
public static string Path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), "someapp");

Related

PCLStorage - How to get path to writable folder?

I need download and save file. I using this code (with Xam.Plugins.DownloadManager and PCLStorage libraries):
public static string DownloadNewXml(string LinkToFile, string PathFile)
{
var downloadManager = CrossDownloadManager.Current;
CrossDownloadManager.Current.PathNameForDownloadedFile = new System.Func<IDownloadFile, string>(file => {
return PathFile;
});
try
{
var file = downloadManager.CreateDownloadFile(LinkToFile);
downloadManager.Start(file);
return "ok";
}
catch(Exception e)
{
return e.ToString() ;
}
}
Where PathFile is: FileSystem.Current.LocalStorage.Path + "file.xml";
This code throw exception on Android and UWP - i can't write file to this path (FileSystem.Current.LocalStorage.Path). So I have a question. How to get path to writable folder for my application on all platforms (Android, UWP, iOS)? Please help.
Try use Path.Combine(FileSystem.Current.LocalStorage.Path, "file.xml") instead

How to include resources to application for windows phone?

I have a problem: I created new c# project for windows phone (in VS 2013) and set test file property as "Copy if newer", but I cannot see file in emulator's Local folder. What do I do wrong?
More detailed:
Create app:
File->New->Project->Templates->Visual C#->Store Apps->Windows Phone Apps->Blank App (Windows Phone)
set test file property
run on emulator (there is a button for this) and list files with code:
async void listFolder()
{
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
Stack<StorageFolder> stack = new Stack<StorageFolder>();
stack.Push(local);
StorageFolder current;
string path;
byte[] bytes;
StorageFile logFile = await local.CreateFileAsync("log.txt", CreationCollisionOption.ReplaceExisting);
using (var s = await logFile.OpenStreamForWriteAsync())
{
while (stack.Count > 0)
{
current = stack.Pop();
foreach (StorageFolder f in await current.GetFoldersAsync())
{
stack.Push(f);
}
path = current.Path;
bytes = Encoding.UTF8.GetBytes(current.Path + "\n");
s.Write(bytes, 0, bytes.Length);
foreach (StorageFile f in await current.GetFilesAsync())
{
bytes = Encoding.UTF8.GetBytes(f.Path + "\n");
s.Write(bytes, 0, bytes.Length);
}
s.Flush();
}
}
}
Check file with Windows Phone Power Tools. Local folder contains log.txt only. Log contains Local directory and log file. No TestText.txt
How do I include file to application and access it on emulator?
Limitations:
I do need to held data on local storage (no web links, no cloud)
If you want to access files that come with your package, then you need to use Package.InstalledLocation, you won't find those files in ApplicationData.LocalFolder.
Note that files included in Package are read-only and you won't be able to write them.
Some more information you will also find at this answer.

Script to move files from folder to another folder using paths in text file

On Windows 8, could someone please help me create a script to move some images from a particular folder to another folder?
The file path that lists the images i want to move (not all images) from the folder are listed in this file: C:\Users\Emmanuel\Desktop\test.txt
The folder in which contains some of the images I want removed appear in this folder:
C:\Users\Computer\Desktop\Images1
The folder in which I want the images to be moved to is this folder:
C:\Users\Computer\Desktop\Images2
Your help will be much appreciated
Try this where SourcesFile is your test.txt and DestFolder is the destination.
public int Run()
{
if (!File.Exists(SourcesFile))
{
throw new ArgumentException("Source folder does not exist");
}
if (!Directory.Exists(DestFolder))
{
Console.WriteLine("Destination folder doesn't exist");
Console.WriteLine("Creating destination folder...");
Directory.CreateDirectory(DestFolder);
}
string[] files = File.ReadAllLines(SourcesFile);
Console.WriteLine("Moving {0} files...", files.Length);
foreach (string file in files)
{
string dest = Path.Combine(DestFolder, Path.GetFileName(file));
if (File.Exists(dest))
{
string newFilename = string.Format("{0}_{1}{2}",
Path.GetFileNameWithoutExtension(file),
Guid.NewGuid().ToString("N"),
Path.GetExtension(file));
string newDest = Path.Combine(DestFolder, newFilename);
Console.WriteLine("File {0} already exists, copying file to {1}", file, newDest);
File.Move(file, newDest);
continue;
}
File.Move(file, dest);
}
return 0;
}

Where are files saved while debugging a Silverlight 5 Application in Internet Explorer 10?

I have some code that saves an xml file to the file system.
public static void Save(T obj, string FileName)
{
if (Application.Current.HasElevatedPermissions)
{
string myDocuments = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string path = System.IO.Path.Combine(myDocuments, FileName);
using (var writer = new StreamWriter(path))
{
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, obj);
writer.Flush();
}
}
else
{
throw new Exception("Cannot Save File. Application Requires Elevated permissions.");
}
}
While debugging using Internet Explorer 10 the file is not saved to the listed path in the path variable "C:\Users\Travis\Documents\Save.xml"
I call load with the exact same path "C:\Users\Travis\Documents\Save.xml" and the file loads correctly but the file still does not exist at the listed location.
I searched the file system with no results for Save.xml but it has to exist since it is able to load after application exit.
If I access the same page using Chrome the file is created successfully at the location.
I am wondering where Internet Explorer saves the file?
I found that if I uncheck "Enable Protected Mode" in IE's Security tab then the file is created in the location as expected.

Plugin subdirectory in Azure deployment

I use MEF to extend my web application and I use the following folder structure
> bin
> extensions
> Plugin1
> Plugin2
> Plugin3
To achive this automatically, the plugin projects output paths are set to these directories. My application is working with and without azure. My problem is now, that it seems to be inpossible to include the extensions subdirectory automatically to the azure deployment package.
I've tried to set the build dependencies too, without success.
Is there another way?
Well,
I've struggled with the bin folder. The issue (if we may say "issue") is that the packaging process, just packs what is "copy to out directory" set to "copy if newer/aways" only for the Web application (Web Role) project. Having another assemblies in the BIN which are not explicitly referenced by the Web Application will not get deployed.
For my case, where I have pretty "static" references I just pack them in a ZIP, put them in a BLOB container and then use the Azure Bootstrapper to download, extract and put in the BIN folder these references. However, because I don't know the actual location of the BIN folder in a startup task, I use helper wrappers for the bootstrapper to make the trick.
You will need to get the list of local sites, which can be accomplished by something similar to:
public IEnumerable<string> WebSiteDirectories
{
get
{
string roleRootDir = Environment.GetEnvironmentVariable("RdRoleRoot");
string appRootDir = (RoleEnvironment.IsEmulated) ? Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory) : roleRootDir;
XDocument roleModelDoc = XDocument.Load(Path.Combine(roleRootDir, "RoleModel.xml"));
var siteElements = roleModelDoc.Root.Element(_roleModelNs + "Sites").Elements(_roleModelNs + "Site");
return
from siteElement in siteElements
where siteElement.Attribute("name") != null
&& siteElement.Attribute("name").Value == "Web"
&& siteElement.Attribute("physicalDirectory") != null
select Path.Combine(appRootDir, siteElement.Attribute("physicalDirectory").Value);
}
}
Where the _roleModelNs variable is defined as follows:
private readonly XNamespace _roleModelNs = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition";
Next you will need something similar to that method:
public void GetRequiredAssemblies(string pathToWebBinfolder)
{
string args = string.Join("",
#"-get https://your_account.blob.core.windows.net/path/to/plugin.zip -lr $lr(temp) -unzip """,
pathToWebBinfolder,
#""" -block");
this._bRunner.RunBootstrapper(args);
}
And the RunBootstrapper has following signature:
public bool RunBootstrapper (string args)
{
bool result = false;
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = this._bootstrapperPath;
psi.Arguments = args;
Trace.WriteLine("AS: Calling " + psi.FileName + " " + psi.Arguments + " ...");
psi.CreateNoWindow = true;
psi.ErrorDialog = false;
psi.UseShellExecute = false;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = false;
psi.RedirectStandardError = true;
// run elevated
// psi.Verb = "runas";
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(psi))
{
exeProcess.PriorityClass = ProcessPriorityClass.High;
string outString = string.Empty;
// use ansynchronous reading for at least one of the streams
// to avoid deadlock
exeProcess.OutputDataReceived += (s, e) =>
{
outString += e.Data;
};
exeProcess.BeginOutputReadLine();
// now read the StandardError stream to the end
// this will cause our main thread to wait for the
// stream to close
string errString = exeProcess.StandardError.ReadToEnd();
Trace.WriteLine("Process out string: " + outString);
Trace.TraceError("Process error string: " + errString);
result = true;
}
}
catch (Exception e)
{
Trace.TraceError("AS: " + e.Message + e.StackTrace);
result = false;
}
return result;
}
Of course, in your case you might want something a bit more complex, where you'll first try to fetch all plugins (if each plugin is in its own ZIP) via code, and then execute the GetRequiredAssemblies multiple times for each plugin. And this code might be executing in the RoleEntryPoint's OnStart method.
And also, if you plan to be more dynamic, you can also override the Run() method of your RoleEntryPoint subclass, and check for new plugins every minute for example.
Hope this helps!
EDIT
And how can you get the plugins deployed. Well, you can either manually upload your plugins, or you can develop a small custom BuildTask to automatically upload your plugin upon build.

Resources