IXMLDOMDocument::selectNodes doesn't work as expected - c++

It's amazing IXMLDOMDocument::selectNodes doesn't work as expected. I know it's because xmlns="http://stackoverflow.com/questions/ask", but I don't know how to make it work if xmlns is present.
V_BSTR(&varParam) = SysAllocString(LR"iPhone5s(XPath)iPhone5s");
V_VT(&varParam) = VT_BSTR;
hr = ptrXMLDom->setProperty(L"SelectionLanguage", varParam);
ptrXMLDom->selectNodes(L"//bookstore", &ptrDomNodeList);
ptrDomNodeList->get_length(&len);//the value is always 0
Remarks: the xml is read-only. Don't tell me to modify original XML.
Here is my code:
#include <msxml6.h>
#include <msxml2.h>//necessary in Visual Studio 2013
HRESULT hr = CoInitialize(NULL);
HRESULT hr = CoCreateInstance(__uuidof(DOMDocument60), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(ppDoc));
if (SUCCEEDED(hr))
{
// these methods should not fail so don't inspect result
(*ppDoc)->put_async(VARIANT_FALSE);
(*ppDoc)->put_validateOnParse(VARIANT_FALSE);
(*ppDoc)->put_resolveExternals(VARIANT_FALSE);
(*ppDoc)->put_preserveWhiteSpace(VARIANT_TRUE);
}
HRESULT hr = S_OK;
IXMLDOMDocument2 *ptrXMLDom = NULL;
VARIANT_BOOL varBool = VARIANT_FALSE;
BSTR bstrXML = nullptr;
VARIANT varParam;
VariantInit(&varParam);
V_BSTR(&varParam) = SysAllocString(LR"iPhone5s(E:\Work\book.xml)iPhone5s");
V_VT(&varParam) = VT_BSTR;
hr = ptrXMLDom->load(varParam, &varBool);
V_BSTR(&varParam) = SysAllocString(LR"iPhone5s(XPath)iPhone5s");
V_VT(&varParam) = VT_BSTR;
hr = ptrXMLDom->setProperty(L"SelectionLanguage", varParam);
ptrXMLDom->selectNodes(L"//bookstore", &ptrDomNodeList);
ptrDomNodeList->get_length(&len);//the value is always 0
CoUninitialize();
Here is the xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Copyright w3school.com.cn -->
<!-- W3School.com.cn bookstore example -->
<bookstore xmlns="http://stackoverflow.com/questions/ask" version="1.0">
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="web" cover="paperback">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="web">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
</bookstore>

i have found the answer by myself.
V_BSTR(&varParam) = SysAllocString(LR"iPhone5s(xmlns:pf='http://stackoverflow.com/questions/ask')iPhone5s");
V_VT(&varParam) = VT_BSTR;
hr = ptrXMLDom->setProperty(L"SelectionNamespaces", varParam);
ptrXMLDom->selectNodes(L"//pf:bookstore/pf:book", &ptrDomNodeList);
ptrDomNodeList->get_length(&len);//4

Related

Accessing attribute values in an XML structure- C++ using MSXML6

I have this XML file below:
<catalog>
<book id="bk101">
<author> Gambardella, Matthew </author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications with XML.</description>
</book>
</catalog>
I would like to print the attribute inside the book node (that being the value of id, which is bk101), however I'm having trouble using the MSXML6 library to do so, and I would like to stick with it instead of changing to Rapid, etc.
Below is my code so far:
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#import <msxml6.dll> rename_namespace(_T("MSXML"))
#include<iostream>
#include<string>
int main(int argc, char* argv[]) {
HRESULT hr = CoInitialize(NULL);
if (SUCCEEDED(hr)) {
try {
MSXML::IXMLDOMDocument2Ptr xmlDoc;
MSXML::IXMLDOMNodePtr bookholder;
MSXML::IXMLDOMNodePtr author;
MSXML::IXMLDOMNodePtr title;
hr = xmlDoc.CreateInstance(__uuidof(MSXML::DOMDocument60),
NULL, CLSCTX_INPROC_SERVER);
// TODO: if (FAILED(hr))...
if (xmlDoc->load(_T("books.xml")) != VARIANT_TRUE) {
printf("Unable to load input.xml\n");
}
else {
printf("XML was successfully loaded\n");
xmlDoc->setProperty("SelectionLanguage", "XPath");
MSXML::IXMLDOMNodeListPtr booklist = xmlDoc->selectNodes("/catalog/*");
bookholder = booklist->Getitem(0);
//printf(bookholder->Getxml()+"\n"); //works till here
//printf(bookholder->; //what to do here to print attribute?
}
}
catch (_com_error& e) {
printf("ERROR: %ws\n", e.ErrorMessage());
}
CoUninitialize();
}
return 0;
}

XPath query is not working in IXMLDOMDocument2, but passes online XPath tester

In the below XML, I'm trying to use an XPath query to select the first <Event> node that has RenderingInfo/Task = StartRemoteSessionRdpClientBegin.
<Events>
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Guid="{9e814aad-3204-11d2-9a82-006008a86939}" />
<EventID>0</EventID>
</System>
<EventData>
<Data Name="EventVersion">0</Data>
<Data Name="Reserved">0</Data>
<Data Name="PartitionType"> 0</Data>
</EventData>
<RenderingInfo Culture="en-US">
<Opcode>PartitionInfoExtensionV2</Opcode>
<Provider>MSNT_SystemTrace</Provider>
<EventName xmlns="http://schemas.microsoft.com/win/2004/08/events/trace">EventTrace</EventName>
</RenderingInfo>
<ExtendedTracingInfo xmlns="http://schemas.microsoft.com/win/2004/08/events/trace">
<EventGuid>{68fdd900-4a3e-11d1-84f4-0000f80464e3}</EventGuid>
</ExtendedTracingInfo>
</Event>
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft.Windows.HVSI.Manager" Guid="{5e3f60ef-a60f-45a9-84ae-e224f761baa3}" />
<EventID>0</EventID>
</System>
<EventData>
<Data Name="ContainerName">2fb583e6-3769-4465-9de0-ce56a1aa84c4</Data>
<Data Name="RDPSessionID">{24259afa-2028-4206-9856-257ea519bfdd}</Data>
<Data Name="PartA_PrivTags">16777216</Data>
</EventData>
<RenderingInfo Culture="en-US">
<Task>StartRemoteSessionRdpClientBegin</Task>
</RenderingInfo>
</Event>
</Events>
From W3School examples I've looked at, I'd think this should be possible with an XPath query like: /Events/Event[RenderingInfo/Task="StartRemoteSessionRdpClientBegin"].
I've tried this with my XML at https://www.uccollabing.com/free-online-xpath-tester-evaluator-tool/ and it seemed to work there, which makes me suspect an issue with my code. Simple queries work e.g. /Events or /Events/*.
Should my above query work?
HRESULT SearchTraceFile(std::wstring fileName)
{
HRESULT hr = S_OK;
_bstr_t xPath = L"/Events/Event[RenderingInfo/Task=\"StartRemoteSessionRdpClientBegin\"]";
wprintf(L"Query path: %s\n", static_cast<wchar_t*>(xPath));
RETURN_IF_FAILED(CoInitialize(NULL));
wrl::ComPtr<IXMLDOMDocument2> xmlDoc;
RETURN_IF_FAILED(CoCreateInstance(
CLSID_DOMDocument60,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument2, (void**)&xmlDoc));
_variant_t localFileName(fileName.c_str());
VARIANT_BOOL successful = VARIANT_FALSE;
RETURN_IF_FAILED(xmlDoc->load(localFileName, &successful));
RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), (successful != VARIANT_TRUE));
_variant_t varXPath(L"XPath");
xmlDoc->setProperty(L"SelectionLanguage", varXPath);
xmlDoc->setProperty(L"MaxElementDepth", CComVariant(10));
wrl::ComPtr<IXMLDOMNodeList> events;
wrl::ComPtr<IXMLDOMNode> spTaskNode;
hr = xmlDoc->selectSingleNode(xPath, &spTaskNode);
if (FAILED(hr)) return hr;
if (S_FALSE == hr)
{
wprintf(L"Not found\n");
return S_OK;
}
BSTR value = NULL;
hr = spTaskNode->get_text(&value);
if (FAILED(hr)) wprintf(L"get_text failed 0x%08x\n", hr);
else wprintf(L"get_text succedded\n");
wprintf(L"value:\n%s\n", value);
::SysFreeString(value);
return hr;
}
Your XML involves namespaces, so you have to take that into account in your XPath query. This is documented on MSDN:
Specify Namespace when you query the DOM with XPath
For example:
HRESULT SearchTraceFile(std::wstring fileName)
{
_bstr_t xPath = L"/Events/e:Event[e:RenderingInfo/e:Task=\"StartRemoteSessionRdpClientBegin\"]"; // <-- NOTE THE 'e:' PREFIXES!
wprintf(L"Query path: %s\n", static_cast<wchar_t*>(xPath));
RETURN_IF_FAILED(CoInitialize(NULL));
wrl::ComPtr<IXMLDOMDocument2> xmlDoc;
RETURN_IF_FAILED(CoCreateInstance(
CLSID_DOMDocument60,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument2, (void**)&xmlDoc));
_variant_t localFileName(fileName.c_str());
VARIANT_BOOL successful = VARIANT_FALSE;
RETURN_IF_FAILED(xmlDoc->load(localFileName, &successful));
RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), (successful != VARIANT_TRUE));
xmlDoc->setProperty(L"SelectionLanguage", _variant_t(L"XPath"));
xmlDoc->setProperty(L"SelectionNamespaces", _variant_t(L"xmlns:e='http://schemas.microsoft.com/win/2004/08/events/event'")); // <-- ADD THIS!
xmlDoc->setProperty(L"MaxElementDepth", _variant_t(10));
wrl::ComPtr<IXMLDOMNodeList> events;
wrl::ComPtr<IXMLDOMNode> spTaskNode;
HRESULT hr = xmlDoc->selectSingleNode(xPath, &spTaskNode);
if (FAILED(hr)) {
wprintf(L"selectSingleNode failed 0x%08x\n", hr);
return hr;
}
if (S_FALSE == hr)
{
wprintf(L"Not found\n");
return S_OK;
}
_bstr_t value;
hr = spTaskNode->get_text(value.GetAddress());
if (FAILED(hr)) {
wprintf(L"get_text failed 0x%08x\n", hr);
return hr;
}
wprintf(L"get_text succeeded\nvalue:\n%s\n", static_cast<wchar_t*>(value));
return S_OK;
}

COM script activation sometimes fails

I am running com scripts from c++ on windows xp
Usually the script executes without problems, but sometimes the execution fails with hresult DISP_E_MEMBERNOTFOUND. (Invoke is the function that fails)
Does anybody have any idea why it happens?
The code is below
CLSID clsid;
MULTI_QI mqi;
HRESULT hr ;
mqi.hr = 0;
mqi.pIID = &IID_IDispatch;
mqi.pItf = NULL;
hr = CLSIDFromProgID(T2W(progId.c_str()), &clsid);
CHECK_HRESULT(hr);
hr = CoCreateInstanceEx(clsid, NULL, CLSCTX_INPROC_SERVER, NULL, 1, &mqi);
CHECK_HRESULT(hr);
tMethodArguments argTemp(arguments.size()) ;
USES_CONVERSION ;
HRESULT hr;
DISPID index ;
OLECHAR FAR* szMember = T2W(method.c_str());
unsigned int err ;
hr = m_pScriptComObj->GetIDsOfNames( IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, &index ) ;
CHECK_HRESULT(hr);
DISPPARAMS params ;
params.rgvarg = pArgs ;
params.rgdispidNamedArgs = NULL ;
params.cArgs = arguments.size() ;
params.cNamedArgs = 0 ;
EXCEPINFO excep_info;
hr = m_pScriptComObj->Invoke(index,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&params,
&res,
&excep_info,
&err);
I omitted method and arguments initialization
The vbscript that is called by INVOKE looks like this
<?xml version="1.0"?>
<component id="script_wsc_script">
<?component?>
<registration
description="script_wsc_script"
progid="wscScript.WSC"
version="1.00"
classid="{A1C14070-EBAB-41A0-BC9C-B4330A73437D}"
remotable="true"
>
</registration>
<public>
<method name="PrintMessage">
<PARAMETER name="first"/>
<PARAMETER name="second"/>
</method>
</public>
<script language="VBScript">
<![CDATA[
Function PrintMessage ( first, second)
''do something
End Function

MFC Cannot Build Dynamic DLL file

I have problem with MFC DLL. I use Visual Studio 2010.
This is my DLL
#ifdef __cplusplus // If used by C++ code,
extern "C" { // we need to export the C interface
#endif
__declspec(dllexport) void __cdecl GetRAMInfo(DWORD& totaRamlPhysical, DWORD& availablephys, DWORD& memoload)
{
// Lay RAM
MEMORYSTATUS status;
status.dwLength = sizeof(status);
GlobalMemoryStatus( &status ); // lay information of ram
totaRamlPhysical = status.dwTotalPhys; // Tong dung luong RAM vat ly
availablephys = status.dwAvailPhys; // Dung luong RAM vat ly dang duoc su dug
memoload = status.dwMemoryLoad; // phan tram RAM duoc ca he thong su dung
}
__declspec(dllexport) void __cdecl GetCPUInfo(DWORD& processorArchitect, DWORD& typeProcessor, DWORD& numberProcessor)
{
SYSTEM_INFO siSysInfo;
GetSystemInfo(&siSysInfo); // lay thong tin cua CPU
processorArchitect = siSysInfo.wProcessorArchitecture;
numberProcessor = siSysInfo.dwNumberOfProcessors;
typeProcessor = siSysInfo.dwProcessorType;
}
__declspec(dllexport) void __cdecl GetRAMuseandProcessMostUse(CString& namePMU, DWORD& ramUse)
{
//===========NAME PMU ==========//
DWORD sizeallProcess; // Kich thuoc danh sach ID Process thu duoc
DWORD processNumber; // So luong Process thu duoc
DWORD arrayProcessID[100]; // mang chua danh sach ID Process
EnumProcesses( arrayProcessID, sizeof(arrayProcessID), &sizeallProcess ); // lay danh sach process dang chay
processNumber = sizeallProcess / sizeof(DWORD); // Lay so luong Process thu duoc
namePMU = GetProcess(arrayProcessID, processNumber);
///===========RAM USE==============//
DWORD arrayWorkingSetSize[100];
unsigned int i;
ramUse =0;
for( i =0; i < processNumber;i++){
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, arrayProcessID[i] ); // handle toi 1 process
if (hProcess != NULL)
{
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ){ // laays kich thuoc bo nho ma tien trinh do su dung
arrayWorkingSetSize[i] = pmc.WorkingSetSize ;
}
}
CloseHandle( hProcess );
}
for(i =2; i<(processNumber); i++){
if(arrayWorkingSetSize[i] != 3435973836){
ramUse += arrayWorkingSetSize[i];
}
}
}
__declspec(dllexport) void __cdecl GetCPUuseandProcessMostUse(CString& namePMUCPU, DOUBLE& cpuUse)
{
//DWORD processID = 2412;
FILETIME ftSysIdle, ftSysKernel, ftSysUser;
FILETIME ftProcCreation, ftProcExit, ftProcKernel, ftProcUser;
//=== HANDLE of a PROCESS ==///
DWORD sizeallProcess; // Kich thuoc danh sach ID Process thu duoc
DWORD processNumber; // So luong Process thu duoc
DWORD arrayProcessID[100]; // mang chua danh sach ID Process
EnumProcesses( arrayProcessID, sizeof(arrayProcessID), &sizeallProcess ); // lay danh sach process dang chay
processNumber = sizeallProcess / sizeof(DWORD); // Lay so luong Process thu duoc
bool flagFor = FALSE;
ULONGLONG arrayTotalSys[2][100];
ULONGLONG arrayTotalProc[2][100];
DOUBLE arrayPercent[100];
for(unsigned int a = 0; a<2; a++) {
for(unsigned int i=2; i<processNumber; i++) {
if(arrayProcessID[i] !=3435973836){
HANDLE hProcess;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, arrayProcessID[i] );
GetSystemTimes(&ftSysIdle, &ftSysKernel, &ftSysUser);
GetProcessTimes(hProcess, &ftProcCreation, &ftProcExit, &ftProcKernel, &ftProcUser);
arrayTotalSys[a][i] = AddTimes(ftSysKernel, ftSysUser);
arrayTotalProc[a][i] = AddTimes(ftProcKernel, ftProcUser);
}
}
Sleep(500);
}
DOUBLE sumSys =0;
DOUBLE sumProc =0;
for(unsigned int i=2; i<processNumber; i++){
if(arrayProcessID[i] !=3435973836){
/*sumSys += arrayTotalSys[0][i] + arrayTotalSys[1][i];
sumProc += arrayTotalProc[0][i] + arrayTotalProc[1][i];*/
sumSys += arrayTotalSys[1][i] - arrayTotalSys[0][i] ;
sumProc += arrayTotalProc[1][i] - arrayTotalProc[0][i] ;
arrayPercent[i] = (double)((100*sumProc)/sumSys);
}
}
int maxindex = 2;
double processMaxPercent = arrayPercent[2];
double sumpercent =0;
for(unsigned int i =2; i<(processNumber); i++){
if(arrayPercent[i] != 3435973836){
if(processMaxPercent < arrayPercent[i] ){
processMaxPercent = arrayPercent[i];
maxindex = i;
}
sumpercent += arrayPercent[i];
}
}
cpuUse = sumpercent;
namePMUCPU = GetNameProcessMU(arrayProcessID[maxindex]); // tam thoi lay ten mac djnh la cai nay
}
__declspec(dllexport) ULONGLONG __cdecl AddTimes(const FILETIME& ftA,const FILETIME& ftB){
LARGE_INTEGER a, b;
a.LowPart = ftA.dwLowDateTime;
a.HighPart = ftA.dwHighDateTime;
b.LowPart = ftB.dwLowDateTime;
b.HighPart = ftB.dwHighDateTime;
return a.QuadPart + b.QuadPart;
}
__declspec(dllexport) CString __cdecl GetProcess(DWORD arrayProcess[], DWORD numberprocess)
{
// Working set cua cac process
DWORD arrayWorkingSetSize[100];
unsigned int maxindex;
DWORD processMaxSize;
CString nameProcessMaxSize;
unsigned int i;
for( i =0; i < numberprocess;i++){
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, arrayProcess[i] ); // handle toi 1 process
if (hProcess != NULL)
{
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ){ // laays kich thuoc bo nho ma tien trinh do su dung
arrayWorkingSetSize[i] = pmc.WorkingSetSize ;
}
}
CloseHandle( hProcess );
}
// Sap xep, lay ra phan tu co WorkingSetSize lon nhat
maxindex = 2;
processMaxSize = arrayWorkingSetSize[2];
for(i =2; i<(numberprocess - 10); i++){
if(arrayWorkingSetSize[i] != 3435973836){
if(processMaxSize < arrayWorkingSetSize[i] ){
processMaxSize = arrayWorkingSetSize[i];
maxindex = i;
}
}
}
// lay ten process co kich thuoc max
nameProcessMaxSize = GetNameProcessMU(arrayProcess[maxindex]);
return nameProcessMaxSize;
}
__declspec(dllexport) CString __cdecl GetNameProcessMU(DWORD processID)
{
CString nameProcess;
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
// Get the process name.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
}
nameProcess = (LPCTSTR)szProcessName; // chuyen kieu
CloseHandle( hProcess );
return nameProcess;
}
#ifdef __cplusplus
}
#endif
Now when i build it, it show error again and again to notice that it dont know some function.
Error 1 error C3861: 'GetProcess': identifier not found c:\users\anhnt\documents\visual studio 2010\projects\bkav_btap2_dll\bkav_btap2_dll\bkav_btap2_dll.cpp 104 1 Bkav_btap2_dll
Error 2 error C3861: 'AddTimes': identifier not found c:\users\anhnt\documents\visual studio 2010\projects\bkav_btap2_dll\bkav_btap2_dll\bkav_btap2_dll.cpp 154 1 Bkav_btap2_dll
Error 3 error C3861: 'AddTimes': identifier not found c:\users\anhnt\documents\visual studio 2010\projects\bkav_btap2_dll\bkav_btap2_dll\bkav_btap2_dll.cpp 155 1 Bkav_btap2_dll
Error 4 error C3861: 'GetNameProcessMU': identifier not found c:\users\anhnt\documents\visual studio 2010\projects\bkav_btap2_dll\bkav_btap2_dll\bkav_btap2_dll.cpp 187 1 Bkav_btap2_dll
Warning 5 warning C4190: 'GetProcess' has C-linkage specified, but returns UDT 'ATL::CStringT<BaseType,StringTraits>' which is incompatible with C c:\users\anhnt\documents\visual studio 2010\projects\bkav_btap2_dll\bkav_btap2_dll\bkav_btap2_dll.cpp 200 1 Bkav_btap2_dll
Error 6 error C3861: 'GetNameProcessMU': identifier not found c:\users\anhnt\documents\visual studio 2010\projects\bkav_btap2_dll\bkav_btap2_dll\bkav_btap2_dll.cpp 234 1 Bkav_btap2_dll
Warning 7 warning C4190: 'GetNameProcessMU' has C-linkage specified, but returns UDT 'ATL::CStringT<BaseType,StringTraits>' which is incompatible with C c:\users\anhnt\documents\visual studio 2010\projects\bkav_btap2_dll\bkav_btap2_dll\bkav_btap2_dll.cpp 239 1 Bkav_btap2_dll
Please help me :(. Thanksss
P/s: i read this topic(stackoverflow.com/questions/17332327/cannot-build-dll-with-base-class) but it not work for me.
You're missing to include the Header files for the required libaries. Add (at least) the following line to the beginning of your file:
#include <windows.h>
Edit:
If I'm creating a new Visual Studio Project and paste the above code into a new file it successfully builds if I add the following lines to the top of the source file:
#include "stdafx.h" // Contains the afx default header files (which internally reference Windows.h)
#include <Psapi.h> // for process specific stuff
__declspec(dllexport) CString __cdecl GetProcess(DWORD arrayProcess[], DWORD numberprocess);
__declspec(dllexport) ULONGLONG __cdecl AddTimes(const FILETIME& ftA, const FILETIME& ftB);
__declspec(dllexport) CString __cdecl GetNameProcessMU(DWORD processID);
Additionally, psapi.lib must be added as linker input.
I suggest you read up some documentation on building C++ projects, on header files and libraries. You seem to be missing the understanding for some basic concepts of C++.
EDIT 2
The following are now my files, they build fine. (Any missing files are left as-is when using the MFC Project wizard, they're optional)
Stackoverflow.vcproj
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D25D3BF5-42FD-4649-BEE4-A7F142367727}</ProjectGuid>
<RootNamespace>StackOverflow</RootNamespace>
<Keyword>MFCDLLProj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>SYSTEMINFO_LIB;WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>.\StackOverflow.def</ModuleDefinitionFile>
<AdditionalDependencies>psapi.lib</AdditionalDependencies>
</Link>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</Midl>
<ResourceCompile>
<Culture>0x0407</Culture>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>SYSTEMINFO_LIB;WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>.\StackOverflow.def</ModuleDefinitionFile>
</Link>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</Midl>
<ResourceCompile>
<Culture>0x0407</Culture>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
<None Include="res\StackOverflow.rc2" />
<None Include="StackOverflow.def" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="SystemInfo.cpp" />
<ClCompile Include="StackOverflow.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Resource.h" />
<ClInclude Include="StackOverflow.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="SystemInfo.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="StackOverflow.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
Stackoverflow.vcproj.filters
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Quelldateien">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Headerdateien">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Ressourcendateien">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
<None Include="StackOverflow.def">
<Filter>Quelldateien</Filter>
</None>
<None Include="res\StackOverflow.rc2">
<Filter>Ressourcendateien</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClCompile Include="StackOverflow.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="SystemInfo.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="StackOverflow.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="Resource.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="SystemInfo.h">
<Filter>Headerdateien</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="StackOverflow.rc">
<Filter>Ressourcendateien</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
SystemInfo.cpp
#include "stdafx.h"
#include <Psapi.h>
#include "SystemInfo.h"
SYSTEMINFO_EXPORTS void __cdecl GetRAMInfo(DWORD& totaRamlPhysical, DWORD& availablephys, DWORD& memoload)
{
// Lay RAM
MEMORYSTATUS status;
status.dwLength = sizeof(status);
GlobalMemoryStatus( &status ); // lay information of ram
totaRamlPhysical = status.dwTotalPhys; // Tong dung luong RAM vat ly
availablephys = status.dwAvailPhys; // Dung luong RAM vat ly dang duoc su dug
memoload = status.dwMemoryLoad; // phan tram RAM duoc ca he thong su dung
}
SYSTEMINFO_EXPORTS void __cdecl GetCPUInfo(DWORD& processorArchitect, DWORD& typeProcessor, DWORD& numberProcessor)
{
SYSTEM_INFO siSysInfo;
GetSystemInfo(&siSysInfo); // lay thong tin cua CPU
processorArchitect = siSysInfo.wProcessorArchitecture;
numberProcessor = siSysInfo.dwNumberOfProcessors;
typeProcessor = siSysInfo.dwProcessorType;
}
SYSTEMINFO_EXPORTS void __cdecl GetRAMuseandProcessMostUse(CString& namePMU, DWORD& ramUse)
{
//===========NAME PMU ==========//
DWORD sizeallProcess; // Kich thuoc danh sach ID Process thu duoc
DWORD processNumber; // So luong Process thu duoc
DWORD arrayProcessID[100]; // mang chua danh sach ID Process
EnumProcesses( arrayProcessID, sizeof(arrayProcessID), &sizeallProcess ); // lay danh sach process dang chay
processNumber = sizeallProcess / sizeof(DWORD); // Lay so luong Process thu duoc
namePMU = GetProcess(arrayProcessID, processNumber);
///===========RAM USE==============//
DWORD arrayWorkingSetSize[100];
unsigned int i;
ramUse =0;
for( i =0; i < processNumber;i++){
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, arrayProcessID[i] ); // handle toi 1 process
if (hProcess != NULL)
{
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ){ // laays kich thuoc bo nho ma tien trinh do su dung
arrayWorkingSetSize[i] = pmc.WorkingSetSize ;
}
}
CloseHandle( hProcess );
}
for(i =2; i<(processNumber); i++){
if(arrayWorkingSetSize[i] != 3435973836){
ramUse += arrayWorkingSetSize[i];
}
}
}
SYSTEMINFO_EXPORTS void __cdecl GetCPUuseandProcessMostUse(CString& namePMUCPU, DOUBLE& cpuUse)
{
//DWORD processID = 2412;
FILETIME ftSysIdle, ftSysKernel, ftSysUser;
FILETIME ftProcCreation, ftProcExit, ftProcKernel, ftProcUser;
//=== HANDLE of a PROCESS ==///
DWORD sizeallProcess; // Kich thuoc danh sach ID Process thu duoc
DWORD processNumber; // So luong Process thu duoc
DWORD arrayProcessID[100]; // mang chua danh sach ID Process
EnumProcesses( arrayProcessID, sizeof(arrayProcessID), &sizeallProcess ); // lay danh sach process dang chay
processNumber = sizeallProcess / sizeof(DWORD); // Lay so luong Process thu duoc
bool flagFor = FALSE;
ULONGLONG arrayTotalSys[2][100];
ULONGLONG arrayTotalProc[2][100];
DOUBLE arrayPercent[100];
for(unsigned int a = 0; a<2; a++) {
for(unsigned int i=2; i<processNumber; i++) {
if(arrayProcessID[i] !=3435973836){
HANDLE hProcess;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, arrayProcessID[i] );
GetSystemTimes(&ftSysIdle, &ftSysKernel, &ftSysUser);
GetProcessTimes(hProcess, &ftProcCreation, &ftProcExit, &ftProcKernel, &ftProcUser);
arrayTotalSys[a][i] = AddTimes(ftSysKernel, ftSysUser);
arrayTotalProc[a][i] = AddTimes(ftProcKernel, ftProcUser);
}
}
Sleep(500);
}
DOUBLE sumSys =0;
DOUBLE sumProc =0;
for(unsigned int i=2; i<processNumber; i++){
if(arrayProcessID[i] !=3435973836){
/*sumSys += arrayTotalSys[0][i] + arrayTotalSys[1][i];
sumProc += arrayTotalProc[0][i] + arrayTotalProc[1][i];*/
sumSys += arrayTotalSys[1][i] - arrayTotalSys[0][i] ;
sumProc += arrayTotalProc[1][i] - arrayTotalProc[0][i] ;
arrayPercent[i] = (double)((100*sumProc)/sumSys);
}
}
int maxindex = 2;
double processMaxPercent = arrayPercent[2];
double sumpercent =0;
for(unsigned int i =2; i<(processNumber); i++){
if(arrayPercent[i] != 3435973836){
if(processMaxPercent < arrayPercent[i] ){
processMaxPercent = arrayPercent[i];
maxindex = i;
}
sumpercent += arrayPercent[i];
}
}
cpuUse = sumpercent;
namePMUCPU = GetNameProcessMU(arrayProcessID[maxindex]); // tam thoi lay ten mac djnh la cai nay
}
SYSTEMINFO_EXPORTS ULONGLONG __cdecl AddTimes(const FILETIME& ftA,const FILETIME& ftB){
LARGE_INTEGER a, b;
a.LowPart = ftA.dwLowDateTime;
a.HighPart = ftA.dwHighDateTime;
b.LowPart = ftB.dwLowDateTime;
b.HighPart = ftB.dwHighDateTime;
return a.QuadPart + b.QuadPart;
}
SYSTEMINFO_EXPORTS CString __cdecl GetProcess(DWORD arrayProcess[], DWORD numberprocess)
{
// Working set cua cac process
DWORD arrayWorkingSetSize[100];
unsigned int maxindex;
DWORD processMaxSize;
CString nameProcessMaxSize;
unsigned int i;
for( i =0; i < numberprocess;i++){
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, arrayProcess[i] ); // handle toi 1 process
if (hProcess != NULL)
{
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ){ // laays kich thuoc bo nho ma tien trinh do su dung
arrayWorkingSetSize[i] = pmc.WorkingSetSize ;
}
}
CloseHandle( hProcess );
}
// Sap xep, lay ra phan tu co WorkingSetSize lon nhat
maxindex = 2;
processMaxSize = arrayWorkingSetSize[2];
for(i =2; i<(numberprocess - 10); i++){
if(arrayWorkingSetSize[i] != 3435973836){
if(processMaxSize < arrayWorkingSetSize[i] ){
processMaxSize = arrayWorkingSetSize[i];
maxindex = i;
}
}
}
// lay ten process co kich thuoc max
nameProcessMaxSize = GetNameProcessMU(arrayProcess[maxindex]);
return nameProcessMaxSize;
}
SYSTEMINFO_EXPORTS CString __cdecl GetNameProcessMU(DWORD processID)
{
CString nameProcess;
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
// Get the process name.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
}
nameProcess = (LPCTSTR)szProcessName; // chuyen kieu
CloseHandle( hProcess );
return nameProcess;
}
SystemInfo.h
#pragma once
#include <Psapi.h>
SYSTEMINFO_EXPORTS CString __cdecl GetProcess(DWORD arrayProcess[], DWORD numberprocess);
SYSTEMINFO_EXPORTS ULONGLONG __cdecl AddTimes(const FILETIME& ftA, const FILETIME& ftB);
SYSTEMINFO_EXPORTS CString __cdecl GetNameProcessMU(DWORD processID);
and these lines added to stdafx.h:
#ifdef SYSTEMINFO_LIB
#define SYSTEMINFO_EXPORTS __declspec(dllexport)
#else
#define SYSTEMINFO_EXPORTS __declspec(dllimport)
#endif
(Yiack, I hope I'm not breaking any rules by posting this much code here.)

C++ XLST transform not working using MSXML 3.0

I'm new to C++ and inherited the following code that is supposed to transform the given XML using the XSLT file to just spit out the text values.
It loads both the XML and XSLT fine and the transformnode() call returns success but no transformation has been applied. The original output at the bottom contains the original XML intact .
It is using MSXML 3.0. I've used Xselerator to validate that the XSLT is valid and works (i.e. the string "This is a test message.." is returned).
Here is the code (minus all the error handling):
IXMLDOMNode *m_pXslt;
ESSXsltData::Initialise(void)
{
IUnknown *l_pUnknown = NULL;
IXMLDOMDocument *l_pXSLDocument = NULL;
HRESULT hr = CoCreateInstance(__uuidof(DOMDocument), NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID *)&l_pUnknown);
hr = l_pUnknown->QueryInterface(IID_IXMLDOMDocument,(LPVOID *)&l_pXSLDocument);
CString l_sFileName(RetrieveXsltFileName().c_str() );
hr = l_pXSLDocument->load(l_vFileName, &l_bSuccess);
hr = l_pXSLDocument->QueryInterface(IID_IXMLDOMNode, (LPVOID *)(&m_pXslt) );
}
HRESULT ESSXsltData::ApplyXslt(const char *p_pszESSXml, std::vector< std::string > &p_CommentLines)
{
IUnknown *l_pUnknown = NULL;
IXMLDOMDocument *l_pDocument = NULL;
if (p_pszESSXml)
{
VARIANT_BOOL l_bSuccess;
HRESULT hr = CoCreateInstance(__uuidof(DOMDocument), NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID *)&l_pUnknown);
hr = l_pUnknown->QueryInterface(IID_IXMLDOMDocument,(LPVOID *)&l_pDocument);
hr = l_pDocument->loadXML(CComBSTR(p_pszESSXml) , &l_bSuccess);
hr = l_pDocument->QueryInterface(IID_IXMLDOMNode, (LPVOID *)(&m_pXslt) );
BSTR l_bsOutput = NULL;
hr = l_pDocument->transformNode(m_pXslt, &l_bsOutput);
COLE2T l_AsciiOutput(l_bsOutput);
log << "AsciiOutput: " << l_AsciiOutput << "\n";
}
}
The p_pszESSXml string is:
<ESS><Message>This is a test message...</Message></ESS>
The XSLT is:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="text" indent="yes"/>
<xsl:template match="ESS">
<xsl:apply-templates select="Message"/>
</xsl:template>
<xsl:template match="Message">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
Fixed it.
It was reassigning m_pXslt to equal the XML is was supposed to be validating.
Someone has been copying and pasting.