FileVersionInfo.GetVersionInfo not letting go of file - vb.net

I'm trying to check the version of the Windows application the user is running against the version that is on the server to see if the local version needs to be updated. I do this by calling
FileVersionInfo.GetVersionInfo("path to file on server")
and reading the version information. This works fine for what I need, however, when I look at open files on the server from the computer management console, I see many instances of my file open in Read mode. This causes a problem when I need to copy a new version to the server. I first have to close all of the open files before it will let me write to it. Even though they are only open in Read mode, it still makes me close them.
Is there a better way to get the file version from the server? Or is there a way to dispose of the FileInfo variable that I am using so it disconnects?

I have not found a good resolution using FileVersionInfo. And from my research using FileVersionInfo does not release the variable as you would expect so I changed to getting the file information from a PowerShell script. This allows me to dispose the object and release the file as I have tested successfully. So here is the code that gets the information:
Dim server_version As String = ""
Dim invoker As New RunspaceInvoke
Dim command As String = "(Get-Item path_to_file_no_quotes_needed).VersionInfo.FileVersion"
Try
Dim outputObjects As Collection(Of PSObject) = invoker.Invoke(command)
For Each result As PSObject In outputObjects
server_version = result.ToString
Next
Catch ex As Exception
End Try
invoker.dispose
When this is run from my app, I see the file get opened in Read mode on the server but it disappears after about 3 seconds. So I can see the object is being properly disposed. Just FYI, there is no FileVersionInfo.dispose method.
In addition, for this to work you need:
Imports System.Management.Automation
which needs a reference in your project. It can be found in:
C:\Windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35\System.Management.Automation.dll

In the Shown event I have code that looks like this,
Try
If My.Application.IsNetworkDeployed AndAlso My.Application.Deployment.CheckForUpdate Then
'update available - the update will happen when app is closed
End If
Catch ex As Exception
'error while checking for update or update is corrupt
End Try
I do this so I can provide the user an indication that an update is available.
In the FormClosed event I do,
Try
'see if update is available, and install if it is
If My.Application.IsNetworkDeployed Then
If My.Application.Deployment.CheckForUpdate Then
My.Application.Deployment.Update()
End If
End If
Catch ex As Exception
End Try

Related

Access 2007 compact DB

Sorry for my English, I write from Italy.
I use the Access 2007 DB in a business data management procedure in VB Net.
As is known, Access DBs expand during use and consequently I need to compact them when the program is closed.
I perform the compaction in this way
Dim MioEngine As New Microsoft.Office.Interop.Access.Dao.DBEngine
MioEngine.CompactDatabase(myAccesDB, newAccessDB,)
Application.DoEvents()
but often and not on all PCs on the network, the compaction does not finish and gives me the following error message:
The process cannot access the 'C:\myAccesDB.accdb' file because it is being used by another process
Analyzing in depth what happens, I see that when the error occurs, the .laccdb file is not closed at the time of compacting.
Is there any way other than the one I used to do the compacting safely?
I specify that all the PCs in our network are Windows 10 pro and all updated; when Windows 10 was in its infancy, I didn't get this error.
Since my comment was not enough, here's an answer:
The idea is to try to opetn .laccdb file before you try to compact the database. You can do something like this:
Dim file as System.IO.FileInfo = New System.IO.FileInfo("c:\myAccesDB.laccdb")
Dim stream As FileStream = Nothing
Try
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None)
stream.Close()
'if stream is successfully closed, file is not in use and database can be compacted
MioEngine.CompactDatabase(myAccesDB, newAccessDB,)
Catch ex As Exception
'show some message to user that file is in use so it can try again
End Try
I worked with VB and Access ages ago, so this is only a direction that you should take.
Thanks, I'll try.
I also had a look to this:
https://support.microsoft.com/en-us/topic/office-error-accdb-remains-locked-after-oledb-connection-is-closed-37d42348-9edf-4493-a5f4-35c685af3160?ui=en-us&rs=en-us&ad=us
Where I find:
This issue is now fixed. If you launch Access, click 'File', then 'Account', then 'Update Options', and 'Update Now', this will ensure that you have the latest version, and all versions should have the fix available.
But I'm not able to find 'File' opening Access,....

Access to path is denied when trying to import from the client's desktop with SSIS

I'm creating a html page that will import an excel file in to a tracking system. On a button click event excel file is located / ssis package is fired / data imported then closed out. Thats the idea work flow. Problem is the excel file access is being denied before the package even executes
Here is the exact error :
I've tried :
excel file properties have been shared to everyone
identity impersonate set to true
hard coding the path
here is the VB code
Protected Sub bntExecute_Click(sender As Object, e As EventArgs) Handles btnExecute.Click
Dim app As Application = New Application()
Dim package As Package = Nothing
'Dim fileName As String = "C:\Users\Desktop\T. Bryant III\PTSID_Update_Template"'
Try
Dim fileName As String = Server.MapPath(System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString()))
FileUpload1.PostedFile.SaveAs(fileName)
package = app.LoadPackage("#C:\Users\Desktop\T.Bryant III\KitImport", Nothing)
'excel connection from package'
package.Connections("SourceConnectionExcel").ConnectionString = "provider=Microsoft.Jet.OLEDB.4.0data source =" + fileName + "Extended Properties = Excel 8.0"
'Execute the pakage'
Dim results As Microsoft.SqlServer.Dts.Runtime.DTSExecResult = package.Execute()
Catch ex As Exception
Throw ex
Finally
package.Dispose()
package = Nothing
End Try
End Sub
Thanks in advance or if there is an easier way to do this please let me know. The package when executing it in ssis works fine with its own connection manager etc.
A few things to try. If they don't work for you as permanent solutions, they should at least confirm that your code is working and you are dealing with a persmissions issue (which appears to be the case).
Move your file to the public folder (C:\Users\Public).
Run your application (or web browser) as an administrator (if applicable to your version of Windows).
If you are using a web browser, try using a different one.
If nothing else works, try pasting your code into a Windows Form Application.
If you still get the same error after trying all of this, it's time to take another look at your code. Remove the Try/Catch block to determine precisely which line is throwing the error. If you've tried hard coding, I'm guessing it's the SaveAs method. I'm not sure what class FileUpload1 is, but some SaveAs methods won't overwrite existing files unless you explicitly tell them to. Check the appropriate documentation and see if you don't need to pass a True value somewhere along with filename.
Update us with the results. At the very least, this should narrow down your problem and allow for a better diagnosis of it.

Testing if I have full read/write access to a file in VB .NET 4.5 before processing it

I'm writing a windows service which runs as the local system account. I'm trying to make sure if I have full read/write access to a file beginning to process it any further. Here is my code:
Dim FullPath As String
FullPath = "C:\directory\file.txt"
Dim ps As Security.PermissionSet
ps = New Security.PermissionSet(Security.Permissions.PermissionState.Unrestricted)
ps.AddPermission(New Security.Permissions.FileIOPermission(Security.Permissions.FileIOPermissionAccess.AllAccess, FullPath))
ps.AddPermission(New Security.Permissions.FileIOPermission(Security.Permissions.FileIOPermissionAccess.AllAccess, IO.Path.GetDirectoryName(FullPath)))
Try
ps.Demand()
Catch ex As Security.SecurityException
System.Diagnostics.EventLog.WriteEntry("ShopLink", "File " + FullPath + " will not be parsed. " + ex.Message)
Exit Sub
Catch ex As Exception
System.Diagnostics.EventLog.WriteEntry("ShopLink", "File " + FullPath + " will not be parsed. " + ex.Message)
Exit Sub
End Try
Then I set the full access permissions for the file to "Deny" for the user account my service is running as. After executing, the code above doesn't throw any exceptions and allows file processing to begin. When the service later tries to change and/or delete the file, I get an "Access Denied" exception.
Any suggestions?
For this purpose i use thise small function:
Private Function HasAccess(ByVal ltFullPath As String)
Try
Using inputstreamreader As New StreamReader(ltFullPath)
inputstreamreader.Close()
End Using
Using inputStream As FileStream = File.Open(ltFullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
inputStream.Close()
Return True
End Using
Catch ex As Exception
Return False
End Try
End Function
In your case then:
If HasAccess(FullPath) ...
I have solved the problem by using My.Computer.FileSystem.DeleteFile to delete the file instead of Kill. My.Computer.FileSystem.DeleteFile was executed without problems after successfully demanding full read/write access to the file in the way described above, while Kill consistently threw an "Access denied" exception.
Using "Kill"... I know this is a very old thread but I'll add this in case anyone stumbles on it like I did. I was working on some old VB6 legacy code. One of my clients users was getting a runtime exception during a file open after a kill. The code was "Killing" the file and then rebuilding it from scratch with binary data held in memory. It tuns out that the "Kill" function triggered the user's anti-virus software which locked the file long enough to cause the next "Open" statement to fail. I discovered this using an error logging utility (the name escapes me at the moment). The line in the error log file on the failed "Open" statement was that the file's status was "Delete pending" due to the user's anti-virus software.

How to release MS Access LDB lock file after created it

sorry for long text.
Problem: I have difficulty in removing the LDB generated by the "CREATE" method of ADOX in the following code segment. Please provides some hints/pointers to the solutions, and thanks.
Aims: Create (on the fly) a new access database and then export data (says Arena modules) to that newly created database.
Expected: The newly created access database should be able to be used by some external operations, say Access.exe, after the end of the subroutine and without exiting the current VB program.
I tested that the "Arena code" do nothing about the create/release of the ldb file.
I tested the "Exclusive Mode" in connection string, but the access file is still locked by the vb program.
I tested under both inside the VB environment, and directly invoke the generated from Explorer, and same results.
Other database formats is not the options to me. (due to Arena export limit)
It is not a web app.
Code:
Sub Method1()
Dim logs As New System.Collections.Generic.List(Of String)
Dim arenaApp As Arena.Application = Nothing
Try
logs.Add("Creating access database")
Try
Dim cat As New ADOX.Catalog
cat.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=new.mdb;Jet OLEDB:Engine Type=5")
cat = Nothing
Catch ex As Exception
logs.Add(ex.Message)
logs.Add(ex.StackTrace)
Finally
logs.Add("End creating access database")
End Try
'Opening Arena model"
arenaApp = New Arena.Application()
arenaApp.Models.Open(fileName)
arenaApp.ActiveModel.ExportModules("", "new.mdb", "TableName", "", Arena.smExportType.smExportAll)
Catch ex As Exception
logs.Add(ex.Message)
logs.Add(ex.StackTrace)
Finally
...
End Try
End Sub
Platform:
Windows 7 64bit, Office 2010 (32)
VB 2010 express
Lib: MS ADO Ext. 2.8 for DDL and Security
What about closing the mdb after creation, then reopening it ?
I am not a VS expert, but in Access, many things in "Design mode" put the mdb in Exclusive mode...and you can't switch back without closing it first i suspect.
If you want to create a database, its probably simpler to PInvoke SQLConfigDataSource. Then you can connect to it via ADODB, ADO.NET or your VB.NET data access methodology of choice.
I don't have an example of doing it in VB.NET, but this C# class and this powershell script demonstrate how to call the function.
I know it's an old question. I encountered exactly the same issue today. Some comments ask why use ADOX, that's because first, it's from legacy code, and second, I didn't find any other ways to dynamically create mdb file.
In VB6, whenever you set adox = Nothing, this com object will be released immediately and so is the ldb file.
In .Net, you have to rely on GC to collect the adox before ldb file is unlocked.
So, I made the following trick. I know it's ugly, but I didn't find any other ways, and at least my trick worked.
Dim t As New Thread(
Sub
'All adox code should be here
'....
'....
adox = Nothing
End Sub
)
t.Start()
t.Join()
t = Nothing
GC.Collect()
Sleep(50)

Deleting a file causes an untrapable error

In my app i have to copy and then delete image files from memory cards, the problem comes when some of the card inadvertantly have the "Lock" switch engaged turning them to read only.
When trying to delete these files i want to log the failure to delete but not show any UI messages until a time of my choosing.
Here is some sample code i am having trouble with.
Sub Main()
Try
System.IO.File.Delete("K:\BYZTCSQ_0050.JPG")
Catch ex As Exception
'Error would be logged here
End Try
End Sub
This works fine when debuging i.e. it tries to delete the file and if not the error is caught and i can proccess it as nessecary, but when i build and run the app i get an error message telling me that the file cannot be deleted.
To test this code you will need a drive that can be physically set to read only (USB memory key, SD card) and try to delete a file on it while debuging and after a build.
Why would the same code run differently and how can i stop the excess error messages?
You can try to create a file on the memory card. For reasons only known to Microsoft (or not), creating a file on a copy-protected drive will raise the error condition in the Try block while deleting a file will not. Incidentally, I got the same odd result -- catching the delete worked fine in debug mode, but not from the .exe.
Imports System.IO
...
Try
fs = File.Create(drive & "\tmp.~tmp")
Catch ex As Exception
copyprotected = true
End Try
if not copyprotected then
file.delete(drive & "\tmp.~tmp")
file.delete(the file you wanted to in the first place)
end if
Instead of wrapping it in a try/catch block, test to see if the file exists before trying to execute the delete:
Dim strFilePath as String = "K:\BYZTCSQ_0050.JPG"
If File.Exists(strFilePath) Then
System.IO.File.Delete(strFilePath)
End If