# vb.net app has no read access to local files



## ABauer (Jan 25, 2012)

Hello, I'm programming a small windows app that allows the user to fill out some fields and then creates and runs a batch file based on their entries.  The program works, but it doesn't.  The program creates the batch file just fine but when it tries to run the batch file, it gets errors in the cmd window saying it cannot find the scripts the batch file is trying to call.  What's confusing me is that if I take the batch file the program created and run it myself, it works just fine so I know it is not the batch that is the problem.  My best guess is that there is some security setting for vs.net that I've overlooked but I am only an "every once in a while" programmer so I really don't know where to look.  Additionally after running the batch, the program is supposed to delete the batch file but that fails as well with the message that it cannot find the batch file. The same batch file that it had just created and run. 

For system information, I'm running Windows XP Pro, SP3 with Visual Studio.net 2003.

Thanks in advance for your help!


----------



## FordGT90Concept (Jan 25, 2012)

Might have something to do with the Working Directory.  Best bet though is to give full paths to files when dealing with batch/cmd.


----------



## ABauer (Jan 25, 2012)

Thanks for the quick reply!  I am using full path names for all file references and all script files are in the same directory as both the app and the created batch file.


----------



## FordGT90Concept (Jan 25, 2012)

Can you provide some code?  Specifically the lines that prepare and launch cmd.  It should involve System.Diagnostics.Process and System.Diagnostics.ProcessStartInfo.


----------



## ABauer (Jan 25, 2012)

Sure can, here you go:

   Private Sub btnRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRun.Click
        Dim MyBatch As New IO.FileStream("C:\KMLTest\MyTempFile.bat", IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.Write)
        Dim MySetupText As New IO.StreamWriter(MyBatch)
        MySetupText.WriteLine("@echo off")
        MySetupText.Flush()
        If chkSHP.Checked = True Then
            Dim SHPPyDir As String = "C:\Python25\Python.exe"
            Dim SHPPyToRun As String = "SDEtoSHP.py"
            Dim SDELayer As String = txtSHPLayer.Text
            Dim WorkDir As String = txtSHPDir.Text
            Dim theSHPCommand As String = SHPPyDir & " " & SHPPyToRun & " " & SDELayer & " " & WorkDir
            '            MsgBox(theCommand)
            Dim MySHPText As New IO.StreamWriter(MyBatch)
            MySHPText.WriteLine(theSHPCommand)
            MySHPText.Flush()
        End If
        If chkKML.Checked = True Then
            Dim KMLFileToDel As String = txtKMLDir.Text & "\" & txtKMLOutName.Text & ".kml"
            Dim TheKMLInFile As String = txtKMLDir.Text & "\" & txtKMLInName.Text & ".shp"
            Dim TheKMLOutFile As String = txtKMLDir.Text & "\" & txtKMLOutName.Text & ".kml"
            Dim TheKMLCommand1 As String = "del " & KMLFileToDel & ">NUL"
            Dim TheKMLCommand2 As String = "ogr2ogr -f KML " & TheKMLOutFile & " " & TheKMLInFile
            Dim MyKMLText As New IO.StreamWriter(MyBatch)
            MyKMLText.WriteLine("SET FWTOOLS_DIR=C:\PROGRA~1\FWTOOL~1.7")
            MyKMLText.WriteLine("call ""%FWTOOLS_DIR%\bin\setfwenv.bat""")
            MyKMLText.WriteLine(TheKMLCommand1)
            MyKMLText.WriteLine(TheKMLCommand2)
            MyKMLText.Flush()
        End If
        If chkCSV.Checked = True Then
            Dim CSVPyDir As String = "C:\Python27\Python.exe"
            Dim CSVPyToRun As String = "KMLtoCSV.py"
            Dim TheCSVInFile As String = txtCSVInName.Text & ".kml"
            Dim TheCSVOutFile As String = txtCSVOutName.Text & ".csv"
            Dim TheCSVCommand As String = CSVPyDir & " " & CSVPyToRun & " " & TheCSVInFile & " " & TheCSVOutFile & " " & txtCSVDir.Text
            Dim MyCSVText As New IO.StreamWriter(MyBatch)
            MyCSVText.WriteLine(TheCSVCommand)
            MyCSVText.Flush()
        End If
        MyBatch.Close()
        'Shell("C:\KMLTest\MyTempFile.bat", AppWinStyle.NormalFocus, True)
        System.Diagnostics.Process.Start("C:\KMLTest\MyTempFile.bat")
        System.Diagnostics.Process.Start("Del C:\KMLTest\MyTempFile.bat")
    End Sub


----------



## ABauer (Jan 25, 2012)

Hmm, cant seem to edit my post but that line calling the batch that shows as:
System.Diagnostics.Process.Start("C:\KMLTest\MyTem pFile.bat")
is actually:
System.Diagnostics.Process.Start("C:\KMLTest\MyTempFile.bat")
I don't know where that space came from


----------



## FordGT90Concept (Jan 25, 2012)

If a line is too long, it adds the space so it can wrap.  If you use the code BBCode tag around it, it shouldn't wrap.


Anyway, first you'll want to remove the Shell command.  That's meant for debugging in Visual Studio, not for actual program code.

Second, you'll need to run the batch the proper way by calling CMD and pointing CMD to the batch.  For example:

```
Dim psi As New System.Diagnostics.ProcessStartInfo(System.Environment.GetEnvironmentVariable("COMSPEC"), "/C " & Chr(34) & "C:\KMLTest\MyTempFile.bat" & Chr(34))
psi.UseShellExecute = False
System.Diagnostics.Process.Start(psi).WaitForExit()
```
The WaitForExit is important because you're trying to delete it immediately afterwards.  If the Delete line is called before the process is done, it would give an access error.

Third, delete using the .NET way instead of running a separate program:

```
System.IO.File.Delete("C:\KMLTest\MyTempFile.bat")
```


Edit: The code above hasn't been tested so it likely isn't perfect.  It has been a while since I coded for VB.

Edit: Changed "cmd.exe" to environmental variable COMSPEC.


----------



## ABauer (Jan 25, 2012)

Fantastic!  It works!  Thank you so much for your help.

If you don't mind me asking, what is the difference (access wise) between the way you did it and my original way since both are using the start() command.  I at one point had the cmd call in the start() section based on some code I found online but it made no difference.


----------



## FordGT90Concept (Jan 25, 2012)

Basically, the way I did it mimiced running the batch.  The way you did it, it left how to run it up to the discretion of Windows (and Windows assumed wrong).

If you were indeed getting an access error, it could be because your program runs cmd with the same priviledges as your program (likely administrator).  Calling the batch directly passed it off to Windows and Windows most likely launched cmd with minimal rights (limited user) so when it tried to do anything outside of its working directory, it errored.


The deleting portion working is because of the WaitForExit().


----------

