Copy a file in a new folder - c#

I have a problem coping a file. I need to copy a .db file and put it in a new folder (called "directory",selected previously with FolderPicker).
The code that i have is: (this is for a store app for Windows 8.1)
try{
StorageFile newDB = await StorageFile.GetFileFromPathAsync(directory);
StorageFile originalDB = await StorageFile.GetFileFromPathAsync(Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "AFBIT.db"));
await newDB.CopyAndReplaceAsync(originalDB);
}
catch(Exception ex){
}
I have a exception in neDB, and said "Value does not fall within the expected range."
I dont know another way to copy a file in xaml, if u know what is the problem or another way to do this i llbe very grateful.

I have something similar that I currently use when copying a file CopyFileAsync method I have created see if this can help you in regards to refactoring your code to a working model
public static async Task CopyFileAsync(string sourcePath, string destinationPath)
{
try
{
using (Stream source = File.Open(sourcePath, FileMode.Open))
{
using (Stream destination = File.Create(destinationPath))
{
await source.CopyToAsync(destination);
}
}
}
catch (IOException io)
{
HttpContext.Current.Response.Write(io.Message); //I use this within a web app change to work for your windows app
}
}

I'm not sure what your truly inquiring but I believe your attempting is:
public static bool CopyFile(string source, string destination)
{
if(!File.Exist(source))
return false;
if(string.IsNullOrEmpty(destination))
return false;
try
{
using(var reader = File.Open(source))
using(var writer = File.Create(destination))
reader.CopyTo(writer);
return true;
}
catch(IOException ex) { return false; }
}
Bare in mind this will eat your exception, then return false if it fails at any point for any reason.
That would essentially copy the file, I noticed that your trying to read your local application folder. Be careful, as it often requires Administrator Privileges when it resides in several locations within the Operating System.

Related

StreamWriter data getting lost on a reboot

I am using StreamWriter to write a file in a sessionchange like logon and logoff.
But if a reboot happens just about the time when we write/close the file, we are getting an empty file and some time data already in it is getting deleted
This is my code
public void ToJson(T objectToWrite)
{
InformFileLogger.Instance.Debug(">>> start >>>");
try
{
string json = null;
string directory = Path.GetDirectoryName(this.serializeFilePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
if (File.Exists(this.serializeFilePath))
{
if (new FileInfo(this.serializeFilePath).Length == 0)
{
File.Delete(this.serializeFilePath);
}
}
json = JsonConvert.SerializeObject(objectToWrite);
if (json != null)
{
using (StreamWriter streamWriter = new StreamWriter(this.serializeFilePath))
{
streamWriter.WriteLine(json);
streamWriter.Close();
}
}
}
catch (Exception ex)
{
InformEventLogger.Error(ex.ToString());
InformFileLogger.Instance.Error(InformHelper.ExceptionMessageFormat(ex));
}
InformFileLogger.Instance.Debug("<<< end <<<");
}
How can I avoid writing null entries in the files/ getting the data deleted?
This really depends on how the reboot is triggered.
Unless the reboot is triggered by your code, you won't be able to make sure your code can do anything before a reboot - including completing a StreamWriter function.

Opening a document from Imanage in Word 2016

I am attempting to open an Imanage document, in MS Word, within a temporary test application (for debugging) to later copy over into an ActiveX control project. The error that is popping up is:
Exception thrown at 0x7618851A (msvcrt.dll) in w3wp.exe: 0xC0000005: Access >violation reading location 0x09801000.
If there is a handler for this exception, the program may be safely continued.
The error occurs when running the cmd.Execute line and I am unsure as to why I am getting the error.
using IManage;
using IMANEXTLib;
using System;
namespace WebApplication3
{
public partial class WebForm2 : System.Web.UI.Page
{
IManDatabase imanagedatabase;
IManDMS myDMS = new ManDMSClass();
protected void Page_Load(object sender, EventArgs e)
{
openImanageDoc("docNumber", "versionNumber", "server", "database", ReadOnly);
}
public void imanageLogin(string server, string database)
{
try
{
IManSession session = myDMS.Sessions.Add(server);
IManWorkArea oWorkArea = session.WorkArea;
session.TrustedLogin();
foreach (IManDatabase dbase in session.Databases)
{
if (dbase.Name == database)
{
imanagedatabase = dbase;
}
}
}
catch (Exception ex)
{
throw ex;
}
}
public void openImanageDoc(string docNo, string versionNo, string server, string database, bool isReadOnly = true)
{
IManDocument doc;
try
{
imanageLogin(server, database);
int iDocNo = int.Parse(docNo);
int iVersion = int.Parse(versionNo);
doc = imanagedatabase.GetDocument(iDocNo, iVersion);
openNRTDocument(ref doc, isReadOnly);
imanagedatabase.Session.Logout();
myDMS.Close();
}
catch (Exception Ex)
{
imanagedatabase.Session.Logout();
throw Ex;
}
finally
{
imanagedatabase = null;
myDMS = null;
}
}
public void openNRTDocument(ref IManDocument nrtDocument, Boolean isReadonly)
{
OpenCmd cmd = new OpenCmd();
ContextItems objContextItems = new ContextItems();
objContextItems.Add("NRTDMS", myDMS);
objContextItems.Add("SelectedNRTDocuments", new[] { (NRTDocument)nrtDocument.LatestVersion });
objContextItems.Add("IManExt.OpenCmd.Integration", false);
objContextItems.Add("IManExt.OpenCmd.NoCmdUI", true);
cmd.Initialize(objContextItems);
cmd.Update();
cmd.Execute();
}
}
}
Due to the nature of the error, I am presuming it is a configuration issue rather than a code error although I could be completely wrong as I am very new to programming.
I have found out that w3wp.exe is an IIS worker process created by the app pool but other than that I have no idea what the numeric code represents. Any help or advice is greatly appreciated.
The error is being raised by the OpenCmd instance because it is most likely trying to access resources such as local registry settings. It's not possible to do that in a web application, unless you host your code in a proprietary technology like ActiveX (which is specific to Internet Explorer)
Actually, it is not appropriate for you to use OpenCmd here. Those type of commands (iManage "ICommand" implementations) are intended to be used in regular Windows applications that have either the iManage FileSite or DeskSite client installed. These commands are all part of the so-called Extensibility COM libraries (iManExt.dll, iManExt2.dll, etc) and should not be used in web applications, or at least used with caution as they may inappropriately attempt to access the registry, as you've discovered, or perhaps even display input Win32 dialogs.
For a web app you should instead just limit yourself to the low-level iManage COM library (IManage.dll). This is in fact what iManage themselves do with their own WorkSite Web application
Probably what you should do is replace your openNRTDocument method with something like this:
// create a temporary file on your web server..
var filePath = Path.GetTempFileName();
// fetch a copy of the iManage document and save to the temporary file location
doc.GetCopy(filePath, imGetCopyOptions.imNativeFormat);
In an MVC web application you would then just return a FileContentResult, something like this:
// read entire document as a byte array
var docContent = File.ReadAllBytes(filePath);
// delete temporary copy of file
File.Delete(filePath);
// return byte stream to web client
return File(stream, MediaTypeNames.Application.Octet, fileName);
In a Web Forms application you could do something like this:
// set content disposition as appropriate - here example is for Word DOCX files
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
// write file to HTTP content output stream
Response.WriteFile(filePath);
Response.End();

UWP Check If File Exists

I am currently working on a Windows 10 UWP App.
The App needs to Check if a certain PDF File exists called "01-introduction", and if so open it.
I already have the code for if the file does not exist.
The Code Below is what i currently have:
try
{
var test = await DownloadsFolder.CreateFileAsync("01-Introduction.pdf", CreationCollisionOption.FailIfExists);
}
catch
{
}
This code Does not work correctly because to check if the file exists here, I attempt to create the file. However if the file does not already exist an empty file will be created. I do not want to create anything if the file does not exist, just open the PDF if it does.
If possible, i would like to look inside a folder which is in the downloads folder called "My Manuals".
Any help would be greatly appreciated.
public async Task<bool> IsFilePresent(string fileName)
{
var item = await ApplicationData.Current.LocalFolder.TryGetItemAsync(fileName);
return item != null;
}
But not support Win8/WP8.1
https://blogs.msdn.microsoft.com/shashankyerramilli/2014/02/17/check-if-a-file-exists-in-windows-phone-8-and-winrt-without-exception/
There are two methods
1) You can use StorageFolder.GetFileAsync() as this is also supported by Windows 8.1 and WP 8.1 devices.
try
{
StorageFile file = await DownloadsFolder.GetFileAsync("01-Introduction.pdf");
}
catch
{
Debug.WriteLine("File does not exits");
}
2) Or you can use FileInfo.Exists only supported for windows 10 UWP.
FileInfo fInfo = new FileInfo("01-Introduction.pdf");
if (!fInfo.Exists)
{
Debug.WriteLine("File does not exits");
}
System.IO.File.Exists is UWP way too. I test now in Windows IOT. it just works.
This helped me in my case:
ApplicationData.Current.LocalFolder.GetFileAsync(path).AsTask().ContinueWith(item => {
if (item.IsFaulted)
return; // file not found
else { /* process file here */ }
});
This worked for me running my UWP C# app on Windows 10...
StorageFolder app_StorageFolder = await StorageFolder.GetFolderFromPathAsync( #App.STORAGE_FOLDER_PATH );
var item = await app_StorageFolder.TryGetItemAsync(relative_file_pathname);
return item != null;
public override bool Exists(string filePath)
{
try
{
string path = Path.GetDirectoryName(filePath);
var fileName = Path.GetFileName(filePath);
StorageFolder accessFolder = StorageFolder.GetFolderFromPathAsync(path).AsTask().GetAwaiter().GetResult();
StorageFile file = accessFolder.GetFileAsync(fileName).AsTask().GetAwaiter().GetResult();
return file != null;
}
catch
{
return false;
}
}
You can use System.IO.File.
Example:
// If file located in local folder. You can do the same for other locations.
string rootPath = ApplicationData.Current.LocalFolder.Path;
string filePath = Path.Combine(rootPath, "fileName.pdf");
if (System.IO.File.Exists(filePath))
{
// File exists
}
else
{
// File doesn't exist
}
I'm doing a Win10 IoT Core UWP app and I have to check the file length instead of "Exists" because CreateFileAsync() already creates an empty file stub immediately. But I need that call before to determine the whole path the file will be located at.
So it's:
var destinationFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("MyFile.wow", ...);
if (new FileInfo(destinationFile.Path).Length > 0)
return destinationFile.Path;
In this way System.IO.File.Exists(filePath) I cannot test DocumentLibrary
because KnownFolders.DocumentsLibrary.Path return empty string
Next solution is very slow await DownloadsFolder.GetFileAsync("01-Introduction.pdf")
IMHO the best way is collect all files from folder and check the file name exist.
List<StorageFile> storageFileList = new List<StorageFile>();
storageFileList.AddRange(await KnownFolders.DocumentsLibrary.GetFilesAsync(CommonFileQuery.OrderByName));
bool fileExist = storageFileList.Any(x => x.Name == "01-Introduction.pdf");
CreateFileSync exposes an overload that let's you choose what to do if an existing file with the same name has been found in the directory, as such:
StorageFile localDbFile = await DownloadsFolder.CreateFileAsync(LocalDbName, CreationCollisionOption.OpenIfExists);
CreationCollisionOption is the object that you need to set up. In my example i'm opening the file instead of creating a new one.
Based on another answer here, I like
public static async Task<bool> DoesFileExist(string filePath) {
var directoryPath = System.IO.Path.GetDirectoryName(filePath);
var fileName = System.IO.Path.GetFileName(filePath);
var folder = await StorageFolder.GetFolderFromPathAsync(directoryPath);
var file = await folder.TryGetItemAsync(fileName);
return file != null;
}
You can use the FileInfo class in this case. It has a method called FileInfo.Exists() which returns a bool result
https://msdn.microsoft.com/en-us/library/system.io.fileinfo.exists(v=vs.110).aspx
EDIT:
If you want to check for the files existence, you will need to create a StorageFile object and call one of the GetFile.... methods. Such as:
StorageFile file = new StorageFile();
file.GetFileFromPathAsync("Insert path")
if(file == null)
{
/// File doesn't exist
}
I had a quick look to find the download folder path but no joy, but the GetFile method should give you the answer your looking for
On Window 10, for me, this is the most "elegant" way:
private static bool IsFileExistent(StorageFile file)
{
return File.Exists(Path.Combine(file.Path));
}
Or, as an extension if you prefer and will use it widely:
static class Extensions
{
public static bool Exists(this StorageFile file)
{
return File.Exists(Path.Combine(file.Path));
}
}

C# Windows Store App - File IO using async/await causes timeouts and InvalidOperationException

this is my first post on this site and I searched high and wide to get my code to work.
Like the title says, it's a WinRT App and I'm having difficulty with File IO. What I want to do is read in a text file stored in a folder that is inside the application installation directory and that contains lines of data that I'll feed into an List<>.
public static async void GetStations()
{
try
{
using (var stream = await Windows.Storage.ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(#"MyApp\Data\file.txt"))
{
using (var streamReader = new StreamReader(stream))
{
while (streamReader.Peek() >= 0)
{
string line = await streamReader.ReadLineAsync();
//do something with
}
}
}
}
catch (Exception e)
{
...
}
finally
{
...
}
}
the problem is I am getting file not found errors when trying to run it. Can anyone help? If you require that I post more information, I can...
Thanks in advance.
If you are distributing your file as a part of your application package then Package.Current.InstalledLocation is the right location. ApplicationData.Current.LocalFolder contains only files that have been put there by your application.
The correct code would be:
public static async void GetStations()
{
try
{
using (var stream = await Windows.ApplicationModel.Package.Current.InstalledLocation.OpenStreamForReadAsync(#"Data\file.txt"))
{
using (var streamReader = new StreamReader(stream))
{
while (streamReader.Peek() >= 0)
{
string line = await streamReader.ReadLineAsync();
//do something with
}
}
}
}
catch (Exception e)
{
//...
}
finally
{
//...
}
}
The file must be included in you project inside Data folder and have Build Action set to Content.
Instead of opening from ApplicationData, you probably need:
Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync
This will get the file in the package's installation folder, instead of the Application's Data folder.

C# Linq for files user has read access to

How would I use Linq on list.Items = directoryInfo.GetFiles("\\server\share\folder\"); to include only the files the user has read access to?
...
So far only suggestions are using try/catches, or APIs that are obsolete in .NET 4.0? I'd prefer something to read the ACL's and see if the specific user or a group the user is a member of has been granted read access. I'm trying to do this for simplified management of granting reports to users on a website that won't be high traffic, so the logic that "who knows if you can actually read it when you try to open the file" doesn't pertain to this case. I sense that Microsoft should really make this task easier.
You run the risk of a race condition if you check for read permission prior to opening the file.
If you're attempting to read all of the files you have access to in a folder, better to just try opening each one and catch the UnauthorizedAccessException.
See:
how can you easily check if access is denied for a file in .NET?
How do you check for permissions to write to a directory or file?
just try this out .should work .haven't tested though
var fw = from f in new DirectoryInfo("C:\\Users\\User\\Downloads\\").GetFiles()
where SecurityManager.IsGranted(new FileIOPermission
(FileIOPermissionAccess.Write, f.FullName))
select f;
EDIT if it is just read only files then try this
var fe = from f in new DirectoryInfo("C:\\Users\\ashley\\Downloads\\").GetFiles()
where f.IsReadOnly==true
select f
Note: I haven't tested it, but in theory it should work
First, define a predicate to determine read access
bool CanRead(FileInfo file)
{
try {
file.GetAccessControl();
//Read and write access;
return true;
}
catch (UnauthorizedAccessException uae)
{
if (uae.Message.Contains("read-only"))
{
//read-only access
return true;
}
return false;
}
}
Then, it should be a simple case of using a where clause in a linq query
from file in directoryInfo.GetFiles("\\server\share\folder\")
where HaveAccess(f) == true
select f;
Tested and working, but will return false if the file is in use
void Main()
{
var directoryInfo = new DirectoryInfo(#"C:\");
var currentUser = WindowsIdentity.GetCurrent();
var files = directoryInfo.GetFiles(".").Where(f => CanRead(currentUser, f.FullName));
}
private bool CanRead(WindowsIdentity user, string filePath)
{
if(!File.Exists(filePath))
return false;
try
{
var fileSecurity = File.GetAccessControl(filePath, AccessControlSections.Access);
foreach(FileSystemAccessRule fsRule in fileSecurity.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier)))
{
foreach(var usrGroup in user.Groups)
{
if(fsRule.IdentityReference.Value == usrGroup.Value)
return true;
}
}
} catch (InvalidOperationException) {
//File is in use
return false;
}
return false;
}

Categories