Finding the user who modified the shared drive folder files - c#

I have a shared drive which is elsewhere on a server. I want to get a notification which gives me the user name of the person who has modified any file present in the shared drive.
Currently I am using the FileSystemWatcher to get the notification and the code provided by Stack overflow question "Find out username(who) modified file in C#" to find the user name.
But Instead I get the name of the computer on which the shared drive is at the moment. I want the username who had modified the file on the shared drive.
My piece of code is :
private string GetSpecificFileProperties(string file, params int[] indexes)
{
string fileName = Path.GetFileName(file);
string folderName = Path.GetDirectoryName(file);
Shell32.Shell shell = new Shell32.Shell();
Shell32.Folder objFolder;
objFolder = shell.NameSpace(folderName);
StringBuilder sb = new StringBuilder();
foreach (Shell32.FolderItem2 item in objFolder.Items())
{
if (fileName == item.Name)
{
for (int i = 0; i < indexes.Length; i++)
{
sb.Append(objFolder.GetDetailsOf(item, indexes[i]) + ",");
}
break;
}
}
string result = sb.ToString().Trim();
if (result.Length == 0)
{
return string.Empty;
}
return result.Substring(0, result.Length - 1);
}
string Type = GetSpecificFileProperties(filePath, 2);
string ObjectKind = GetSpecificFileProperties(filePath, 11);
DateTime CreatedDate = Convert.ToDateTime(GetSpecificFileProperties(filePath, 4));
DateTime LastModifiedDate = Convert.ToDateTime(GetSpecificFileProperties(filePath, 3));
DateTime LastAccessDate = Convert.ToDateTime(GetSpecificFileProperties(filePath, 5));
string LastUser = GetSpecificFileProperties(filePath, 10);
string ComputerName = GetSpecificFileProperties(filePath, 53);
string FileSize = GetSpecificFileProperties(filePath, 1);

I have got the fix to that,
It can be achieved using the ObjectSecurity Class of .NET. In that we can use the GetOwner.
It fetches the owner of the file who has modified / created a file.
This is the piece of code which would help:
string owner = System.IO.File.GetAccessControl(e.FullPath).GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();
Console.WriteLine(owner);

Related

Using powershell reflection to perform database updates

I'm editing my question to make it more readily understood.
Here is an example solution: https://github.com/mckenn55/PowershellTest
I created a brand new net47 MVC project. I added an area called "Database" and a controller within that area called "Update". Within that controller, I have the following:
public ActionResult Index()
{
return View(Execute());
}
public static List<string> Execute()
{
var returnable = new List<string>();
var assembly = Assembly.GetExecutingAssembly();
string codeBase = assembly.CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
var assemblyLocation = Path.GetDirectoryName(path);
string resourcePath = "";
string ModuleName = assembly.ManifestModule.Name;
ModuleName = ModuleName.Substring(0, ModuleName.LastIndexOf("."));
ModuleName = ModuleName.Replace(' ', '_').Replace(".", "");
string FolderPath = "Areas.Database.SQL";
FolderPath = FolderPath.Replace(' ', '_');
if (FolderPath != null && FolderPath.Length > 0 && FolderPath[FolderPath.Length - 1] == '.')
FolderPath = FolderPath.Substring(0, FolderPath.Length - 1);
StringBuilder filepath = new StringBuilder();
filepath.Append(ModuleName);
if (FolderPath != null && FolderPath.Length > 0)
{
filepath.Append('.' + FolderPath);
filepath.Append('.');
}
resourcePath = filepath.ToString();
string[] resourceNames = assembly.GetManifestResourceNames();
foreach (var resourceName in resourceNames)
{
if (Regex.Match(resourceName, "^" + resourcePath).Success)
{
returnable.Add(resourceName);
}
}
var orderedFileNames = new List<string>();
if (returnable != null && returnable.Any())
{
orderedFileNames = returnable.OrderBy(q => q).ToList();
}
else
{
returnable.Add("No files found");
}
return returnable;
}
Within the Database area, I have a directory called "SQL" and within that directory, I have a single file, TestFile.sql, included in the solution as an embedded resource. The results of the Execute() method, when viewed using the index action is "PSTest.Areas.Database.SQL.TestFile.sql". I would like to see the same thing in Powershell. I have tried the following:
> Add-Type -path "C:\Temp\PSTest\PSTest\bin\PSTest.dll"
> [PSTest.Areas.Database.UpdateController]::Execute()
No Files Found
Is my goal possible through powershell and if so, how?
I was not able to find a solution to this using powershell alone. I wrote a C# console app that is able to perform these actions without any issue.

how to store and retrieve multiple values inside single session variable

i am using dropzone to upload multiple files to the server. files will be uploaded to server while file names will be stored in table.
i am trying to add file names in session.
the problem here is that it doesn't add multiple file names inside single session
here is my code :
string imageSessList = context.Session["imageNames"].ToString(); //if i put this line at the begining, then the debugger doesn't even moves to foreach block
foreach (string s in context.Request.Files)
{
HttpPostedFile file = context.Request.Files[s];
string fileName = file.FileName;
string fileExtension = file.ContentType;
string strUploadFileExtension = fileName.Substring(fileName.LastIndexOf(".") + 1);
string strAllowedFileTypes = "***jpg***jpeg***png***gif***bmp***"; //allowed file types
string destFileName = "";
List<string> lstImageNames = new List<string>();
// else upload file
if (!string.IsNullOrEmpty(fileName))
{
if (strAllowedFileTypes.IndexOf("***" + strUploadFileExtension + "***") != -1) //check extension
{
if (context.Request.Files[0].ContentLength < 5 * 1024 * 1024) //check filesize
{
// generate file name
destFileName = Guid.NewGuid().ToString() + "." + strUploadFileExtension;
string destFilePath = HttpContext.Current.Server.MapPath("/resourceContent/") + destFileName;
//Save image names to session
lstImageNames.Add(destFileName);
context.Session["imageNames"] = lstImageNames;
file.SaveAs(destFilePath);
strMessage = "Success " + destFileName;
}
else
{
strMessage = "File Size can't be more than 5 MB.";
}
}
else
{
strMessage = "File type not supported!";
}
}
} // foreach
context.Response.Write(strMessage);
}
here i am able to add only single filename to session, not multiple.
how to store and maintain multiple file names in single session :
context.Session["imageNames"]
you need to get current list from session
List<string> lstImageNames= (List<string>)Session["imageNames"];
if(lstImageNames==null)
lstImageNames = new List<string>(); // create new list in the first time
now add new item to it.
lstImageNames.Add(destFileName);
set back to session
context.Session["imageNames"] = lstImageNames;

get files from directory based on substring of filename - C#

I have a C# console app which gets all files in a directory. Taking the file name below as an example, and given that I will have 3 strings, ref, year1, year2, how could I say:
File name: 31596_2015-06-30.pdf
Give me all files where the file name contain ref AND file name contains a year between year1 and year 2?
Code so far:
var files = Directory.EnumerateFiles(sourceDir, "*", SearchOption.TopDirectoryOnly)
.Select(Path.GetFileName);
string start_year = null;
string end_year = null;
string ref = null;
// dr is a sql data reader
if (dr.HasRows == true)
{
while (dr.Read())
{
start_year = dr.GetString(1).Substring(7, 4);
end_year = dr.GetString(2).Substring(7, 4);
ref = dr.GetString(3);
foreach(string filename in files)
{
if (filename.Contains(ref))
{
File.Copy(sourceDir + filename, targetDir + filename);
}
}
File.Copy(sourceDir + dr.GetString(0), targetDir + dr.GetString(0));
}
}
I suggest extracting a class, say, FileData:
public class FileData {
public bool IsParsed {get; private set; }
public String FileName {get; private set; }
public DateTime Date {get; private set; }
public String Ref {get; private set; }
public FileData(String path) {
FileName = path;
if (String.IsNullOrEmpty(path))
return;
int p = path.IndexOf('_');
if (p < 0)
return;
Ref = path.Substring(0, p);
DateTime dt;
IsParsed = DateTime.TryParseExact(path.Substring(p + 1),
"yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out dt);
Date = dt;
}
}
By doing this you can put a simple Linq to obtain the files
var files = Directory
.EnumerateFiles(sourceDir, "*", SearchOption.TopDirectoryOnly)
.Select(file => new FileData(file))
.Where(info => info.IsParsed)
.Where(info => String.Equals(info.Ref, myRef))
.Where(info => info.Date.Year >= year1 && info.Date.Year <= year2)
.Select(info => info.FileName);
Assuming that your filenames have always the format as in your post,
you first need to split the year out of the name.
One possible solution could be:
string filenameYear = filename.Split('_')[1].Split('-')[0];
then you can use this string in your if condition to ask for all three cases:
if (filename.Contains(_ref) &&
Convert.ToInt32(filenameYear) > Convert.ToInt32(start_year) &&
Convert.ToInt32(filenameYear) < Convert.ToInt32(end_year))
{
// Do what ever you desire
}
in the line:
File.Copy(sourceDir + filename, targetDir + filename);
If sourceDir and targetDir has not a \ in the end or filename in the beginning. This will crash.
You can use
File.Copy(Path.Combine(sourceDir,filename), Path.combine(targetDir, filename);
to avoid problems
ps. you should avoid using ref as a name for variables in C#.
it is reserved as a keyword
I like Linq for this sort of thing. Unless you know for a fact that the values in the reader will always by what you expect, you should perform some validations, but this will achieve your stated goal with the least amount of changes to your sample code.
var start_year = (DateTime)dr.GetString(1).Substring(7, 4);
var end_year = (DateTime)dr.GetString(2).Substring(7, 4);
ref = dr.GetString(3);
foreach(string filename in files.Where(x => x.StartsWith(ref)
&& (DateTime)x.Substring(7, 4) >= start_year
&& (DateTime)x.Substring(7, 4) <= end_year))
{
File.Copy(sourceDir + filename, targetDir + filename);
}

C# fail to create file in directory if has other file

Can someone help me, I just learning C# for about 2 month, I have this problem,
i'm building a class for filter data from temp file and create the result in new txt file inside directory, if directory is empty nor at the same date, it build perfectly, and if there another file at same date it should create with increase the last number at lastname.
My problem when I run code, it is not creating if the directory has files with the same dates, then the result should be something like this:
C:\result_2014051301.txt
C:\result_2014051401.txt
C:\result_2014051402.txt <-- Failed, it is not ..2014051401.txt
class Entity2
{
public Entity2()
{
string fileTemp = "DEFAULT.temp";
string indexD = Properties.Settings.Default.ChIndex2D;
string indexC = Properties.Settings.Default.ChIndex2C;
string indexS = Properties.Settings.Default.ChIndex2S;
string tempPath = AppDomain.CurrentDomain.BaseDirectory;
string targetPath = Properties.Settings.Default.ExtractALL_DIR;
string SourceFile = Path.Combine(tempPath, fileTemp);
string tempFileX = Path.GetTempFileName();
if (!System.IO.Directory.Exists(targetPath))
{
System.Windows.Forms.MessageBox.Show("Error missing .temp", "Message Box");
}
else
{
string ext = ".txt";
int sequence = 0;
DateTime dateFileName = DateTime.Today;
string discode = Properties.Settings.Default.ChannelID_2;
string filename = discode + "_" + dateFileName.ToString("yyyyMMdd");
string pathX = Properties.Settings.Default.ExtractALL_DIR + #"/Channel2";
if (!Directory.Exists(pathX))
{
Directory.CreateDirectory(pathX);
}
string[] files = Directory.GetFiles(pathX, filename + "*.txt", SearchOption.TopDirectoryOnly);
if (files.Length > 0)
{
Array.Sort(files);
string lastFilename = files[files.Length - 1];
sequence = Int32.Parse(lastFilename.Substring(0, lastFilename.Length - 4).Replace(pathX + filename, ""));
}
sequence++;
string newFileName = filename + sequence.ToString().PadLeft(2, '0') + ext;
string DestFile = Path.Combine(pathX, newFileName);
using (var ab = new StreamReader(SourceFile))
using (var cd = new StreamWriter(DestFile))
{
string lineX;
while ((lineX = ab.ReadLine()) != null)
{
if (lineX.LastIndexOf("100", 3) != -1 || lineX.LastIndexOf("MGR", 15) != -1 || lineX.LastIndexOf(indexC, 15) != -1)
{
lineX = lineX.Replace(indexD, "");
lineX = lineX.Replace("DEFAULT", discode);
if (lineX.LastIndexOf("800", 3) != -1)
{
lineX = lineX.Replace(indexS, "");
}
cd.WriteLine(lineX);
}
}
}
}
}
}
This piece is not functioning correctly:
Int32.Parse(lastFilename.Substring(0, lastFilename.Length - 4).Replace(pathX + filename, ""));
pathX + filename is C:\folderfile.txt not C:\folder\file.txt.
You either need to add the \ or call Path.Join.
That will cause the Parse operation to fail since it tries to consume the who string (minus the extension).

C# Webserver requested directory issue

I am trying to make a web server in C#, i need to get the requested url and then list the files and folders requested.This is good to get the first directory .
For Eg. My webserver root is c:\test when i open localhost i get the contents of test folder. Say Data is subfolder of c:\test, i can click on data from the browser and get into C:\test\data now when i click on any folder then the get request comes with %2F instead of c:\test\data\ok and so i am stuck.
Code to Recieve The Request :
sRequest = sBuffer.Substring(0, iStartPos - 1);
sRequest.Replace("\\", "/");
if ((sRequest.IndexOf(".") < 1) && (!sRequest.EndsWith("/")))
{
sRequest = sRequest + "/";
}
iStartPos = sRequest.LastIndexOf("/") + 1;
sRequestedFile = sRequest.Substring(iStartPos);
sDirName = sRequest.Substring(sRequest.IndexOf("/"), sRequest.LastIndexOf("/") - 3);
if (sDirName == "/")
sLocalDir = sMyWebServerRoot;
else
{
//Get the Virtual Directory
// sLocalDir = GetLocalPath(sMyWebServerRoot, sDirName);
Console.WriteLine("i am here");
sDirName = sDirName.Substring(1, sDirName.Length - 2);
//sDirName = sDirName.Replace("/", "\\");
Console.WriteLine("Amit:" + sDirName);
string test1 = Path.Combine("C:\\test\\", sDirName);
sLocalDir = Path.Combine(#"C:\\test", sDirName);
}
Now to List Dir I have the following Function :
public String listdir(string sLocaldir,string sDirName)
{
string sresult = "";
StringBuilder sb = new StringBuilder();
sb.AppendLine("<html>");
sb.AppendLine("<head>");
sb.AppendLine("<title>Test</title>");
sb.AppendLine("</head>");
sb.AppendLine("<body>");
sb.AppendLine("<h1><center><u>Listing Folders Under " + sLocaldir + "</h1></u></center>");
string[] folderpaths = Directory.GetDirectories(sLocaldir);
sb.AppendLine("<font color=red><font size=5>Listing Directories<br>");
for (int i = 0; i < folderpaths.Length; i++)
{
string fpath = folderpaths[i];
string[] foldernames = fpath.Split('\\');
int j = foldernames.Length - 1;
string fname = foldernames[j];
string fullname;
if (sDirName != "/")
{
//fname= fname + "\\";
fullname = sDirName +"/"+ fname;
//fullname = fullname.Replace("\\", "/");
//fullname = Path.GetPathRoot("C:\\test");
Console.WriteLine("Get full path:" + fullname);
}
else
{
fullname = fname;
}
Console.WriteLine("Full Test:" + fullname);
//sb.AppendLine(string.Format("<img src=file.png height=20 width=20>{1}<br>",
sb.AppendLine(string.Format("<img src=file.png height=20 width=20>{1}<br>",
HttpUtility.HtmlEncode(HttpUtility.UrlEncode(fullname )),
HttpUtility.HtmlEncode(fname)));
}
string[] filePaths = Directory.GetFiles(#"C:\test");
sb.AppendLine("<font color=red><font size=5>Listing Files<br>");
for (int i = 0; i < filePaths.Length; ++i)
{
string name = Path.GetFileName(filePaths[i]);
sb.AppendLine(string.Format("<img src=file.png height=20 width=20>{1}<br>",
HttpUtility.HtmlEncode(HttpUtility.UrlEncode(name)),
HttpUtility.HtmlEncode(name)));
}
sb.AppendLine("</ul>");
sb.AppendLine("</body>");
sb.AppendLine("</html>");
sresult = sb.ToString();
return sresult;
//Console.WriteLine(sresult);
}
Any help would be highly appreciated.
Thank you
%2F is safe encoding for the / symbol. You are HTMLEncoding the / symbol in your code above.
Your approach can be much simpler see:
http://www.codeproject.com/KB/IP/mywebserver.aspx

Categories