0

In my .Net application, I am dynamically creating a .bat file to find all open files on the machine using OPENFILES /QUery (if another machine on the network is accessing them). This batch file returns the proper output if I run it outside of my .net application, but if I execute it inside it, I get no output at all, running the same exact batch file. Code below:

    Dim curdir As String = System.IO.Directory.GetCurrentDirectory.ToString
    File.Create(curdir & "\temp.bat").Close()
    Using writer As New System.IO.StreamWriter(curdir & "\temp.bat")
        writer.WriteLine("@echo ON")
        writer.WriteLine("OPENFILES /Query > " & curdir & "\temp.txt")
        writer.WriteLine("exit")
    End Using
    File.Create(curdir & "\temp.txt").Close()
    Using Process As New Process
        'Process.StartInfo.UseShellExecute = True
        Process.StartInfo.FileName = curdir & "\temp.bat"
        Process.StartInfo.Verb = "runas"
        Process.Start()
        Process.WaitForExit()
        Dim srOutput As New IO.StreamReader(curdir & "\temp.txt")
        MessageBox.Show(srOutput.ReadToEnd)
    End Using

I have also tried the following:

  Dim myprocess As New Process
    'Program you want to launch execute etc.
    myprocess.StartInfo.FileName = "c:\windows\SysWow64\openfiles.exe"
    myprocess.StartInfo.Arguments = " /query"

    'This is important. Since this is a windows service it will run
    'even though no one is logged in.
    'Therefore there is not desktop available so you better
    'not show any windows dialogs
    myprocess.StartInfo.UseShellExecute = False
    myprocess.StartInfo.CreateNoWindow = True
    'We want to redirect the output from the openfiles call to the program
    'Since there won't be any window to display it in
    myprocess.StartInfo.RedirectStandardOutput = True
    Try
        myprocess.Start()

        If Not (myprocess.StandardOutput Is Nothing) Then

            'This string is used to contain what openfiles program returns
            Dim tmpstr2 As String = String.Empty
            Dim values(6) As Object 'This storeds the fields from openfiles
            Dim values2(0) As Object 'This is the current date
            values2(0) = DateTime.Now
            Dim cnt As Integer = 0

            Do
                tmpstr2 = myprocess.StandardOutput.ReadLine
                ' Add some text to the file.
                If Not (tmpstr2 Is Nothing) Then
                    cnt += 1
                    'The output is fixed length
                    If cnt > 5 Then
                        values(0) = tmpstr2.Substring(0, 15).Trim 'Host name
                        values(1) = tmpstr2.Substring(16, 8).Trim 'ID
                        values(2) = tmpstr2.Substring(25, 20).Trim 'accessed by
                        values(3) = tmpstr2.Substring(46, 10).Trim 'type
                        values(4) = tmpstr2.Substring(57, 10).Trim 'locks
                        values(5) = tmpstr2.Substring(68, 15).Trim 'open mode
                        values(6) = tmpstr2.Substring(84) 'open file
                    End If
                End If
                File.Create(curdir & "\temp.ini").Close()
                INIWrapper.WriteINIValue2("OpenFiles" & cnt.ToString, "Host Name", values(0), curdir & "\temp.ini")
                INIWrapper.WriteINIValue2("OpenFiles" & cnt.ToString, "ID", values(1), curdir & "\temp.ini")
                INIWrapper.WriteINIValue2("OpenFiles" & cnt.ToString, "Accessed by", values(2), curdir & "\temp.ini")
                INIWrapper.WriteINIValue2("OpenFiles" & cnt.ToString, "Type", values(3), curdir & "\temp.ini")
                INIWrapper.WriteINIValue2("OpenFiles" & cnt.ToString, "Locks", values(4), curdir & "\temp.ini")
                INIWrapper.WriteINIValue2("OpenFiles" & cnt.ToString, "Open mode", values(5), curdir & "\temp.ini")
                INIWrapper.WriteINIValue2("OpenFiles" & cnt.ToString, "Open File", values(6), curdir & "\temp.ini")

            Loop Until tmpstr2 Is Nothing
        End If
        'Wait for the process to finish before continuing.
        myprocess.WaitForExit()
    Catch e As System.Exception

    Finally
        'Free resources
        myprocess.Close()
    End Try

to no avail.

EDIT:

I have just noticed that the command line is throwing an error: ERROR: The target system must be running a 32 bit OS

does anyone know how to get around this for OPENFILES.exe? This command works file outside of my application.

dingdangdowney
  • 501
  • 1
  • 8
  • 22
  • I'd think/hope these kind of operations would be blocked without explicit permissions since you can do stuff like delete the entire harddrive data with a .bat – G_V Oct 31 '14 at 12:41
  • I just need to be able to run this command, or find another way of getting a list of all of the Open files that would be returned by the OPENFILES /Query command. This was just the initial way I thought to do it, and did not see alternatives in my initial research. – dingdangdowney Oct 31 '14 at 12:46
  • Have you tried running the 64-bit version (`C:\Windows\System32\openfiles.exe`)? – aphoria Oct 31 '14 at 13:57
  • I have indeed tried this, but without success. – dingdangdowney Oct 31 '14 at 14:04
  • Take a look on [How do I get the list of open file handles by process in C#?](http://stackoverflow.com/questions/177146) - C++/C# solution. Or take a look on [An app to see who has files open on a network server](http://www.codeproject.com/Articles/10760/An-app-to-see-who-has-files-open-on-a-network-serv), a VB.net solution which uses also openfiles.exe. – Mofi Oct 31 '14 at 14:05
  • When you run the 64-bit version, I'm assuming you get a different error...what is it? – aphoria Oct 31 '14 at 14:14
  • And there is also a Windows script solution, see [How Can I List Open Sessions and Open Files on a Computer?](http://blogs.technet.com/b/heyscriptingguy/archive/2005/02/16/how-can-i-list-open-sessions-and-open-files-on-a-computer.aspx) Best would be not depending on other applications and code it directly in your VB.net application if this is possible. And the forum topic [List all files that a process has opened](http://www.vbforums.com/showthread.php?523326-RESOLVED-List-all-files-that-a-process-has-opened) contains VB.net code for exactly what you need. – Mofi Oct 31 '14 at 14:15
  • @aphoria, I still get the same message when running the 64 bit version. – dingdangdowney Oct 31 '14 at 15:02
  • @Mofi I have actually done quite a bit of searching. The VB.net link you provided is actually where I have adapted my current code from (the second code block). This is still giving me the error mentioned. – dingdangdowney Oct 31 '14 at 15:05
  • @downeysyndrome, if you want to run 64-bit version of openfiles.exe as simply necessary from within a 32-bit application, you have to use `C:\Windows\Sysnative\openfiles.exe` and NOT `c:\windows\SysWow64\openfiles.exe` as you do in your code. See [File System Redirector](http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187.aspx) article in MSDN to understand which directory contains which files. – Mofi Oct 31 '14 at 15:56

0 Answers0