I would like to get the file owner information but are having some trouble with this line:
const string fileOwner = Delimon.Win32.IO.File.GetAccessControl(fi.Name).GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();
Specifically, it doesn't like fi.name. My error is
An object reference is required for the non-static field, method, or property 'Delimon.Win32.IO.File.GetAccessControl(string)'
Here is the larger chuck of code where it sits:
// check if file exists. if so dont overwrite...
if(Delimon.Win32.IO.File.Exists(targetPath+fi.Name)) {
// Console.WriteLine(fileName + " already exists, nothing written");
}
else {
// Console.WriteLine(fileName + " is new so written to dir");
string fileOwner=Delimon.Win32.IO.File.GetAccessControl(fi.Name).GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();
Delimon.Win32.IO.File.Copy(fileName, destFile, true);
// convert extension to number
switch(fileExt) {
case ".doc":
fileType=1;
break;
case ".xls":
fileType=2;
break;
case ".mdb":
fileType=3;
break;
default:
fileType=1;
break;
}
// I want tot use fileOwner here in an SQL statement
}
Please note fi.Name holds the file name only. I also have a variable called fileName which holds the full absolute path including the file name. This gives me the same issue.
The method File.GetAccessControl() is 'implemented' as an instance methods and not a static method (not like the one on MSDN)
Try to create a file of type Delimon.Win32.IO.File then call the methode using the created instance:
Delimon.Win32.IO.File file = new Delimon.Win32.IO.File(...); // Check constructor
FileSecurity fs = myFile.GetAccessControl();
You may want to check the documentation regards the Delimon.Win32.IO.File.Exists method which could be an instance methode either.
From the error, it sounds like fi.Name is unable to be found because fi is null when calling GetAccessControl. Take a look at it in the debugger.
Sorry for a couple of answers I placed in the wrong spot. Am new to this site (and c#/.net if you cant tell) I believe I have found a solution here Getting / setting file owner in C# Based on that this is how I have it working:
using System.Security.AccessControl;
using System.Security.Principal;
var fs = System.IO.File.GetAccessControl(fileName);
var sid = fs.GetOwner(typeof(SecurityIdentifier));
Console.WriteLine(sid);
var ntAccount = sid.Translate(typeof(NTAccount));
Console.WriteLine(ntAccount);
so ntAccount is may variable which I will use in the SQL for the document owners name. Thanks for every ones time helping me here. This solution does seem to be working. Quick question since im new here. Should I have posted this as a reply and should I accept it?
Related
using (var openFileDialog1 = new OpenFileDialog())
{
openFileDialog1.Reset();
if (!string.IsNullOrEmpty(ExcelFilePath))
{
string fileName = Path.GetFileName(ExcelFilePath);
string fileExt = Path.GetExtension(ExcelFilePath);
//Avoid "you can't open this location using this program file" dialog
//if there is a file name in the path strip it )
if (!string.IsNullOrEmpty(fileName))
initialDirectory = Path.GetDirectoryName(ExcelFilePath);
//if not let it be
else
initialDirectory = ExcelFilePath;
openFileDialog1.InitialDirectory = initialDirectory;
}
else
openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = "Excel files (*.xls or *.xlsx)|*.xls;*.xlsx";
//openFileDialog1.Filter = "xls files (*.xls)|*.xls|xlsx files(*.xlsx)|.xlsx";
openFileDialog1.FilterIndex = 2;
openFileDialog1.RestoreDirectory = false;
openFileDialog1.CheckFileExists = true;
openFileDialog1.CheckPathExists = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
var browseSelectionMade = BrowseSelectionMade;
if (browseSelectionMade!=null)
browseSelectionMade(this, new DataEventArgs<string>(openFileDialog1.FileName));
}
}
Regardless of whether or not I set RestoreDirectory to true, I will always browse to the LAST used directory if my initial directory is set to a path that doesn't exist. Where is the last used directory saved by OpenFileDialog? And is there a way to override this behavior? (e.g. I always want to set it to C:\ if the initial directory doesn't exist?)
It seems like all you need to do is the following:
string path; // this is the path that you are checking.
if(Directory.Exists(path)) {
openFileDialog1.InitialDirectory = path;
} else {
openFileDialog1.InitialDirectory = #"C:\";
}
That is unless I'm missing something.
Where is the last used directory saved?
It is stored in the registry. The exact location depends on the Windows version, for Win7 it is HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32. A quick look with regedit ought to convince you that you don't want to mess with that.
The simple workaround is to provide a valid path. If the one you calculate isn't valid, Directory.Exists returns false, then provide a valid one. Like the Documents folder returned by Environment.GetFolderPath(). Then again, nothing wrong with the last used one either, the user will easily recognize it with good odds that it happens to be close to the desired one.
I don't think there is anything built in for that. Just check before you open the dialog:
if (!Directory.Exists(initialDirectory))
{
openFileDialog1.InitialDirectory = #"C:\";
}
Check to see if the ExcelFilePath exists, you check to see if it's null or empty, however if before your block you check to see if the directory exists, and if it doesn't reset the value to an empty string you should be golden.
(yes you'll need to apply your file name logic etc earlier) however once you've parsed all of that out, it's trivial to determine if the directory exits
if (!Directory.Exists(excelPath))
{
ExcelFilePath = String.Empty;
}
Also, to set the default extension you should set FilterIndex property instead of DefaultExt. see: https://stackoverflow.com/a/6104319/381082
Here's a good article on the OpenFileDialog in C#: http://www.c-sharpcorner.com/uploadfile/mahesh/openfiledialog-in-C-Sharp/
For future me
remember to do:
try
{
result = dialog.ShowDialog(Window);
}
catch
{
dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
result = dialog.ShowDialog(Window);
}
This helps in the situation when user opened file from location, that does not longer exists (ex. USB stick, mapped network drive) - ShowDialog throws exception if InitialDirectory is invalid.
Edit: After consulting with a more knowledgeable friend, perhaps the better solution is, in hindsight, obvious. Just store your own registry key in HKEY_CURRENT_USER\SOFTWARE\YourCompanyOrAppName\Whatevs or something similar (not sure on best practices, or which folders you have read/write access to, do your own research in that) and avoid this problem altogether. By simply letting the user navigate to where they want once, and then storing the path in the registry (as a normal string, and not a PIDL) and retrieving that path the next time. For reference, see the MSDN articles on the Registry and RegistryKey classes, and their example in the RegistryKey/Methods/SetValue article. Still, I'll leave this post as is, as a point of curiosity, or if someone has a very specific problem and needs this solution. As always, good luck!
For any poor soul wandering through here in the future, it seems I figured out how to find the last used directory. Just like stated previously, it's stored in the registry, more specifically in HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU\
Here is a set of folders for each file extension, including a "*" for unknown file extensions. I'll do this for txt files, change the path as needed. To access this path we make a RegistryKey and call OpenSubKey (BTW, full code below)
string RegistryPath = #"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSavePidlMRU\\txt";
RegistryKey rk = Registry.CurrentUser.OpenSubKey(RegistryPath);
In here is a set of entries which all contain PIDLs (we'll get to that) of the last opened or saved items.
DO NOTE: the folder name OpenSavePidlMRU, i've seen called just OpenSaveMRU, and seems to be for versions older than win 10.
Also in here is an entry called "MRUListEx", MRU stands for "Most Recently Used". In this entry is an index of which item was... well, most recently used. So if I have 10 entries, named 0 to 9, and 9 was the last used, the first byte in MRUListEx will be 0x09. So for:
byte[] mrulistex = (byte[])rk.GetValue("MRUListEx");
byte Last = mrulistex[0];
Last will equal 0x09 (on my system)
Then we call GetValue again but for that entry
byte[] LastPathByteArray = (byte[])rk.GetValue(Last.ToString());
And here's where things get problematic, as this won't return a byte array where each byte is a character in our filepath, it returns what's known as a PIDL. While the byte array will seem to contain the path, in both char and wide char, it also contains a bunch of gibberish that can't be easily converted.
I won't pretend to understand it, but https://stackoverflow.com/a/4318663 provides a way to convert this to a string. (see code below)
string LastPath = GetPathFromPIDL(LastPathByteArray);
And we're done. PLEASE NOTE this doesn't necessarily represent a good solution, but I wasn't able to find much official documentation on this in my half hour of digging. And obviously this code doesn't check if the registry path is correct, if the registry keys exist, or do much error checking at all, but this does at least work.
using Microsoft.Win32; //for the registry class
using System.Runtime.InteropServices; //for converting the PIDL
//GetPathFromPIDL from matt.schechtman at https://stackoverflow.com/a/4318663
[DllImport("shell32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SHGetPathFromIDListW(IntPtr pidl, MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszPath);
private string GetPathFromPIDL(byte[] byteCode)
{
//MAX_PATH = 260
StringBuilder builder = new StringBuilder(260);
IntPtr ptr = IntPtr.Zero;
GCHandle h0 = GCHandle.Alloc(byteCode, GCHandleType.Pinned);
try
{
ptr = h0.AddrOfPinnedObject();
}
finally
{
h0.Free();
}
SHGetPathFromIDListW(ptr, builder);
return builder.ToString();
}
public void OnClick_Button_OpenFile(object sender, RoutedEventArgs e)
{
string RegistryPath = #"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSavePidlMRU\\txt";
RegistryKey rk = Registry.CurrentUser.OpenSubKey(RegistryPath);
byte[] mrulistex = (byte[])rk.GetValue("MRUListEx");
byte Last = mrulistex[0];
byte[] LastPathByteArray = (byte[])rk.GetValue(Last.ToString());
string LastPath = GetPathFromPIDL(LastPathByteArray);
// Configure open file dialog box
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();`
dlg.InitialDirectory = LastPath;
result = dlg.ShowDialog();
if (result == true)
{
string filename = dlg.FileName;
}
//etc etc, rest of your code
}
Good luck.
In case you're using file name stored in some string, it's better to use Path to cut the file name (on my W10 the open dialog doesn't open in initial directory, if I supply just file name):
if (!System.IO.Directory.Exists(filename))
{
openDlg.InitialDirectory =
System.IO.Path.GetDirectoryName(filename);
}
string profile = "\\" + txtProfileLoad.Text + ".txt";
profile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + profile;
The variable profile is receiving the correct file path, but when I run it the File.Exists comes up false every time.
if (System.IO.File.Exists(profile) == true)
{
System.IO.StreamReader profileReader;
profileReader = new System.IO.StreamReader(profile);
do
{
profileLevel = profileLevel + profileReader.ReadLine() + "\r\n";
} while (profileReader.Peek() != -1);
loadName(profileLevel);
wordBeingUsed.finalWord = loadedName;
Close();
}
else
{
MessageBox.Show("Invalid file name. Please try again.");
}
There aren't any permissions stopping it from seeing the file.
Any help with this would be appreciated. It's been driving me crazy.
Is this a pre-existing file that you are trying to read? Or is this a new file that you are hoping to create? What is the value inside txtProfileLoad.Text, issue most likely is within this property.
Run a sanity check:
var profile = "mytestfile.txt";
var myFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), profile);
File.WriteAllText(myFile, "Testing file write");
if (File.Exists(myFile))
{
// Access works.
}
else
{
//Didn't work
}
If above code works, then it is most likely that the name you create from txtProfileLoad.Text is different from actual file on the drive. On the other hand, if this is a file that doesn't exist yet; then of course it would return false when you check Exists.
You can use a string variable and pass the file name to it:
string tempFile = txtProfileLoad.Text;
string profile = #"C:\temp\tempfile.txt";
Also check out if you could use the file open method instead of File.Exist.
As per MSDN:
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 Nothing, 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.
Have you tried running as an administrator? Try do "right click" on the Visual Studio icon and select "Run as Administrator", and see if you still encounter the same behaviour.
I stored a file path in database table like this ../Document/5292013/cal.png. Now I want to check whether or not the file exists in the server folder. I am using the below code to check this, but it's not working for me.
if (File.Exists(Server.MapPath(root.GetElementsByTagName("FLD_DOC_ID")[0].InnerText)))
{
proof.HRef = Server.MapPath(root.GetElementsByTagName("FLD_DOC_ID")[0].InnerText);
}
Now I check using watch File.Exists(Server.MapPath("Document")) //Returns false, but server having the same folder.
Please help me to solve this.
You need to transform the file name to a virtual form before using MapPath. You must know the specifics of how it needs to be done. For example:
string fileName = root.GetElementsByTagName("FLD_DOC_ID")[0].InnerText;
fileName = fileName.Replace("..", "~");
if (File.Exists(Server.MapPath(fileName))
{
// you probably do not want MapPath here:
//proof.HRef = Server.MapPath(root.GetElementsByTagName("FLD_DOC_ID")[0].InnerText);
proof.HRef = System.Web.VirtualPathUtility.ToAbsolute(fileName);
}
Try to print out Server.MapPath(root.GetElementsByTagName("FLD_DOC_ID")[0].InnerText)
it might be pointing a wrong path or something
Any way, checking a file if it exists or not is very trivial:
if(File.Exists(the file path))
{
}
First you have to get filepath (filename) from database using select query then use that path with file.exists.
Example:
First get filename or filepath from database then,
if you get only filename then use below code:
if(File.Exits(Server.MapPath("Document/5292013/"+filename)))
{
}
or
if you get only filepath then use below code:
if(File.Exits(Server.MapPath("filename")))
{
}
Thanks
I am trying to create 2 XML files in the same folder.
For some reason it does create the first one, but does not create the second one.
Could it be that the first one is still being created when an attempt to create the second file is made, and therefore the latter fails?
I don't get any errors with the code:
if (File.Exists(FileNameTextBox.Text + ".AA.xml"))
{
MessageBox.Show("Already exists. renaming to *.old" + Environment.NewLine +
"if there is already an *.old file, this will be deleted.");
if (File.Exists(FileNameTextBox.Text + ".AA.xml.old"))
{
File.Delete(FileNameTextBox.Text + ".AA.xml.old");
}
File.Move(FileNameTextBox.Text + ".AA.xml", FileNameTextBox.Text + ".AA.xml.old");
}
if (!File.Exists(FileNameTextBox.Text + ".AA.xml"))
{
XmlTextWriter textWritter = new XmlTextWriter(FileNameTextBox.Text + ".AA.xml", null);
textWritter.WriteStartDocument();
textWritter.WriteStartElement("Data");
textWritter.WriteEndElement();
textWritter.Close();
}
if (File.Exists("BB.xml"))
{
if (File.Exists("BB.xml.old"))
{
File.Delete("BB.xml.old");
}
File.Move("BB.xml", "BB.xml.old");
}
if (!File.Exists("BB.xml"))
{
XmlTextWriter textWritterPC3 = new XmlTextWriter("BB.xml", null);
textWritterPC3.WriteStartDocument();
textWritterPC3.WriteStartElement("Data");
textWritterPC3.WriteEndElement();
textWritterPC3.Close();
}
Whats in FileNameTextBox.Text? Does it specify a directory path?
Your second file is created without saying which directory. So it will be created in the current directory - which is not necessarily the directory specified by FileNameTextBox.Text
You are not specifying an absolute path for your file names, so you are using whatever the current directory happens to be, which is not reliable. Also you may need to call DirectoryInfo.Refresh() or FileInfo.Refresh() to make sure you are seeing the latest directory information (whether the file exists or not).
The comment is only making the last if case execute the first row.. The last if should look like this. I don't know if it's only in your example.
Your example
if (!File.Exists("BB.xml")) // {
XmlTextWriter textWritterPC3 = new XmlTextWriter("BB.xml", null);
should be
if (!File.Exists("BB.xml")) //
{
XmlTextWriter textWritterPC3 = new XmlTextWriter("BB.xml", null);
textWritterPC3.WriteStartDocument();
textWritterPC3.WriteStartElement("Data");
textWritterPC3.WriteEndElement();
textWritterPC3.Close();
}
I have written a code to move a file as follows
private void Move_Click(object sender, EventArgs e)
{
string strOrgpath = string.Empty, strNewpath = string.Empty;
strOrgpath = tvwACH.SelectedNode.ToString();
string strPath = strOrgpath.Substring(10);
FolderBrowserDialog folderborwser1 = new FolderBrowserDialog();
if (folderborwser1.ShowDialog() == DialogResult.OK)
{
try
{
strNewpath = folderborwser1.SelectedPath;
File.Move(strPath, strNewpath);
}
catch (Exception ex)
{
}
}
}
But i am getting the exception as i mentioned can any one tell why and some times i am getting the error as access to the path is denied
Make sure your substring call returns the correct result. If possible, use static methods from the Path class instead. Take a look at the MSDN page for File.Move and pay attention to what parameters are expected -- you should provide two valid full file names (e.g. C:\Blah\myFile.txt).
"Access denied" error message might happen if the user picks a folder they don't have write access to in the folder browser dialog. That's a scenario you'll have to handle in your code, perhaps by catching the UnauthorizedAccessException.
Update: the destination file should also point to a filename. So you'll need to do something like this:
var origFileName = Path.GetFileName(strPath);
strNewpath = Path.Combine(folderborwser1.SelectedPath, origFileName);
File.Move(strPath, strNewpath);
Without seeing the values that are being used in your application at run-time, I'm guessing tvwACH.SelecteNode.ToString() or strOrgpath.Substring(10) is not a valid File System path.
You should Debug your application and set a breakpoint to see what those values are (and post them if it's not obvious what your problem is at that point).