I know this question has been asked many times, but I have almost tried everything but got no luck. So please help.
Some global variables:
private string _DirectoryForLogin = "LoginFiles", _FileForLogin = "Login.startup";
private IsolatedStorageFile _GlobalAccessRight = IsolatedStorageFile.GetUserStoreForApplication();
_DirectoryForLogin stores the name of the directory that stores login info and _FileForLogin stores txt file saved as .startup(I do not think this is the problem).
Later after InitializeCompolnent() I am doing this:
using(_GlobalAccessRight){
//Checking if directory exists; case when user had already been logged in.
if (_GlobalAccessRight.DirectoryExists(_DirectoryForLogin))
{
//Check if login startup file is already created.
if (_GlobalAccessRight.FileExists(_DirectoryForLogin + "\\" + _FileForLogin))
{
//Not of much concern for you people.
_UserNameLabel.Text = "Please wait.... Logging in.";
_UserNameHolder.BorderThickness = new Thickness(0);
_UserNameHolder.IsEnabled = false;
_PasswordLabel.Text = "";
_PasswordHolder.BorderThickness = new Thickness(0);
_PasswordHolder.IsEnabled = false;
_LoginButton.BorderThickness = new Thickness(0);
_LoginButton.Content = "";
_LoginButton.IsEnabled = false;
}
else
_GlobalAccessRight.CreateFile(_DirectoryForLogin + "\\" + _FileForLogin);
//This part basically only creates the file, if directory was already existing.
}
else
{
//Creates directory as well as file.
_GlobalAccessRight.CreateDirectory(_DirectoryForLogin);
_GlobalAccessRight.CreateFile(_DirectoryForLogin + "\\" + _FileForLogin);
}
}
Things were working fine till now. Problem is that if I try to delete the directory anywhere after creating directory, it sends me an error: "Operation not permitted on IsolatedStorage." But I resolved it for time being by just closing my emulator all the time so that I get a fresh IsolatedStorage location.
Next I am taking input from the user in the text and password boxes, and writing them on a file above through this code:
using(_GlobalAccessRight){
//I have also tried by giving the FileShare argument below.
using(IsolatedStorageFileStream WritingStreamForLoginInfo = new IsolatedStorageFileStream(_DirectoryForLogin + "\\" + _FileForLogin, FileMode.OpenOrCreate, FileAccess.ReadWrite, _GlobalAccessRight)){
using(StreamWriter WritingLoginInfo = new StreamWriter(WritingStreamForLoginInfo)){
String _LoginCredentials = "UserName: ";
_LoginCredentials += _UserNameHolder.Text;
_LoginCredentials += "\n";
_LoginCredentials = "Password: ";
_LoginCredentials += _PasswordHolder.Password;
//I added this afterwards. Before it was not here. And still it was not working.
WritingLoginInfo.Flush();
WritingLoginInfo.Write(_LoginCredentials.ToCharArray(), 0, _LoginCredentials.Length);
WritingLoginInfo.Close();
WritingStreamForLoginInfo.Close();
}//End of 1st using clause
}//End of second using clause
}//End of third using clause
The above writing code is executed in the function that is executed on a Tap event of a Login button.
The code is sending this error:
Store must be open for this operation.
Exception detail:
System.ObjectDisposedException was unhandled
Message=Store must be open for this operation.
StackTrace:
at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, IsolatedStorageFile isf)
at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
at SafeMessenger.MainPage._LoginButton_Tap(Object sender, GestureEventArgs e)
at MS.Internal.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)
Now one last thing that I should tell you people. Before I was doing like, creating a separate IsolatedStorageFile object for each thing. That is in above code, and in directory creation code. At that time I was getting this error:
"Operation not permitted on IsolatedStorage."
Right now I tried to go through the debug details of various variables and I found this which could be of some help for you people. Remember _GlobalAccessRight is a global private variable of IsolatedStorageFile type.
Quota 'this._GlobalAccessRight.Quota' threw an exception of type 'System.ObjectDisposedException' long {System.ObjectDisposedException}
Kindly help me with this. Thank you for your time and any help, in advance. It would be a great help.
So after reading and thinking a lot I have finally got my code working on my own.
First the errors that operation not permitted were raised because of my bad handling of streams.
First I changed these lines:
.
.
.
}
else
_GlobalAccessRight.CreateFile(_DirectoryForLogin + "\\" + _FileForLogin);
//This part basically only creates the file, if directory was already existing.
}
else
{
//Creates directory as well as file.
_GlobalAccessRight.CreateDirectory(_DirectoryForLogin);
_GlobalAccessRight.CreateFile(_DirectoryForLogin + "\\" + _FileForLogin);
}
To:
.
.
.
}
else
_GlobalAccessRight.CreateFile(_DirectoryForLogin + "\\" + _FileForLogin).Dispose();
//This part basically only creates the file, if directory was already existing.
}
else
{
//Creates directory as well as file.
_GlobalAccessRight.CreateDirectory(_DirectoryForLogin);
_GlobalAccessRight.CreateFile(_DirectoryForLogin + "\\" + _FileForLogin).Dispose();
}
The second mistake was this:
I globally declared the IsolatedStorageFile object. After using it in my First using block:
using(_GlobalAccessRight){
//Checking if directory exists; case when user had already been logged in.
if (_GlobalAccessRight.DirectoryExists(_DirectoryForLogin))
{
.
.
.
.
It got disposed at the end of it.
Therefore when I used it again in the function:
using(_GlobalAccessRight){
//I have also tried by giving the FileShare argument below.
using(IsolatedStorageFileStream WritingStreamForLoginInfo = new IsolatedStorageFileStream(_DirectoryForLogin + "\\" + _FileForLogin, FileMode.OpenOrCreate, FileAccess.ReadWrite, _GlobalAccessRight)){
using(StreamWriter WritingLoginInfo = new StreamWriter(WritingStreamForLoginInfo)){
String _LoginCredentials = "UserName: ";
.
.
.
it threw me error stating:
"Store must be open for that."
So I changed it to be this:
using(_GlobalAccessRight = IsolatedStorageFile.GetUserStoreForApplication()){
using(IsolatedStorageFileStream WritingStreamForLoginInfo = new IsolatedStorageFileStream(_DirectoryForLogin + "\\" + _FileForLogin, FileMode.OpenOrCreate, FileAccess.ReadWrite, _GlobalAccessRight)){
using(StreamWriter WritingLoginInfo = new StreamWriter(WritingStreamForLoginInfo)){
String _LoginCredentials = "UserName: ";
Thats it! Bravo! :)
Try to remove these two lines:
WritingLoginInfo.Close();
WritingStreamForLoginInfo.Close();
using block supposed to open and close/dispose stream automatically. Maybe the error "Store must be open for this operation" caused by the code trying to close already closed connection at the end of using block.
Related
I'm working with C# and adobe acrobat SDK.
When the program throws an error due to the pdf already being compressed I want to move the pdf.
However, C# complains that the file is being used by another process and I know it has to do with the SDK and not another program.
After some debugging I found out that compressPDFOperation.Execute is the culprit.
How can I close it so that I can move the file?
try {
// Initial setup, create credentials instance.
Console.WriteLine(".json: " + Directory.GetCurrentDirectory() + "/pdftools-api-credentials.json");
Credentials credentials = Credentials.ServiceAccountCredentialsBuilder()
.FromFile(Directory.GetCurrentDirectory() + "/pdftools-api-credentials.json")
.Build();
// Create an ExecutionContext using credentials and create a new operation instance.
ExecutionContext executionContext = ExecutionContext.Create(credentials);
CompressPDFOperation compressPDFOperation = CompressPDFOperation.CreateNew();
// Set operation input from a source file.
FileRef sourceFileRef = FileRef.CreateFromLocalFile(directory + #"\" + pdfname);
compressPDFOperation.SetInput(sourceFileRef);
// Execute the operation.
FileRef result = compressPDFOperation.Execute(executionContext);
// Save the result to the specified location.
//if pdf is part of a group, the group directory name will be stored in fileGroupDirectory
string fileGroupDirectory = directory.Replace(sourceDir, "");
result.SaveAs(finishedDir + fileGroupDirectory + pdfname);
}
catch (ServiceApiException ex)
{
Console.WriteLine("Exception encountered while executing operation", ex.Message);
if (ex.Message.Contains("The input file is already compressed"))
{
File.Move(file, finishedDir + fileGroupDirectory + fileName);
}
}
I've found a solution , it's not best practice but I don't know an other way to do it.
I've declared all the variables used to execute the compression (sourceFileRef, compressPdfOperation, ...) before the try catch statement and after result.SaveAs(...) I set those variables to null and run the garbage collection.
compressPDFOperation = null;
result = null;
sourceFileRef = null;
executionContext = null;
credentials = null;
GC.Collect();
On my MVC website, there is a page that archives an old file and writes a new one.
However, when I archive the old file, I get the following error:
System.UnauthorizedAccessException was caught
HResult=-2147024891
Message=Access to the path is denied.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.__Error.WinIOError()
at System.IO.File.InternalMove(String sourceFileName, String destFileName, Boolean checkHost)
at System.IO.File.Move(String sourceFileName, String destFileName)
at Controller.Action in C:\Program\Controllers\MyController.cs:line 201
InnerException:
I've checked the permissions on the account that I'm impersonating, and the account has Modify, Read & execute, List folder contents, Read, and Write permissions on the folder I'm trying to write to.
Maybe I'm missing something about the file permissions? The error is when I'm trying to move the file into the archive on \server123\D$\Archive. I know that when I archive the file at C:\Temp\Archive (my machine), the program works perfectly. I am also able to write a new file without any trouble to \server123\Test. Could the error be because I'm moving from one drive of the server to another? If that is the case... is there a way around it so I can write from \server123\Test to \server123\D$\Archive?
Here is the code I'm using to move the file.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MoveFile(MoveFileViewModel model)
{
string cartonsXml = GetCartonsXml(model);
try
{
//Impersonate user who has access to both folders.
string user = ConfigurationManager.AppSettings["FileUser"].ToString();
string domain = ConfigurationManager.AppSettings["FileDomain"].ToString();
string password = ConfigurationManager.AppSettings["FilePassword"].ToString();
ImpersonateUser impersonateUser = new ImpersonateUser();
IntPtr token = impersonateUser.GetUserToken(user, domain, password);
if (token != IntPtr.Zero)
{
using (WindowsImpersonationContext wic = WindowsIdentity.Impersonate(token))
{
//Move old cartons.xml file to archive.
string oldCartonsFilePath = Path.Combine(#"\\server123\Test", "cartons.xml");
string archiveFilePath = Path.Combine(#"\\server123\D$\Archive", "cartons("
+ DateTime.Now.Month + "-" + DateTime.Now.Day + "-" + DateTime.Now.Year + ")." + Guid.NewGuid().ToString() + ".xml");
System.IO.File.Move(oldCartonsFilePath, archiveFilePath); //This is where I catch the exception!
//Write new cartons.xml file.
string newCartonsFilePath = Path.Combine(#"\\server123\Test", "cartons.xml");
using (StreamWriter sw = new StreamWriter(newCartonsFilePath))
{
sw.WriteLine(cartonsXml);
sw.Close();
}
ViewBag.MsgText = "Complete!";
ViewBag.MsgColor = "Green";
}
}
else
{
ViewBag.MsgText = "Credentials failed! Files not moved!";
ViewBag.MsgColor = "Red";
}
}
catch (Exception ex)
{
ViewBag.MsgText = ex.Message;
ViewBag.MsgColor = "Red";
}
return View(model);
}
Please help! :(
After a variety of trials and errors, I created a share of the folder I'm trying to access, granted the account I'm using read/write permissions to it, and now the code works correctly. I will be updating my code based on the comments I've seen here. Thanks guys!
I have a program that is a launcher for a mod for a game. The launcher works for most of the people who use it, including myself, but for some there is a strange bug that really has me struggling to fix it, and further more driving me absolutely mental!
The basic idea is that my mod files are contained in a folder, the launcher iterates through these files, reads a certain byte of the file and based on the result either moves the file, or moves the file and writes some text to a certain file, then launches the game. Seemingly simple.
The main launch function looks like this:
private void Launch()
{
using (StreamWriter writer = new StreamWriter(userScriptPath, false, Encoding.Unicode))
{
foreach (string file in Directory.GetFiles(modFolderPath + "\\Files\\", "*.pack"))
{
int p = GetPackType(file);
if (p == 3)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
writer.WriteLine("mod \"" + Path.GetFileName(file) + "\";");
}
else if (p == 4)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
}
}
}
Process game = Process.Start(gamePath);
// There is code here that waits for a minute until the game process is actually found, incase its slow starting up
game.WaitForExit();
RestorePacks(); // <- Method to put back the files after finishing
}
The problem some users are getting is that when launching the mod the game launches but it appears as though the launcher doesn't move the files as the game is still in its normal state, it was very hard to ascertain exactly why this was happening as I had no way of debugging it on their computers and the program was working fine for me and all of my test users.
To try and find out what was going on I added a number of checks and some logging to the launcher so that if the launcher didn't work, I'd at least have an idea why. (Note that no errors are thrown for the users even when it doesn't work)
The checks I added included using File.Exists() after attempting to move a file to make sure it was actually moved, the logging kept a note of move attempts and the result of this check to see if the file was actually moved.
I even added a specific if statement to the Process.Start function checking specifically that a certain file was indeed in the required location before launching the game.
Finally before launching all of the files in the folder where the mod files should now be are written to the log.
All of the logs from users who the launcher didn't work for shared one thing in common the program attempted to move the file, threw no error, and then when checking that the file was indeed moved, the file appeared to be there. But when reaching the point where all of the files in the required directory are written to the log, only one of the required 30+ mod files appear to be in the directory.
An example output log looked something like this:
File moving: modfile1.txt
Checking if file is where we tried to move it to: Yes
File moving: modfile2.txt
Checking if file is where we tried to move it to: Yes
File moving: modfile3.txt
Checking if file is where we tried to move it to: Yes
Writing out all files in directory:
normalgamefile1.txt
normalgamefile2.txt
normalgamefile3.txt
modfile1.txt
After seeing this and noticing it was always only a single file that had moved and no others, and also that the program did think the files were where they where supposed to be, the confusion really started to kick in.
This is the method that reads the file to ascertain what type of file it is:
private int GetPackType(string path)
{
FileStream fs = File.OpenRead(path);
BinaryReader reader = new BinaryReader(fs);
reader.ReadChars(4);
int packType = reader.ReadInt32();
fs.Close();
fs.Dispose();
return packType;
}
As you can probably see, and what I've just noticed is that I've failed to close/dispose of reader, and I'm guessing and somewhat hoping this might be the cause of my problem.
(Note I'm now using Using statements in this method but can't test this fix for quite a while)
SO, if you've read this far thank you, my question is..
Firstly do you have any idea what the problem is? Could it be that reader still might have the file open and has not closed and thus the file can't move, IF SO then why does it work perfectly for me and most others, but not for some? Surely a file still being used elsewhere would throw an error?
I've gone through all the simple stuff like making sure the program is run with administrator privileges, etc.
Thank you greatly for any help!
EDIT
As asked in the comments this is the version of the code with my checks and logging added. Simple stuff, which is why I omitted it, the log simply adds to a string, the string is then printed to file when all is done.
private void Launch()
{
using (StreamWriter writer = new StreamWriter(userScriptPath, false, Encoding.Unicode))
{
foreach (string file in Directory.GetFiles(modFolderPath + "\\Files\\", "*.pack"))
{
int p = GetPackType(file);
if (p == 3)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
log += "Move File: " + Path.GetFileName(file) + "\r\n";
writer.WriteLine("mod \"" + Path.GetFileName(file) + "\";");
log += "Write mod line: " + Path.GetFileName(file) + "\r\n";
}
else if (p == 4)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
log += "Move File: " + Path.GetFileName(file) + "\r\n";
}
// Check the file did actually move
if (File.Exists(dataPath + "\\" + Path.GetFileName(file)) == false)
{
MessageBox.Show("The mod could not launch successfully!\n\nError: Packs failed to move", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
log += "File Found\r\n";
}
}
}
if (File.Exists(dataPath + "\\_GreatWar5_DB.pack")) // This pack should always be there if things have worked
{
Process game = Process.Start(gamePath);
}
else
{
MessageBox.Show("The mod could not launch successfully!\n\nError: Data pack missing", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// There is code here waits for a minute until the game process is actually found, incase its slow starting up
game.WaitForExit();
RestorePacks(); // <- Method to put back the files after finishing
}
What I am trying to do is to read in a file to a richTextBox automatically with the OnSelectedIndexChange method. There arent any errors, it just flat out doesnt work. Heres the code that I am working with
public void comboBox1_OnSelectedIndexChanged(object sender, EventArgs e)
{
string selectedPath = comboBox1.SelectedItem.ToString();
if (File.Exists(#"C:\\Mavro\\MavBridge\\" + selectedPath + "\\ " + "Comment" + ".txt"))
{
try
{
Thread.Sleep(0500);
System.IO.StreamReader textFile = new System.IO.StreamReader(#"C:\\Mavro\\MavBridge\\" + selectedPath + "\\ " + "Comment" + ".txt");
richTextBox1.Text = textFile.ReadToEnd();
textFile.Close();
}
catch
{
MessageBox.Show("Error: File cannot be opened!", "Error");
}
}
else
{
MessageBox.Show("No comment was found in this folder", "Alert");
}
}
Just for fun, lets have you try something. First, replace the following line:
if (File.Exists(#"C:\\Mavro\\MavBridge\\" + selectedPath + "\\ " + "Comment" + ".txt"))
with this:
if(File.Exists(string.Format("C:\\Mavro\\MavBridge\\{0}\\Comment.txt", selectedPath)))
It looks like you had an extra space ("\\ " + "Comment"), so I'm sure that's why it never hits this block of code. Also, anytime you have an object that needs to be closed/disposed, more often than not it implements IDisposable, meaning you should encapsulate the object within a using block:
Thread.Sleep(0500);
try
{
using(System.IO.StreamReader textFile = new System.IO.StreamReader(string.Format("C:\\Mavro\\MavBridge\\{0}\\Comment.txt", selectedPath)))
{
richTextBox1.Text = textFile.ReadToEnd();
}
}
catch
{
MessageBox.Show("Error: File cannot be opened!", "Error");
}
However, this can be simplified even further by bypassing the StreamReader entirely and using System.IO.File.ReadAllText instead:
richTextBox1.Text = System.IO.File.ReadAllText(string.Format("C:\\Mavro\\MavBridge\\{0}\\Comment.txt", selectedPath));
Well, one problem comes from the fact that you have:
#"C:\\Mavro\\MavBridge\\" + selectedPath + "\\ " + "Comment" + ".txt"
Since you are using a verbatim string (the # at the beginning), you do not need to put double slashes.
For the rest, make sure your file exists.
Later edit: also I am not sure if you copy/pasted in a rush or something like that, but did you actually put the catch block inside the try ?
1) What is the error you see?
2) Are you positive the file exists?
3) Are you positive the path created by your code is the path you are expecting?
4) Why are you sleeping the thread?
5) Why not just use File.ReadAllText?
6) File.Exists will return false if the code is running with permissions that do not have access to a file, even if the file does exist. Does the user your code is running as, have permissions?
true if the caller has the required permissions and path contains the
name of an existing file; otherwise, false. This method also returns
false if path is null, an invalid path, or a zero-length string. If
the caller does not have sufficient permissions to read the specified
file, no exception is thrown and the method returns false regardless
of the existence of path.
and
The Exists method returns false if any error occurs while trying to
determine if the specified file exists. This can occur in situations
that raise exceptions such as passing a file name with invalid
characters or too many characters, a failing or missing disk, or if
the caller does not have permission to read the file.
Get rid of # before each string. Your directory as it currently is uses actual double slashes instead of C:\Mavro\MavBridge. Use single slashes with \ or go with # at the beginning, but don't use both.
Also, I would strongly suggest using Path.Combine instead of concatenating pieces together like that.
Wondering how to best deal with a problem I am having with xsltransform. Long story short, everything works in my test environment, but it crashes when I run it on the server due to the filenames it tries to deal with, which are output from another program, over which I have no control.
For example. "4Copy (2) of Fed_Around_Six__TFVC020-12.mov.xml" a simple # would solve this, but it's actually running on a service, and this service gets all files of that type in the directory and processes them one by one.
string[] filepaths = Directory.GetFiles(path, Filetype);
I keep the file name variable in:
FileInfo f = new FileInfo(filepaths[i]);
But the method I use for the transform:
myXslTransform = new XslCompiledTransform();
myXslTransform.Transform(filename,OutputFileName);
Only accepts (String, String) and thus when it sees "4Copy (2) of Fed_Around_Six__TFVC020-12.mov.xml" it has a heart attack and cuts it off.
I was thinking save the original name, rename, remove whitespace, transform, and rename back. But I think there is a smarter way to handle it out there, just not sure where to look. Is there a way of telling C# to handle a variable as a literal? Or a different transform method that accepts these weird filenames with very bad naming conventions?
Any insight that helps would be great!
The error & exception message I recieve from the Eventvwr is
Cannot Translate
\\9g031\Export\4Copy (2) of Fed_Around_Six__TFVC020-12.mov.xml
OutputName = \\9g031\Export\done\4Copy (2) of Fed_Around_Six__TFVC020-12.mov.xml
XSL LOC = C:\CXS.xsl
System.IO.IOException: The specified path is invalid.
private void PreformTranslation(FileInfo FileName, String OutputFileName , String result)
{
try
{
XslCompiledTransform myXslTransform;
myXslTransform = new XslCompiledTransform();
myXslTransform.Load(XSLname);
EventLog.WriteEntry(FileName.ToString(), OutputFileName);
myXslTransform.Transform(FileName.Name,OutputFileName);
EventLog.WriteEntry("TranslationComplete");
if (File.Exists(path + result))
{
MoveVideoFiles(path + result, outputPath + result);
}
// Rename(OutputFileName, FileName, Out);
}
catch (Exception e)
{
EventLog.WriteEntry("Cannot Translate " + FileName + " OutputName = " + OutputFileName + " \r\n"+
"XSL LOC = " + XSLname + "\r\n" + e);
}
}
The default directory when running a service is something like "windows/system32" and this isn't the directory of the executable.
This is probably the reason the XML file isn't found.