updating xml file from VB6
I have a 3rd party (black box) application that stores data in an XML file, which I want to be able to modify via my own VB6 app. I can successfully read the XML into my app, and navigate through the nodes, display in grids, etc. I can even make the updates I need to the MSXML2.DOMDocument50 object within my app - but can anybody tell me how I can write this information back out to the original XML file? The 3rd party application may be running throughout the process - I have tested updating the file 'on the fly' which is OK, but I can't delete and recreate it, as it is updated every 15 seconds from the 3rd party application...
To clarify my requirement a bit, the 3rd part app runs constantly, collecting statistics and regularly writing them out to the XML file. My app will be run ad hoc, and allows me to capture the stats at that point for reporting and archiving, but (and this is my stumbling block) then reset the counters held in the XML file back to 0.
Apologies if this has been covered elsewhere - I am new to DevX and could not find anything suitable via the forum searches, but am quite happy to be pointed in the right direction.
I assume you tried the "save" command on the DOM object. Does it fail? What's the problem?
probably the third party app opens the xml file and keeps it locked? If that app runs continuosly that make sense does it. Can you write the statistics in a separate file?
Bob - dammit! That's far too simple - why didn't I think of that?
Marco - Saving the stats elsewhere is already part of my process. My issue is that once saved, I wanted to reset the original file back to zero...
However, now that I have been able to write out the XML, this has exposed another problem... it appears that although I can rewrite the XML file with all zeroes, if the stats program is still running, it writes them all back again 15 seconds later. It looks like the stats program only reads the file once when the program starts running, thereafter, the figures are all maintained internally in memory, and the whole lot dumped out to the XML file every 15 seconds and at close of the program. So it doesn't look like I can reset it on the fly, anyway. I'm going to have to try some alternative method - perhaps I can get my VB app to close the stats program while I do the reset, or at least check to see that it isn't running. Any ideas how I can control or check for another process that isn't VB or Microsoft? I've interacted with IE and MS Office apps from VB, but this program ain't VB friendly as far as I can see (I can't pull its DLL files into my VB project, so there probably aren't any APIs that I can use). Perhaps I should start another thread since the issue is no longer XML specific?
Who wrote this 'stat' program? Is it a commercial product? Did you buy it? Does it have a documentation?
On the othe rhand, why do you want to reset the statistic every 15 seconds? Doesn't make sense to leave the stat program to continue its job and collect data other time, and have your app to capture snapshots of the data?
I am just trying to understand what is involved in your process...
The app measures time spent working on a variety of different projects. At the end of each day, and when I switch between clients, I need to capture all the data up to that moment, move it to a different location for subsequent reporting, and reset all the counters to zero for the next set of data to be accumulated.
It is a free piece of software, that has no documentation, and is old enough to be unsupported, and I can't get access to the source or developer
I think that I will have to live with shutting it down while I do the capture and reset, but it would be nice if I could have my VB app warn me if the other app is still running...
You can use the Win32 API to determine if another program is running, and then shut it down if it is:
Of course, this assumes the program is running with an open window...
Private Const WM_CLOSE = &H10
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Public Function KillWindow(ByVal strWindowName As String, ByRef strErrMsg As String) As Boolean
Dim lngHandle As Long
Dim lngRetVal As Long
lngHandle = FindWindow(vbNullString, strWindowName)
If lngHandle = 0 Then
strErrMsg = "Window not found"
lngRetVal = PostMessage(lngHandle, WM_CLOSE, 0, 0)
If lngRetVal = 0 Then
KillWindow = False
strErrMsg = "ERROR - " & Err.LastDllError
KillWindow = True
I knew that in some place I had a module to kill a process. The code has been tested in XP.
Here it is, drop this in a bas module. It kills all processes starting with the provided name. You can change it as you wish.
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szexeFile As String * 260
Private Declare Function CreateToolhelpSnapshot Lib "kernel32.dll" Alias "CreateToolhelp32Snapshot" ( _
ByVal lFlags As Long, lProcessID As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, _
ByVal blnheritHandle As Long, ByVal dwAppProcessId As Long) As Long
Private Declare Function ProcessFirst Lib "kernel32.dll" Alias "Process32First" (ByVal hSnapshot As Long, _
uProcess As PROCESSENTRY32) As Long
Private Declare Function ProcessNext Lib "kernel32.dll" Alias "Process32Next" (ByVal hSnapshot As Long, _
uProcess As PROCESSENTRY32) As Long
Private Declare Function TerminateProcess Lib "kernel32.dll" (ByVal ApphProcess As Long, _
ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Const PROCESS_ALL_ACCESS = 0
Private Const TH32CS_SNAPPROCESS As Long = 2&
Private Const INVALID_HANDLE_VALUE = -1
Private Const PROCESS_TERMINATE = 1
Public Sub KillProcess(NameProcess As String)
If Len(Trim(NameProcess)) = 0 Then Exit Sub
NameProcess = Trim(NameProcess)
Dim hSnapshot As Long
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
If hSnapshot = INVALID_HANDLE_VALUE Then Exit Sub
Dim procEntry As PROCESSENTRY32
Dim bProcessFound As Boolean
procEntry.dwSize = Len(procEntry)
bProcessFound = (ProcessFirst(hSnapshot, procEntry) <> 0)
Dim procName As String
Dim lExitCode As Long
Dim hProcess As Long
Do While bProcessFound
procName = procEntry.szexeFile
If StrComp(Left$(procName, Len(NameProcess)), NameProcess, vbTextCompare) = 0 Then
hProcess = OpenProcess(PROCESS_TERMINATE, False, procEntry.th32ProcessID)
If hProcess <> 0 Then
TerminateProcess hProcess, lExitCode
bProcessFound = (ProcessNext(hSnapshot, procEntry) <> 0)
Thanks guys. Using your approaches, I am currently checking for the existence of the other application, and shutting it down before proceeding - which is a temporary workaround. When I get the time to revisit it (generally only on the train on my way home - where I don't have internet access...), now that I can identify the application's hwnd, I'm going to try and send it the keystroke sequence to reset the files to zero itself (I think I can do this either with SendMessage or SendKey?), rather than trying to manipulate the xml file from my end. It would be a bit more elegant, and also leave the stats program running, rather than require me to manually restart it.
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center