 |
|
 |
Is there any way to get the PC Name of the user who is accessing server resources?
|
|
|
|
 |
|
 |
Honestly it has been a number of years since I have used this app. The company I wrote this for I haven't worked for in a number of year. Anyway, I believe the PC that has the share lock open is the Host variable. Hope that helps. Ben
|
|
|
|
 |
|
|
 |
|
 |
I took a look at your article. We did write similar articles. Mine was written 5 years before yours. Well, I guess great minds think alike.
Have a great day.
Ben
|
|
|
|
 |
|
 |
I have been trying to do something similar with an ASP.net version thinking I could deploy it across a network so that anyone would be able to see who has what files open.
Background:
I am an IT Manager for a medium sized company, so I personally have access to check who has what files locked and even close those files on other people. This is not my personal challenge but instead I want to give the ability to others to be able to also at least view who has what files locked.
Situation:
We use Acrobat pretty extensively and try to be as paperless as possible, however acrobat does not tell you when someone else has your file open so the few people who need to update these PDF files frequently are not able to because multiple people have these files open. They would come to me or one of my substitutes to find out who has the file open and depending possibly close that file on them. It happens at times when they cannot find me and with no access to the server or an admin account cannot find out other than to walk all over to find who has it open. This is not very affective, if I could deploy a simple webpage that would allow them to be able to view who has the files open they can ask them to close it personally.
My solution:
Instead of running a service that checks open files every minute I'd like to make that part of my ASP.net application such that whenever the page is opened it will fire the openfiles.exe and output the results into a csv which I can then interpret into a gridview or something. I have the basic gridview working (though I want to modify it as viewing the csv directly doesn't give me good options for filtering or sorting). I can solve my csv/gridview fine by importing the csv line by line into some datasource and read it back from there to a grid. My problem lies in firing the openfiles.exe command from asp.net.
My Problem:
I have researched the command on the microsoft website and developed a command that will give me what I want, and put it into a batch file. This script returns all the open files on a particular server using an administrative account credentials and outputs them into a csv. When I run this batch manually it works like a dream. When I try to launch it out of an ASP.net application it doesn't recognize the openfiles.exe as an internal or external command.
I think if I took your service idea I could essentially do the same as you are just simply make the front end an ASP.net site instead of a forms application. I just don't like the 1 minute delay and the need to run the service on the server constantly when it seems it could simply just be fired when needed. Any insight would be appreciated.
-Torbs
|
|
|
|
 |
|
 |
Hey Torbs,
You know, the post just below yours, someone posted some code to call the dll directly that openfiles calls. I didn't even know that could be done. I would suggest looking at that code as perhaps another way to get the information you need.
For me the reason I wrote the window service is that openfiles only seems to work when you have an admin login that has the correct rights etc. So that type of admin login isn't something you would want just anyone running. So it was easiest for me to just create a service that could run with that admin rights on a server and then have a windows app that looked at the data.
So in your case you could probably do it in asp.net, but you would run into a few hurdles. First your asp.net site runs as aspnet_user. This user generally does not have any network rights. The way around this is to setup your application pool to run as a network use. Still I would caution against this since it would mean that your asp.net site would be running as someone who has pretty elevated rights. Normally when I set up an application pool to use a network user, it is a normal user that just has rights to a sql server so then I can use NT authentcation to access sql not a sql user name and password.
Anyway, I don't know if I have been much help. Let me know if you have more questions.
Ben
|
|
|
|
 |
|
 |
Ben,
Thanks for your input.
With a few switches you can run the command as another user so if the user running the command doesn't have sufficient permissions they can still run it as long as they add the credentials in a switch. I put this in the batch script where no one would have access to the batch script and it would not require me to give this web application access to the administration of the computer (I agree very bad idea, even though this will be intranet only).
The code below seems to require that the user running it is indeed an administrator, this is where openfiles.exe was the better option for me since I could let it run as a plain jane user and still get results (because the admin credentials were in the swtiches). Though maybe there is some credence to the need to give some rights to the website user in order to even run the command. I will have to look into this possibility. I guess I should also verify that a non administrative user can run my batch script with the embedded credentials.
http://technet.microsoft.com/en-us/library/bb490961.aspx
You can see where you can put in a username and password. But I will try it from a non admin user account to confirm whether it is working or not.
Thanks again.
|
|
|
|
 |
|
 |
It has been a while since I have played with this code. The original company I wrote this code for I haven't worked for, in a number of years. Anyway, if my memory serves me correctly, a non admin user is not able to call the openfiles and have it return the data you are seeking. I could be wrong, but that is what I remember.
Ben
|
|
|
|
 |
|
 |
Hi,
As I stated below, It would easier to just call the NetFileEnum Windows API in order to get the same information, instead of running an external process and parsing its output.
Actually this is the very same API that is internally used by OpenFiles.exe:
NetFileEnum
http://www.pinvoke.net/default.aspx/netapi32/NetFileEnum.html
Here is some code I "borrowed" from PInvoke.net web site:
class Program
{
static void Main(string[] args)
{
const int MAX_PREFERRED_LENGTH = -1;
int dwReadEntries;
int dwTotalEntries;
IntPtr pBuffer = IntPtr.Zero;
FILE_INFO_3 pCurrent = new FILE_INFO_3();
int dwStatus = NetFileEnum(null, null, null, 3, ref pBuffer,
MAX_PREFERRED_LENGTH, out dwReadEntries, out dwTotalEntries, IntPtr.Zero);
if (dwStatus == 0)
{
for (int dwIndex = 0; dwIndex < dwReadEntries; dwIndex++)
{
IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (dwIndex * Marshal.SizeOf(pCurrent)));
pCurrent = (FILE_INFO_3)Marshal.PtrToStructure(iPtr, typeof(FILE_INFO_3));
Console.WriteLine("dwIndex={0}", dwIndex);
Console.WriteLine(" id={0}", pCurrent.fi3_id);
Console.WriteLine(" num_locks={0}", pCurrent.fi3_num_locks);
Console.WriteLine(" pathname={0}", pCurrent.fi3_pathname);
Console.WriteLine(" permission={0}", pCurrent.fi3_permission);
Console.WriteLine(" username={0}", pCurrent.fi3_username);
}
NetApiBufferFree(pBuffer);
}
}
[DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int NetFileEnum(
string servername,
string basepath,
string username,
int level,
ref IntPtr bufptr,
int prefmaxlen,
out int entriesread,
out int totalentries,
IntPtr resume_handle
);
[DllImport("Netapi32.dll", SetLastError = true)]
static extern int NetApiBufferFree(IntPtr Buffer);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct FILE_INFO_3
{
public int fi3_id;
public int fi3_permission;
public int fi3_num_locks;
[MarshalAs(UnmanagedType.LPWStr)]
public string fi3_pathname;
[MarshalAs(UnmanagedType.LPWStr)]
public string fi3_username;
}
}
Nice article, though.
Cheers,
Caio Proiete
|
|
|
|
 |
|
 |
When reading the file names, for some words of Brazil, these letters with accent has changed its character, for example, cópia returns c¢pia.
how to solve?
pardon, I'm not speak english.
Thanks
Wilson
|
|
|
|
 |
|
 |
Hello,
I don't know for sure what the problem is, but I am guessing that it may be an encoding problem. The System.Text.Encoding Class may be the answer. Honestly I haven't done much with encoding for this purpose, so I don't have a good answer for you. I found an example here:
http://bytes.com/topic/net/answers/172097-writing-file-mangles-special-characters[^]
Their example was in write out to a file. So we would be doing the reading in of a file. So I am guessing if you changed the code to read the file with the correct encoding then the characters would display correctly.
I hope that helps.
Ben
|
|
|
|
 |
|
 |
So this is a complete guess on what the code would look like, but hopefully this helps point you in the right direction.
So myprocess.StandardOutput is our StreamReader
If you create a new streamreader
something like:
dim eAnsi as Encoding = System.Text.Encoding.GetEncoding(1252)
dim sr as StreamReader = new StreamReader(myprocess.StandardOutput,eAnsi)
Then use sr where the code has myprocess.StandardOutput
I am guessing that you will properly read the special characters and thus they will display correctly.
Hope that helps.
Ben
|
|
|
|
 |
|
 |
Hi Wilson,
It would be much easier to just call the NetFileEnum Windows API to get the same information, instead of running an external process and parsing its output.
But anyway, in order to get the correct characters with accents and everything, you have the set the correct encoding in the property StartInfo.StandardOutputEncoding, which in your case would be "ibm850" (CodePage = 850).
Something like that would do the trick:
using (Process p = new Process())
{
p.StartInfo.FileName = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.System), "openfiles.exe");
p.StartInfo.Arguments = "/query /v";
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.StandardOutputEncoding = Encoding.GetEncoding("ibm850");
p.Start();
string line;
while ((line = p.StandardOutput.ReadLine()) != null)
{
}
p.WaitForExit();
}
Cheers,
Caio Proiete
|
|
|
|
 |
|
 |
Hello Caio Proiete,
thank you very much for your help. It's ecxaclly what I was needing.
thank you
Wilson Dutra
|
|
|
|
 |
|
 |
Hello,
we are looking for a long time for a tool like this.
we use VB.net 2008, we have compiled openfilesServer,exe and installed.
Everytime we try to start the service we see the green bar, but he don't finished.
It stopped with the message:
The service "OpenFilesSever" was started on "locale Computer" and then stopped.
I tried to translate from german.
Thank you for help.
|
|
|
|
 |
|
 |
Hello,
My first guess would be that your user doesn't have rights to write to the event log. Sometimes it is best to start the service once with an admin user that has rights to write to the event log. Then change the login to be a network user that has the correct rights on the network.
Check the event log to see if the windows service is writing out any messages.
Hope that helps.
Ben
|
|
|
|
 |
|
 |
Hello,
thank you for the immediately answer.
In the event log we found:
The service can't start, a piece of:
d:\share\openfilesdata\openfilesini.xml
was not found.
We have a directory:
c:\services
In this directory we have:
openfilesServer.exe and installed from this directory
opnefilesini.xml
It seems that the software are looking in the default directory.
Where is our mistake ?
|
|
|
|
 |
|
 |
In the OpenFilesService.vb file, there is a Private sub called readXmlini
In this sub there is a default path which is d:\share\openfilesdata\
You can change this to point to your path or you can pass a parameter into the window service. If you find your windows service in the console, then right click and select properties, on the general tab there is a box at the bottom called start parameters:
You can pass the path to your exe in that.
It might make the most sense to just change the OpenFilesSErvice.vb file and recompile the app, but either way will work.
Hope that helps.
Ben
|
|
|
|
 |
|
 |
Hello,
now I find the following in the event log:
"The service can't start"
Der Dienst kann nicht gestartet werden. System.IndexOutOfRangeException: Der Index war außerhalb des Arraybereichs.
bei OpenFilesServer.OpenFilesService.readxmlIni(String[] inargs)
bei OpenFilesServer.OpenFilesService.OnStart(String[] args)
bei System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(Object state)
I tried it on a Vista-PC and a XP-Pro-PC.
thanks
Uwe
|
|
|
|
 |
|
 |
This sounds like you have a problem with your xml file
The OpenFilesini.xml should have two nodes in it
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<Settings>
<OutputDir>\\servername\folderforoutput\</OutputDir>
<TimerElapse>60000</TimerElapse>
</Settings>
<FileServers>
<FileServerName>\\Server1</FileServerName>
<Active_Flag>Y</Active_Flag>
</FileServers>
</NewDataSet>
You need one Settings node and at least one FileServers node
I am guessing the xml file exists, but you are missing one of those two nodes.
NOTE you also need to have a valid servername and folder in OutputDir
and FileServerName
If you leave the defaults in there they will not work since those servers and folders do not exist on your network.
Hope that helps.
Ben
|
|
|
|
 |
|
 |
Hello Ben,
thank you for the help. It was not the .xml file, it is the parameter in the startbox.
I compiled the source with the right path to the exe, now it works.
I don't know the right parameter in the startbox, with c:\services it doesn't work.
The exe is in this directory.
I will work with the "right" source, so don't need a startparameter.
Best regards,
Uwe
|
|
|
|
 |
|
 |
Glad you got it working.
Ben
|
|
|
|
 |
|
 |
Great article , but I would like to know if there is any knowledge of listing the files opened by a process launched within my app.
Supposing I launch a batch session (via System.Diagnostic.Process class) I want to know which files that batch session is reading and writing from. Can this be done?
Many thanks,
David.
|
|
|
|
 |
|
 |
You know, I have never tried that before, but I am pretty sure you could find out if the process had files open. Your process still needs a context and rights to read files. If you had your process running as a windows service you could have the windows service log in as a specific login(user). Anyway, guess you would just have to try it and find out.
Ben
|
|
|
|
 |
|
 |
Hi,
I've Dl the zip.file and fill in the ini fiel. After running the service the following message came in:
"Application has generated an exception that could not be handled"
What is wrong???
John
|
|
|
|
 |