Hi ,
I'm using Excel.Application generating excel report via vb.net 2003 , the problem is excel.exe process reminds even after generated excel report closed . I have been using the followed code to close or dispose the process , but it does'nt work either.
thenks
Dim
procList() As Process = Process.GetProcesses() Dim k As Integer For k = 0 To procList.GetUpperBound(0) Step k + 1 If procList(k).ProcessName = "EXCEL" ThenprocList(k).Close()
procList(k).Dispose()
End If Next
Can't kill Excel.Exe after using Excel component in vb.net
Scoutn
Hi,
The above method will kill the process. However if there are multiple applications or batch program running independant of eachother and each of them create their own excel object, the above method will kill all of the processes.
Is there anyway to uniquely identify the process pertaining to your application so that we can try to find the process by its id and kill the same
Another way is to do the following
objExcel.Workbooks.Close()
objExcel.Quit()
Marshal.ReleaseComObject(objExcel)
objExcel =
NothingGC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
But using GC is a performance issue. However this can be used if it does not occur frequently, in the sense that this GC.Collect does not happen at places where the user will have frequent access.
IraMaster
Terryd68
Still didn't work. It may be easier using Office 2003, but Office XP just will not release without killing the proc. Even if I do it in debug and then shut down the program (where it should drop the connection to the COM object), it still stays connected.
Workbook.Save()
Workbook.Close()
Application.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(Worksheet)
System.Runtime.InteropServices.Marshal.ReleaseComObject(Workbook)
System.Runtime.InteropServices.Marshal.ReleaseComObject(Application)
Worksheet = Nothing
Workbook =
NothingApplication =
NothingGC.Collect()
Dim proc As System.Diagnostics.Process For Each proc In System.Diagnostics.Process.GetProcessesByName("EXCEL")proc.Kill()
NextCruzPedro
you could try this
Public
Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _(
ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Dim proc As System.Diagnostics.Process Dim intPID As Integer Dim intResult As Integer Dim iHandle As IntPtr Dim strVer As String TryobjExcel =
New Excel.ApplicationobjExcel.Caption = "test"
objExcel.DisplayAlerts =
FalsestrVer = objExcel.Version
iHandle = IntPtr.Zero
If CInt(strVer) > 9 TheniHandle =
New IntPtr(CType(objExcel.Parent.Hwnd, Integer)) ElseiHandle = FindWindow(
Nothing, objExcel.Caption) End IfobjExcel.Workbooks.Close()
objExcel.Quit()
Marshal.ReleaseComObject(objExcel)
objExcel =
NothingintResult = GetWindowThreadProcessId(iHandle, intPID)
proc = System.Diagnostics.Process.GetProcessById(intPID)
proc.Kill()
Catch ex As Exception End Trythis will kill only the associated excel.exe and not all the exe's in the task manager.
Cheers
Ganesh
Andrea Lattuada
Noah Hambayi
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32 Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, _ ByVal wParam As Int32, ByVal lParam As Int32) As Int32 Public Function TerminateExcel() Dim ClassName As String = "XLMain" Dim WindowHandle As Int32When all else fails I use API function calls:
Dim ReturnVal As Int32
Const WM_QUIT = &H12
Do
Loop Until WindowHandle = 0
End Function
chunkai
Hi Swade,
you might be right about Excel but I am not convinced by your code. Every COM wrapper variable has to be passed to ReleaseComObject. In your case you do not call ReleaseComObject on Workbook and Worksheet. Setting them to Nothing has no immediate effect as those objects are just collectable if not referenced any more, but the collection and with that the Release call on the internal COM interface pointer is only down upon garbage collection.
Good candidates for holding references one might forget are event handlers. I don't know how the WithEvents semantics are when it comes to remove the event connections. Being explicit with AddHandler and RemoveHandler might help.
If Excel is still not exiting you might try calling GC.Collect(). Yes, I know, this is bad practice in general, but if you really used all possible ways to release your COM "connections" to Excel and there still seems to be some object holding onto Excel which is maybe unreachable and so collectable, that might be less "rude" than killing excel.exe.
If that all doesn't work, well, go for killing excel...
--
SvenC
Venkata Prasad K
I strongly agree with Denton! Every other approach is a waste of time and energy. This is simple and effective.
BlueTeck
Speedie
In v2.0 of the framework you get FinalReleaseComObject that does the loop for you.
olapdummy
Hi,
that is really not the supposed way of releasing a COM server ;)
Call System.Runtime.InteropServices.Marshal.ReleaseComObject on every COM variable when you do not need that COM variable any more. Unfortunately COM wrappers do not follow the IDisposable pattern so you cannot use the using statement but have to remember to put that call in your code at the appropriate places.
After the last COM reference is released excel.exe should go away if it was not started interactively before.
--
SvenC
tovarish
The FinalReleaseCOMObject and all forms of it do not kill the EXCEL.EXE in the windows task manager. I've run loops, do until, etc.... and nothing.
Unless an actual Microsoft VB Programmer (someone who developed it for MS) comes on here and gives me the specific code that kills an instance of excel using the Marhsall.ReleaseComObject or Marshall.FinalReleaseComObject then I will continue to work under the assumption that Excel XP cannot be shut down without process.kill().
It just doesn't release. Period. (For Office XP)
Sahus
Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, _
ByVal wParam As Int32, ByVal lParam As Int32) As Int32
Const WM_QUIT = &H12sveroa
Sadly that (the Interop Marshal release) doesn't always work because Excel XP and lower suck at releasing. I had to use your loop, but replace the Process.Close() and Process.Quit() with Process.Kill(). Works like a charm. Just be careful that you want ALL versions of excel.exe to be killed, because they will.
I use this:
Workbook.Save()
Workbook.Close()
Application.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(Application)
Worksheet =
NothingWorkbook = Nothing
Application = Nothing Dim proc As System.Diagnostics.Process For Each proc In System.Diagnostics.Process.GetProcessesByName("EXCEL")
proc.Kill()
Next