2011年5月30日 星期一

32 bit application Registry location in x64 Windows

For 64 bit application in  64 bit Windows
HKEY_LOCAL_MACHINE\SOFTWARE\

For 32 bit application
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node

To access or store Registry by Win API, the API will redirect to the corresponding  path

Also the uninstall registry of 32 bit application in win64 is located at

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{product GUID}

2011年5月27日 星期五

ModifyMenu, DeleteMenu

CMenu MainMenu;
MainMenu.LoadMenu (IDR_MENU_NOTIFY);

MainMenu.ModifyMenuW(ID_STREAM_RESTART,MF_BYCOMMAND|MF_STRING,ID_STREAM_RESTART,_T("START"));
MainMenu.DeleteMenu(ID_STREAM_CLOSE,MF_BYCOMMAND);

StartService ,StopService

To StartService or StopService, needs to use OpenSCManager and OpenService API to get SC_HANDLE
//============Stop Service============================
#include "Winsvc.h" // to use SC_HANDLE
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (schSCManager==0)
    {
        TRACE(_T("KillService OpenSCManager failed"));
    }
    else
    {
        // open the service
        SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
        if (schService==0)
        {
            TRACE(_T("KillService OpenService failed"));
        }
      

      else
        {
            // call ControlService to kill the given service
            SERVICE_STATUS status;
            if(ControlService(schService, SERVICE_CONTROL_STOP, &status))
            {
                CloseServiceHandle(schService);
                CloseServiceHandle(schSCManager);
                return TRUE;
            }


           else
            {
                TRACE(_T("KillService ControlService failed"));
            }
            CloseServiceHandle(schService);
        }
        CloseServiceHandle(schSCManager);
       
    }
   
   
    return FALSE;

//============Start Service===============

SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (schSCManager==0)
    {
        TRACE(_T("RunService OpenSCManager failed\r\n"));
    }
    else
    {
        // open the service
        SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
        if (schService == 0)
        {
            TRACE(_T("RunService OpenService failed"));
        }
        else
        {
            // call StartService to run the service
            if(StartService(schService, 0, (const TCHAR**)NULL))
            {
                CloseServiceHandle(schService);
                CloseServiceHandle(schSCManager);
                return TRUE;
            }
            else
            {
                TRACE(_T("RunService StartService failed"));
            }
            CloseServiceHandle(schService);
        }
        CloseServiceHandle(schSCManager);
       
    }
   

    return FALSE;

QueryServiceStatus

 利用  OpenSCManager, OpenService 這兩個API可以查詢目前服務執行的狀態。
首先要#include "Winsvc.h" 才能使用SC_HANDLE等structure

bool bQueryResult = true;
 // 利用OpenSCManager API 來得到 SC_HANDLE

SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (schSCManager==0)
    {
        TRACE(_T("RunService OpenSCManager failed\r\n"));
    }
    else
    {
 // open the service SC_HANDLE schService = OpenService( schSCManager,
pServiceName, // 這裡的ServiceName是執行檔的名稱(不含.exe),不是服務的顯示名稱
SERVICE_QUERY_STATUS); // 這裡表示執行查詢狀態

        if (schService == 0)
        {
            TRACE(_T("RunService OpenService failed"));
        }
        else
        {
            SERVICE_STATUS ss; // 宣告一個SERVICE_STATUS structure
            if(QueryServiceStatus(schService, &ss))
            {
                if(ss.dwCurrentState == SERVICE_RUNNING)

                    bQueryResult = true;
                else
                    bQueryResult = false;

            }
           
   
            CloseServiceHandle(schService);
            CloseServiceHandle(schSCManager);
        }

    }
    return bQueryResult;

2011年5月26日 星期四

GetFileVersion

利用GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue這三個API來取得檔案的Version資訊

首先取得執行程式的位置
// get the app path
    TCHAR apppath[MAX_PATH]={0};
    GetModuleFileName(AfxGetInstanceHandle(),apppath,MAX_PATH-1);
    CString csAppPath(apppath);
    int nPos = csAppPath.ReverseFind('\\');
    csAppPath = csAppPath.Left(nPos + 1);
    csAppPath += _T("my.exe");
  
取得版本資訊
  // get version
    DWORD dwLen = 0;
    TCHAR* lpData=NULL;
    BOOL bSuccess = FALSE;
    dwLen = GetFileVersionInfoSize(csAppPath, 0);

   if (0 == dwLen)
    {
      return ;
    }

    lpData =new TCHAR [dwLen+1];

    GetFileVersionInfo(csAppPath, 0, dwLen, lpData);
   
    LPVOID lpBuffer = NULL;
    UINT uLen = 0;

   VerQueryValue(lpData,
              _T("\\StringFileInfo\\040904b0\\FileVersion"),
//040904b0 can be found in resource view->version-> blockheader
             
     /*  properties for query  可以查詢的資訊
    CompanyName
    FileDescription
    FileVersion
    InternalName
    LegalCopyright
    OriginalFilename
    ProductName
    ProductVersion
    Comments
    LegalTrademarks
    PrivateBuild
    SpecialBuild
     */            
              &lpBuffer,
              &uLen);
   
// lpBuffer存有查詢回來的資訊。

   CString csVersion;
   csVersion.Format(_T("%s"),(TCHAR*)lpBuffer);

   m_csVersion += csVersion;
 
delete [] lpData;
// lpBuffer可以不用delete,因為他指向和lpData相同的記憶體空間

2011年5月12日 星期四

[轉錄] Static Class Members may not be Initialized in a Constructor

A common mistake is to initialize static class members inside the constructor body or a member-initialization list like this:
 
class File
{
  private: 
    static bool locked;
  private: 
    File();
  //…
};
File::File(): locked(false) {} //error, static initialization in a member initialization list
Although compilers flag these ill-formed initializations as errors, programmers often wonder why this is an error. Bear in mind that a constructor is called as many times as the number of objects created, whereas a static data member may be initialized only once because it is shared by all the class objects. Therefore, you should initialize static members outside the class, as in this example:
 
class File
{
  private: 
    static bool locked;
  private: 
    File() { /*..*/}
  //…
};

File::locked = false; //correct initialization of a non-const static member
Alternatively, for const static members of an integral type, the Standard now allows in-class initialization:
 
class Screen
{
private:
  const static int pixels = 768*1024; //in-class initialization of const static integral types
public:
  Screen() {/*..*/}
//…
}; 
 
 
原文網址: http://www.devx.com/tips/Tip/13148