Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
Windos
win32.3rdparty
win32.directx.audio
win32.directx.ddk
win32.directx.graphics
win32.directx.input
win32.directx.managed
win32.directx.misc
win32.directx.networking
win32.directx.sdk
win32.directx.video
win32.dirx.grap.shaders
win32.gdi
win32.international
win32.kernel
win32.messaging
win32.mmedia
win32.networks
win32.ole
win32.rtc
win32.tapi
win32.tapi.beta
win32.tools
win32.ui
win32.wince
win32.wmi
windows.mediacenter
winfx.aero
winfx.announcements
winfx.avalon
winfx.collaboration
winfx.fundamentals
winfx.general
winfx.indigo
winfx.sdk
winfx.winfs
  
 
date: Mon, 3 Dec 2007 00:14:11 -0800 (PST),    group: microsoft.public.win32.programmer.tools        back       


Problem with double byte   
Hi All,

The following sample code works well on single byte languages and
prints the list of running processes in the box. But on double byte
languages like chinese, korean etc, it doesn't print the full process
name and it prints partially on a process which have space in the
process name.

// TestApp.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE  1
#endif
#define tmain     wmain
#else
#define tmain     main
#endif



#include <windows.h>
#include <winperf.h>
#include <malloc.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <stdlib.h>


int tmain ()
{
    PDH_STATUS  pdhStatus               = ERROR_SUCCESS;
    LPTSTR      szCounterListBuffer     = NULL;
    DWORD       dwCounterListSize       = 0;
    LPTSTR      szInstanceListBuffer    = NULL;
    DWORD       dwInstanceListSize      = 0;
    LPCSTR      szThisInstance          = NULL;




    // Determine the required buffer size for the data.
    pdhStatus = PdhEnumObjectItems (
        NULL,                   // real time source
        NULL,                   // local machine
        TEXT("Process"),        // object to enumerate
        szCounterListBuffer,    // pass NULL and 0
        &dwCounterListSize,     // to get length required
        szInstanceListBuffer,   // buffer size
        &dwInstanceListSize,    //
        PERF_DETAIL_WIZARD,     // counter detail level
        0);

    if (pdhStatus == PDH_MORE_DATA || pdhStatus == ERROR_SUCCESS)
    {
        // Allocate the buffers and try the call again.
        szCounterListBuffer = (LPTSTR)malloc (
            (dwCounterListSize * sizeof (TCHAR)));
        szInstanceListBuffer = (LPTSTR)malloc (
            (dwInstanceListSize * sizeof (TCHAR)));

        if ((szCounterListBuffer != NULL) &&
            (szInstanceListBuffer != NULL))
        {
            pdhStatus = PdhEnumObjectItems (
                NULL,                 // real time source
                NULL,                 // local machine
                TEXT("Process"),      // object to enumerate
                szCounterListBuffer,  // buffer to receive counter
list
                &dwCounterListSize,
                szInstanceListBuffer, // buffer to receive instance
list
                &dwInstanceListSize,
                PERF_DETAIL_WIZARD,   // counter detail level
                0);

            if (pdhStatus == ERROR_SUCCESS)
            {
                _tprintf (TEXT("\nEnumerating Processes:"));

                // Walk the instance list. The list can contain one
                // or more null-terminated strings. The last string
                // is followed by a second null-terminator.
				szThisInstance = szInstanceListBuffer;
				while(*szThisInstance)
				{
					_tprintf(TEXT("\n%s"),szThisInstance);
					szThisInstance = szThisInstance + _tcslen(szThisInstance) *
sizeof(TCHAR);
					szThisInstance = _tcsinc(szThisInstance);
				}


			}
            else
            {
                _tprintf(TEXT("\nPdhEnumObjectItems failed1 with
%ld."), pdhStatus);
            }
        }
        else
        {
            _tprintf (TEXT("\nUnable to allocate buffers"));
            pdhStatus = ERROR_OUTOFMEMORY;
        }

        if (szCounterListBuffer != NULL)
            free (szCounterListBuffer);

        if (szInstanceListBuffer != NULL)
            free (szInstanceListBuffer);
    }
    else
    {

        //_tprintf(TEXT("\nPdhEnumObjectItems failed2 with %ld."),
pdhStatus);
    }

    return pdhStatus;
}


Please help me to solve the issue.
date: Mon, 3 Dec 2007 00:14:11 -0800 (PST)   author:   unknown

Re: Problem with double byte   
Fixes the thing:
in the while(*szThisInstance) loop change
  szThisInstance = szThisInstance + _tcslen(szThisInstance) * sizeof(TCHAR);
to
  szThisInstance = szThisInstance + _tcslen(szThisInstance);

When you add a number to a pointer, the number is automatically multiplied
with the size of the type.


Other things that you might cleanup:
 - Build your project with UNICODE defined
 - Usually you define both UNICODE and _UNICODE
   http://www.mihai-nita.net/article.php?artID=20060723a
   Defining _UNICODE before including stdafx.h, because stuff
   declared in stdafx.h might be affected
 - No need for tmain, just include <tchar.h> and use _tmain.
 - Change szThisInstance to LPCTSTR
 

-- 
Mihai Nita [Microsoft MVP, Windows - SDK]
http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email
date: Mon, 03 Dec 2007 18:57:39 -0800   author:   Mihai N.

Re: Problem with double byte   
Hi

Thanks for your reply.

Changed the settings and code as you said. The modified code is given
below

// TestApp.cpp : Defines the entry point for the console application.
//


#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE  1
#endif

#include "stdafx.h"
#include <windows.h>
#include <winperf.h>
#include <malloc.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <stdlib.h>



int _tmain()
{
    PDH_STATUS  pdhStatus               = ERROR_SUCCESS;
    LPTSTR      szCounterListBuffer     = NULL;
    DWORD       dwCounterListSize       = 0;
    LPTSTR      szInstanceListBuffer    = NULL;
    DWORD       dwInstanceListSize      = 0;
    LPCTSTR      szThisInstance          = NULL;




    // Determine the required buffer size for the data.
    pdhStatus = PdhEnumObjectItems (
        NULL,                   // real time source
        NULL,                   // local machine
        TEXT("Process"),        // object to enumerate
        szCounterListBuffer,    // pass NULL and 0
        &dwCounterListSize,     // to get length required
        szInstanceListBuffer,   // buffer size
        &dwInstanceListSize,    //
        PERF_DETAIL_WIZARD,     // counter detail level
        0);

    if (pdhStatus == PDH_MORE_DATA || pdhStatus == ERROR_SUCCESS)
    {
        // Allocate the buffers and try the call again.
        szCounterListBuffer = (LPTSTR)malloc (
            (dwCounterListSize * sizeof (TCHAR)));
        szInstanceListBuffer = (LPTSTR)malloc (
            (dwInstanceListSize * sizeof (TCHAR)));

        if ((szCounterListBuffer != NULL) &&
            (szInstanceListBuffer != NULL))
        {
            pdhStatus = PdhEnumObjectItems (
                NULL,                 // real time source
                NULL,                 // local machine
                TEXT("Process"),      // object to enumerate
                szCounterListBuffer,  // buffer to receive counter
list
                &dwCounterListSize,
                szInstanceListBuffer, // buffer to receive instance
list
                &dwInstanceListSize,
                PERF_DETAIL_WIZARD,   // counter detail level
                0);

            if (pdhStatus == ERROR_SUCCESS)
            {

                _tprintf (TEXT("\nEnumerating Processes:"));

                // Walk the instance list. The list can contain one
                // or more null-terminated strings. The last string
                // is followed by a second null-terminator.
				szThisInstance = szInstanceListBuffer;
				while(*szThisInstance)
				{
					_tprintf(TEXT("\n%s"),szThisInstance);
					szThisInstance = szThisInstance + _tcslen(szThisInstance);
					szThisInstance = _tcsinc(szThisInstance);
				}

			}
            else
            {
                _tprintf(TEXT("\nPdhEnumObjectItems failed1 with
%ld."), pdhStatus);
            }
        }
        else
        {
            _tprintf (TEXT("\nUnable to allocate buffers"));
            pdhStatus = ERROR_OUTOFMEMORY;
        }

        if (szCounterListBuffer != NULL)
            free (szCounterListBuffer);

        if (szInstanceListBuffer != NULL)
            free (szInstanceListBuffer);
    }
    else
    {

        //_tprintf(TEXT("\nPdhEnumObjectItems failed2 with %ld."),
pdhStatus);
    }

    return pdhStatus;
}


My project settings under "all configurations" is given below

_UNICODE,UNICODE,WIN32,_CONSOLE

The code compiles and links successfully. But i'm not able to see the
korean process names in the output. Instead, a empty line is coming.

Please help me to solve the issue.









On Dec 4, 10:57 am, "Mihai N."  wrote:
> Fixes the thing:
> in the while(*szThisInstance) loop change
>   szThisInstance = szThisInstance + _tcslen(szThisInstance) * sizeof(TCHAR);
> to
>   szThisInstance = szThisInstance + _tcslen(szThisInstance);
>
> When you add a number to a pointer, the number is automatically multiplied
> with the size of the type.
>
> Other things that you might cleanup:
>  - Build your project with UNICODE defined
>  - Usually you define both UNICODE and _UNICODE
>    http://www.mihai-nita.net/article.php?artID=20060723a
>    Defining _UNICODE before including stdafx.h, because stuff
>    declared in stdafx.h might be affected
>  - No need for tmain, just include <tchar.h> and use _tmain.
>  - Change szThisInstance to LPCTSTR
>
> --
> Mihai Nita [Microsoft MVP, Windows - SDK]http://www.mihai-nita.net
> ------------------------------------------
> Replace _year_ with _ to get the real email
date: Mon, 3 Dec 2007 20:52:04 -0800 (PST)   author:   unknown

Re: Problem with double byte   
> The code compiles and links successfully. But i'm not able to see the
> korean process names in the output. Instead, a empty line is coming.

Is the system code page set to Korean, or just the process name is Korean?
Because the console cannot display all the languages you throw at it,
even if the application is Unicode. It is just a dumb console.

Try replacing
   _tprintf(TEXT("\n%s"),szThisInstance);
with
   MessageBox( NULL, szThisInstance, TEXT("Test"), MB_OK );
If the string in the message box looks ok, then that is the problem.

And there is no real solution.
You just can't display all strings in the console.
Still, Korean will work on a Korean system, Japanese on a Japanese system,
and so on.


-- 
Mihai Nita [Microsoft MVP, Windows - SDK]
http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email
date: Mon, 03 Dec 2007 22:47:50 -0800   author:   Mihai N.

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us