<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>VCL Developer &#187; دلفی</title>
	<atom:link href="http://vcldeveloper.com/tag/%d8%af%d9%84%d9%81%db%8c/feed/" rel="self" type="application/rss+xml" />
	<link>http://vcldeveloper.com</link>
	<description>Ali Keshavarz&#039;s Website</description>
	<lastBuildDate>Fri, 04 Nov 2011 23:40:16 +0000</lastBuildDate>
	<language>fa</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Update 1 for RAD Studio XE2 is available</title>
		<link>http://vcldeveloper.com/news/update-1-for-rad-studio-xe2-is-available/</link>
		<comments>http://vcldeveloper.com/news/update-1-for-rad-studio-xe2-is-available/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 08:08:52 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi XE2]]></category>
		<category><![CDATA[Embarcadero]]></category>
		<category><![CDATA[RAD Studio]]></category>
		<category><![CDATA[RAD Studio XE2]]></category>
		<category><![CDATA[دلفی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=525</guid>
		<description><![CDATA[Today,  just less than a month of releasing the original XE2 product, Embarcadero published the first update of a series of frequent updates for RAD Studio XE2 (including Delphi XE2 and C++ Builder XE2). Update 1 contains 120 bug fixes in FireMonkey, VCL Styles, compiler, and IDE. This update is mandatory for installing the future [...]]]></description>
			<content:encoded><![CDATA[<p>Today,  just less than a month of releasing the original XE2 product, Embarcadero published the first update of a series of frequent updates for RAD Studio XE2 (including Delphi XE2 and C++ Builder XE2). Update 1 contains 120 bug fixes in FireMonkey, VCL Styles, compiler, and IDE. This update is mandatory for installing the future updates. Here is the official announcement: <a href="http://edn.embarcadero.com/article/41650" target="_blank">Update 1 for Delphi XE2, C++Builder XE2 and RAD Studio XE2</a> . Make sure to read Release Notes for Update 1 before installing it, because Update 1 requires a full uninstall of original XE2 installation and is not a simple upgrade. You can also see a list of all bug fixes in this update here: <a href="http://edn.embarcadero.com/article/41649" target="_blank">Delphi XE2 and C++Builder XE2 Update 1 Bug Fix List</a> .</p>
<p>As I checked the bugs list, at least one bug regarding BiDi support (QC # 97965) is fixed in VCL Styles. No other BiDi related bugs are fixed in this update. Embarcadero staff mentioned in Embarcadero newsgroups that the company is planning to release monthly updates for XE2 product, so we should wait to see if any of the BiDi related bugs will be fixed in the coming updates or not.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/news/update-1-for-rad-studio-xe2-is-available/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Enumerating Windows services</title>
		<link>http://vcldeveloper.com/tips-tricks/enumerating-windows-services/</link>
		<comments>http://vcldeveloper.com/tips-tricks/enumerating-windows-services/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 14:30:28 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi XE2]]></category>
		<category><![CDATA[Services]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[دلفی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=504</guid>
		<description><![CDATA[A while ago, I had to enumerate all Windows services for a project. I was browsing the source code today, and thought maybe it would be a good idea to talk about this matter in a blog post, and publish a sample source code to achieve this. The easiest way to enumerate Windows services is [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">A while ago, I had to enumerate all Windows services for a project. I was browsing the source code today, and thought maybe it would be a good idea to talk about this matter in a blog post, and publish a sample source code to achieve this.</p>
<p style="text-align: justify;">The easiest way to enumerate Windows services is using WMI. Of course using WMI requires some basic knowledge of MS COM technology which is tricky, but thanks to the great tool. <a href="http://code.google.com/p/delphi-wmi-class-generator/" target="_blank">Delphi WMI Class Generator</a> by <a href="http://www.theroadtodelphi.wordpress.com/" target="_blank">Rodrigo Ruz</a>, you can have a ready Delphi class for obtaining information about installed services on a Windows machine without even writing a single line of code. All you have to know is that WMI class for Windows services is Win32_Service under root\CIMV2 namespace. Delphi WMI Class Generator will generate a unit named uWin32_Service.pas which contains a class named TWin32_Service. This class returns info about a single service for you. If you need to enumerate all installed services, you need to write a couple of codes to call its GetCollectionCount to retrieve number of available services, and SetCollectionIndex to set current item index for the class. Here is a sample code to retrieve names of all installed services on the local machine using TWin32_Service class:</p>
<pre class="brush: delphi; title: ; notranslate">
var
  i: Integer;
begin
  with TWin32_Service.Create do
  try
    for i := 0 to GetCollectionCount - 1 do
    begin
      Writeln(DisplayName);
      SetCollectionIndex(i);
    end;
  finally
    Free;
  end;
end;
</pre>
<p style="text-align: justify;">However, WMI is slow, and it relays on WMI service. If you need a faster way to enumerate Windows services, or if for whatever reason WMI service is disabled or not working on your target machine; then you have to relay on Windows API. Using Windows API for this purpose is not as easy as using the automatically generated TWin32_Service class. I am not aware of a single Windows API function that can enumerate Windows services for you and give you all the detailed information which WMI returns for each service. You have to call roughly a dozen of API functions to enumerate Windows services and retrieve some nice information for each service.</p>
<p style="text-align: justify;">First you need to open a handle to service manager on the target machine by calling <a href="http://msdn.microsoft.com/en-us/library/ms684323%28v=vs.85%29.aspx" target="_blank">OpenSCManager</a> function, then you should call <a href="http://msdn.microsoft.com/en-us/library/ms682640%28VS.85%29.aspx" target="_blank">EnumServicesStatusEx</a> function to enumerate available services, and retrieve their names and status. If you just need service names and status, you are done, but if you need to retrieve description and configuration for each service too, then you should open a handle for each service using <a href="http://msdn.microsoft.com/en-us/library/ms684330%28v=vs.85%29.aspx" target="_blank">OpenService </a>function by giving it service name which you obtain through EnumServicesStatusEx call , and then call <a href="http://msdn.microsoft.com/en-us/library/ms684932%28v=vs.85%29.aspx" target="_blank">QueryServiceConfig</a> and <a href="http://msdn.microsoft.com/en-us/library/ms684935%28v=vs.85%29.aspx" target="_blank">QueryServiceConfig2</a> functions to get the required configurations. At the end you should make sure you free all the allocated buffers, and close all handles. Delphi installation does not provide header translation for some of these API functions (particularly EnumServicesStatusEx and QueryServiceConfig2), but they are translated and available for Delphi by well-known Project JEDI, and their JEDI Windows API Headers which contain the majority of Windows headers. If you are a Delphi developer and have not heard about them yet (That would be weird!!), you can download the package from <a title="JEDI Windows API Header" href="http://blog.delphi-jedi.net/jedi-api-headers/" target="_blank">this link</a>.</p>
<p style="text-align: justify;">Anyways, in the source code below, I wrapped all of those API calls into a class named TAkServices. This class holds an internal list containing information for each Windows service installed on a given machine. I tested it on both Delphi 2010 (Win32) and Delphi XE2 (Win64):</p>
<p style="text-align: justify;"><span id="more-504"></span></p>
<pre class="brush: delphi; title: ; notranslate">
{*******************************************************************************
/// &lt;author&gt; Ali Keshavarz (vcldeveloper@gmail.com) &lt;/author&gt;
/// &lt;date&gt; 09/13/2011 &lt;/date&gt;
/// &lt;license&gt;
///  This work is licensed under the Creative Commons Attribution 3.0 Unported
///  License. To view a copy of this license, visit
///  http://creativecommons.org/licenses/by/3.0/
///  or send a letter to Creative Commons, 171 Second Street, Suite 300,
///  San Francisco, California, 94105, USA.
/// &lt;/license&gt;
*******************************************************************************}

unit uAkServices;

interface

uses
 Generics.Collections;

type
 /// Service status values; these items are defined in Windows SDK. For more
 /// info refer to MSDN.
 TAkServiceState = (SERVICE_STOPPED          = $۰۰۰۰۰۰۰۱,
 SERVICE_START_PENDING    = $۰۰۰۰۰۰۰۲,
 SERVICE_STOP_PENDING     = $۰۰۰۰۰۰۰۳,
 SERVICE_RUNNING          = $۰۰۰۰۰۰۰۴,
 SERVICE_CONTINUE_PENDING = $00000005,
 SERVICE_PAUSE_PENDING    = $۰۰۰۰۰۰۰۶,
 SERVICE_PAUSED           = $۰۰۰۰۰۰۰۷ );

 /// Service startup mode values; these items are defined in Windows SDK. For
 /// more info refer to MSDN.
 TAkServiceStartMode = (SERVICE_BOOT_START,
 SERVICE_SYSTEM_START,
 SERVICE_AUTO_START,
 SERVICE_DEMAND_START,
 SERVICE_DISABLED );

 /// &lt;summary&gt;
 /// Service information structure. This structure is used by TAkServiceList
 /// class to save info for each individual service.
 /// &lt;/summary&gt;
 TAkServiceInfo = record
 public
 /// A path to service executable file.
 BinaryPath : string;
 /// Current service state.
 CurrentState : TAkServiceState;

 Description : string;
 /// User-friendly name of service
 DisplayName : string;
 /// Service flags. It can be either zero or SERVICE_RUNS_IN_SYSTEM_PROCESS.
 Flags : Integer;
 /// Actual name of service which is also used as service key name in Registry.
 Name : string;
 /// Process identifier for a running service. If the service is not running
 /// or it is running in System process, then ProcessID will be zero.
 ProcessID : Cardinal;
 /// Startup mode of service.
 StartMode : TAkServiceStartMode;
 /// Username by which service logged into system.
 StartName : string;
 end;

 /// Holds a list of TAkServiceInfo reccords as the list of Windows services.
 TAkServiceList = TList&lt;TAkServiceInfo&gt;;

 TAkServiceInfoEnumerator = TEnumerator&lt;TAkServiceInfo&gt;;

 /// &lt;summary&gt;
 /// Provides a list of installed Windows services on a given machine.
 /// &lt;/summary&gt;
 TAkServices = class
 private
 FLastUpdateTime : TDateTime;
 FList : TAkServiceList;
 FMachineName : string;
 function GetCount: Integer;
 function GetItem(Index: Integer): TAkServiceInfo;
 procedure GetServiceConfig(hSCManager: Cardinal; var Service: TAkServiceInfo);
 procedure SetMachineName(const Value: string);
 protected
 procedure InitializeList; virtual;
 procedure InternalRefresh; virtual;
 public
 /// &lt;summary&gt;
 /// Constructor for TAkServices.
 /// &lt;/summary&gt;
 /// &lt;param name=&quot;AMachineName&quot;&gt;
 ///  (in) Name of the machine which its services should be listed. Default = ''
 /// &lt;/param&gt;
 /// &lt;param name=&quot;.&quot;&gt;&lt;/param&gt;
 constructor Create(const AMachineName: string = '');
 destructor Destroy; override;
 function GetEnumerator: TAkServiceInfoEnumerator;
 /// &lt;summary&gt; Updates list of services. &lt;/summary&gt;
 procedure Refresh;
 /// &lt;summary&gt;
 /// Indicates number of services. If the list is not updated yet, it will be
 /// updated first.
 /// &lt;/summary&gt;
 property Count: Integer read GetCount;
 /// &lt;summary&gt;
 /// Returns item at the Index position of the list of services.
 /// If the list is not updated yet, it will be updated first.
 /// &lt;/summary&gt;
 property Item[Index: Integer]: TAkServiceInfo read GetItem; default;
 /// &lt;summary&gt;
 /// Indicates last update time for the list. It will be updated each time
 /// Refresh method is called.
 /// &lt;/summary&gt;
 property LastUpdateTime: TDateTime read FLastUpdateTime;
 /// &lt;summary&gt;Name of the machine which its services should be listed. &lt;/summary&gt;
 property MachineName: string read FMachineName write SetMachineName;
 end;

implementation

uses
 SysUtils,
 Windows,
 JwaWinNT,
 JwaWinType,
 JwaWinSvc,
 JwaWinError;

{ TAkServices }

constructor TAkServices.Create(const AMachineName: string);
begin
 inherited Create;
 FMachineName := AMachineName;
end;

destructor TAkServices.Destroy;
begin
 System.TMonitor.Enter(Self);
 try
 FList.Free;
 FList := nil;
 finally
 System.TMonitor.Exit(Self);
 end;

 inherited;
end;

function TAkServices.GetCount: Integer;
begin
 InitializeList;
 Result := FList.Count;
end;

function TAkServices.GetEnumerator: TAkServiceInfoEnumerator;
begin
 InitializeList;
 Result := FList.GetEnumerator;
end;

function TAkServices.GetItem(Index: Integer): TAkServiceInfo;
begin
 InitializeList;
 Result := FList[Index];
end;

procedure TAkServices.InitializeList;
begin
 if not Assigned(FList) then
 begin
 System.TMonitor.Enter(Self);
 try
 FList := TAkServiceList.Create;
 InternalRefresh;
 finally
 System.TMonitor.Exit(Self);
 end;
 end;
end;

procedure TAkServices.GetServiceConfig(hSCManager: Cardinal; var Service: TAkServiceInfo);
var
 dwBufNeeded: Cardinal;
 dwBufSize: Cardinal;
 hService : Cardinal;

 /// &lt;summary&gt;
 /// Retrieves service binary path, start mode, and user name.
 /// &lt;/summary&gt;
 procedure GetRequiredConfig(var Service: TAkServiceInfo);
 var
 lpServiceConfig : LPQUERY_SERVICE_CONFIG;
 begin
 dwBufSize := 0;
 dwBufNeeded := 0;
 /// Retrieve required buffer size.
 QueryServiceConfig(hService, nil, dwBufSize, dwBufNeeded);
 if GetLastError &lt;&gt; ERROR_INSUFFICIENT_BUFFER then
 RaiseLastOSError;

 /// Alocate enough buffer size.
 dwBufSize := dwBufNeeded;
 lpServiceConfig := AllocMem(dwBufSize);
 try
 /// Get service configuration
 if not QueryServiceConfig(hService, lpServiceConfig, dwBufSize, dwBufNeeded) then
 RaiseLastOSError;

 /// Save configuration data in the record.
 Service.BinaryPath := lpServiceConfig.lpBinaryPathName;
 Service.StartMode := TAkServiceStartMode(lpServiceConfig.dwStartType);
 Service.StartName := lpServiceConfig.lpServiceStartName;
 finally
 FreeMem(lpServiceConfig);
 end;
 end;

 /// &lt;summary&gt;
 /// Retrieves service description.
 /// &lt;/summary&gt;
 procedure GetOptionalConfig(var Service: TAkServiceInfo);
 var
 lpServiceDescBuff : LPSERVICE_DESCRIPTION;
 begin
 dwBufSize := 0;
 dwBufNeeded := 0;
 /// Retrieve required buffer size.
 QueryServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, nil, dwBufSize, dwBufNeeded);
 if GetLastError &lt;&gt; ERROR_INSUFFICIENT_BUFFER then
 RaiseLastOSError;

 /// Alocate enough buffer size.
 dwBufSize := dwBufNeeded;
 lpServiceDescBuff := AllocMem(dwBufSize);
 try
 /// Retrieve service description
 if not QueryServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION,
                            PByte(lpServiceDescBuff), dwBufSize, dwBufNeeded) then
   RaiseLastOSError;
  /// Save service description in the record.
  if Assigned(lpServiceDescBuff.lpDescription) then
   SetString(Service.Description,
             lpServiceDescBuff.lpDescription,
             StrLen(lpServiceDescBuff.lpDescription));
   finally
     FreeMem(lpServiceDescBuff);
   end;
 end;

begin
  Assert(hSCManager &gt; 0, 'Service manager is not initialized.');

  /// Open a service handle to be used by QueryServiceConfig() and QueryServiceConfig2() functions.
  hService := OpenService(hSCManager,PChar(Service.Name),SERVICE_QUERY_CONFIG);
  if hService = 0 then
    RaiseLastOSError;
  try
    GetRequiredConfig(Service);
    GetOptionalConfig(Service);
  finally
    CloseServiceHandle(hService);
  end;
end;

procedure TAkServices.InternalRefresh;
var
  dwBufNeeded: Cardinal;
  dwBufSize: Cardinal;
  dwNumOfServices: ULONG;
  hSCM: SC_HANDLE;
  lpResumeHandle: Cardinal;
  NewItem : TAkServiceInfo;
  pBuf: PBYTE;
  pInfo: LPENUM_SERVICE_STATUS_PROCESS;
  i: Integer;
begin
  Assert(Assigned(FList),'Internal list is not assigned yet!');

  System.TMonitor.Enter(FList);
  try
   dwBufSize := 0;
   dwBufNeeded := 0;
   dwNumOfServices := 0;
   lpResumeHandle := 0;
   FList.Clear;

   /// We need an open service manager handle to be able to enumerate services.
   hSCM := OpenSCManager(PChar(FMachineName), nil,
   SC_MANAGER_ENUMERATE_SERVICE or SC_MANAGER_CONNECT);
   if (hSCM = 0) then
     RaiseLastOSError;

   try
     /// First check how much buffer is needed by passing dwBufSize as zero,
     /// and pBuf as nil.
     EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
                          SERVICE_STATE_ALL, nil, dwBufSize, dwBufNeeded,
                          dwNumOfServices, lpResumeHandle, nil);
     if (dwBufNeeded &lt; 1) then
       RaiseLastOSError;

     /// Alocate enough space for the buffer.
     dwBufSize := dwBufNeeded;
     pBuf := AllocMem(dwBufSize);
     try
       /// Retrieve services list
       if not EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
                                   SERVICE_STATE_ALL, pBuf, dwBufSize, dwBufNeeded,
                                   dwNumOfServices, lpResumeHandle, nil) then
         RaiseLastOSError;

       /// Type casting pBuf to LPENUM_SERVICE_STATUS_PROCESS record is necessary
       ///  so that we can access each service info in the buffer as a record.
       pInfo := LPENUM_SERVICE_STATUS_PROCESS(pBuf);
       /// Write services list
       for i := 0 to dwNumOfServices-1 do
       begin
         NewItem.Name := pInfo.lpServiceName;
         NewItem.DisplayName := pInfo.lpDisplayName;
         NewItem.Flags := pInfo.ServiceStatusProcess.dwServiceFlags;
         NewItem.ProcessID := pInfo.ServiceStatusProcess.dwProcessId;
         NewItem.CurrentState := TAkServiceState(pInfo.ServiceStatusProcess.dwCurrentState);
         GetServiceConfig(hSCM, NewItem);
         FList.Add(NewItem);

         /// Go to next record in the buffer. Compiler will increment pInfo pointer
         ///  according to size LPENUM_SERVICE_STATUS_PROCESS record.
         Inc(pInfo);
       end;
       FLastUpdateTime := Now;
    finally
       FreeMem(pBuf);
    end;
  finally
    CloseServiceHandle(hSCM);
  end;
  finally
     System.TMonitor.Exit(FList);
  end;
end;

procedure TAkServices.Refresh;
begin
 /// If FList is not created yet, InitializeList will create it and calls InternalRefresh
 /// automatically, but if the list is already created, just calling InternalRefresh
 /// is enough.
 if not Assigned(FList) then
 InitializeList
 else
 InternalRefresh;
end;

procedure TAkServices.SetMachineName(const Value: string);
begin
 if not SameText(FMachineName, Value) then
 begin
    FMachineName := Value;
    Refresh;
  end;
end;

end.
</pre>
<p style="text-align: justify;">Here is also a demo Delphi application using TAkServices class to enumerate Windows services on the local machine, and show them in a ListView control. Download link for the source files (including uAkServices.pas and all required JEDI API header translations) is available at the end of this article:</p>
<div id="attachment_507" class="wp-caption aligncenter" style="width: 310px"><a href="/wp-content/uploads/2011/09/WinServicesDemo.png"><img class="size-medium wp-image-507" title="WinServicesDemo" src="http://vcldeveloper.com/wp-content/uploads/2011/09/WinServicesDemo-300x218.png" alt="" width="300" height="218" /></a><p class="wp-caption-text">Demo application in action; enumerating Windows services using Windows API</p></div>
<h3>Download:</h3>
<p class="download"><a href="/downloads/Enum_Win_Services_Demo.zip">Source code plus the demo app</a></p>
<p><strong>P.S.</strong> Oops, it seems my code highlighter is not keen on indentation in longer source codes. If you see the code without proper indentation, you can use <a href="http://pastebin.com/777VN9RU">this pastebin link</a> to see the source formatted properly, or download the source file. I&#8217;m sorry for the inconvenience.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/enumerating-windows-services/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ProcessInfo 1.5 is released with Win64 support</title>
		<link>http://vcldeveloper.com/news/processinfo-1-5-is-released-with-win64-support/</link>
		<comments>http://vcldeveloper.com/news/processinfo-1-5-is-released-with-win64-support/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 22:14:29 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Components]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Freeware]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TAppInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>
		<category><![CDATA[کامپوننت]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=499</guid>
		<description><![CDATA[ProcessInfo 1.5 is released. The changes in this release are: Added support for Win64 and Delphi XE2. Added TProcessItem.CloseProcess method to close a process normally (not forcefully). Added TProcessItem.CurrentProcess property. This property always refers to the current process in the list of running processes. Added PrivateWorkingSetSize property to TProcessItem.MemoryInfo. Added global  ProcessInformation function. This function [...]]]></description>
			<content:encoded><![CDATA[<p>ProcessInfo 1.5 is released. The changes in this release are:</p>
<ul>
<li>Added support for Win64 and Delphi XE2.</li>
<li> Added TProcessItem.CloseProcess method to close a process normally (not forcefully).</li>
<li> Added TProcessItem.CurrentProcess property. This property always refers to the current process in the list of running processes.</li>
<li>Added PrivateWorkingSetSize property to TProcessItem.MemoryInfo.</li>
<li> Added global  ProcessInformation function. This function returns a global instance of TProcessInfo. The instance will be freed when the application is terminating.</li>
<li> Fixed a few minor bugs.</li>
</ul>
<p>To download ProcessInfo 1.5, please go to <a href="/products/products-components/process-info/">ProcessInfo</a> page.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/news/processinfo-1-5-is-released-with-win64-support/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Different function parameter modifiers in Delphi</title>
		<link>http://vcldeveloper.com/articles/different-function-parameter-modifiers-in-delphi/</link>
		<comments>http://vcldeveloper.com/articles/different-function-parameter-modifiers-in-delphi/#comments</comments>
		<pubDate>Sun, 01 Aug 2010 23:45:12 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[const]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[parameter]]></category>
		<category><![CDATA[procedure]]></category>
		<category><![CDATA[دلفی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/tips-tricks/different-function-parameter-modifiers-in-delphi/</guid>
		<description><![CDATA[Recently a friend asked me about constant parameters in Delphi functions, that brought the idea of writing a new post about passing parameters to functions/procedures in Delphi. Parameter modifiers When you call a function or procedure (I am going to refer to both of them as Functions here), you have to somehow pass the required [...]]]></description>
			<content:encoded><![CDATA[<p>Recently a friend asked me about constant parameters in Delphi functions, that brought the idea of writing a new post about passing parameters to functions/procedures in Delphi.</p>
<h2>Parameter modifiers</h2>
<p>When you call a function or procedure (I am going to refer to both of them as Functions here), you have to somehow pass the required input or output parameters to it. Parameters are passed to functions either by value, or by reference.</p>
<p><span style="text-decoration: underline;">Passing by value</span> means, compiler makes a new copy of the original data, and sends it to the function. This way, the function has its own copy of data, and changing value of the parameter inside the function does not affect the original data. This is the default mode when you pass a parameter to a function in Delphi:<span id="more-388"></span></p>
<pre class="brush: delphi; title: ; notranslate">
program Test02;

procedure Foo(Param1: Integer);
begin
  Inc(Param1); //=&gt; Has no effect on MyData.
end;

var
  MyData : Integer;
begin
  MyData := 1;
  Foo(MyData);
  Writeln(MyData); //=&gt; MyData is still 1.
end.
</pre>
<p><span style="text-decoration: underline;">Passing by reference</span> means, compiler only sends a pointer to the function. This pointer refers to the original data, so changing value of the parameter inside the function directly changes the original data. In Delphi such parameters are marked with <strong>var</strong> keyword:</p>
<pre class="brush: delphi; title: ; notranslate">
program Test02;

procedure Foo(Var Param1: Integer);
begin
  Inc(Param1);
end;

var
  MyData : Integer;
begin
  MyData := 1;
  Foo(MyData);
  Writeln(MyData); //=&gt; MyData is 2.
end.
</pre>
<p>These are the two basic ways parameters are passed to functions, but Delphi has still two other modifier keywords for function parameters: <strong>const</strong> and <strong>out</strong>. What are these two used for?</p>
<p>“Const” makes the parameter read-only, so that you cannot change its value inside the function. This lets compiler to generate optimized code when there is no need to alter value of that parameter inside the function.</p>
<pre class="brush: delphi; title: ; notranslate">
procedure Foo(const Param1: Integer);
begin
  Inc(Param1); // =&gt; ERROR! You cannot modify a const parameter.
end;
</pre>
<p>“Out” is similar to “var”, the difference is, when you use “Out” the initial value of the parameter is discarded inside the function, and it does not matter. What matters is the value you assign to that parameter inside your function. “Out” is basically there to support MS COM method declaration in Delphi. You can use it in any function you write, but you will see lots of COM methods having Out parameters in their declaration.</p>
<p>OK, the purpose of Const and Out modifiers are clear, it can be guessed even from their name which represent Constant and Output; but, to which category do they belong?</p>
<h2>Are “Out” and “Const” passed by value or by reference?</h2>
<p>For “out”, as I mentioned above, it acts similar to “var”, so it passes parameters by reference.</p>
<p>How about “Const’? Const acts somehow differently! It passes parameters usually by value, but it passes certain data types by reference too! Which data types are passed by value, and which ones are passed by reference? To clarify this, I wrote a simple program; it shows address of a parameter passed to a function using the default passing (by value), var modifier (by reference), and const modifier. It repeats this for various data types, to show how these modifiers pass different data types to a function. The source code is attached at the end of this post. Here is a screenshot of this sample program:</p>
<p><a href="http://vcldeveloper.com/wp-content/uploads/2010/08/function_param_modifiers.png"><img class="wlDisabledImage" style="margin: 0px auto; display: block; float: none; border-width: 0px;" title="function_param_modifiers" src="http://vcldeveloper.com/wp-content/uploads/2010/08/function_param_modifiers_thumb.png" border="0" alt="function_param_modifiers" width="424" height="407" /></a></p>
<p>For each data type, “Original:” line indicates address of the original data before being passed to the function. “Value:” line indicates address of the parameter passed to the function by value. “Const:” line indicates address of the parameter passed to the function as a constant. And finally, “var:” line indicates address of the parameter passed to the function by reference.</p>
<p>As you can see, for all data types, address of var parameter is the same as address of the original data, and address of value parameter (passed by value) differs from the original data. Therefore, we can conclude passing a parameter by value, always makes a copy of the original data; and passing a parameter with var modifier always refers to the original data, regardless of the data type which is used.</p>
<p>But for constant parameters, we can see that it always passes the parameter by value, except when the parameter is of array type (<em>static arrays and open arrays, not dynamic arrays; dynamic arrays are passed similar to objects</em>), or record type. It means, if you do not specify a modifier for a parameter of type array (<em>not dynamic arrays</em>) or records, then every time your function is called, the whole data inside that array or record will be pushed into stack, and when the execution of your function is over, it is dismissed! On the other hand, when you use Const or Var modifiers, only a pointer to your record or array is passed to the function, so there is no need to copy the whole data of the array or record.</p>
<p>Now you might ask, if the compiler is smart enough to optimize array and record parameters when Var or <strong>Const</strong> modifiers are used, then why doesn’t it use the same optimization for objects, interfaces, strings, or dynamic arrays?! The answer is: Because those are special data types!</p>
<h2>Objects, Interfaces, Strings, and Dynamic Arrays as parameters</h2>
<p>Objects, interfaces, strings, and dynamic arrays are behind the scene just pointers. They do not contain the real data. They are pointers that refer to the real data. That’s why if you call SizeOf() function on a string or object type, even if your string or object contains huge data; the result is always 4 (<em>as long as Delphi compiler is 32-bits</em>)! SizeOf() function only returns the size of that pointer, not size of the data that pointer refers to. Also that is why we have Length() function for getting size of strings and dynamic arrays, and TObject.InstanceSize class method for getting size of an object.</p>
<p>Hence, for data types as objects, interfaces, strings, or dynamic arrays; we can say practically they are always passed by reference, even if no modifier is specified for them. So the code bellow directly affects StringList variable, and there is no local copy of that object inside Foo:</p>
<pre class="brush: delphi; title: ; notranslate">
program Test03

uses Classes;

procedure Foo(Param1: TStrings);
begin
  Param1.Add(‘۱۲۳۴’); //=&gt; This will directly add a new item to StringList.
end;

var
  StringList : TStringList;
begin
  StringList : TStringList.Create;
  try
    Foo(StringList);
    WriteLn(StringList.Text); //=&gt; Writes ‘۱۲۳۴’.
  finally
    StringList.Free;
  end;
end.
</pre>
<p>Using var modifier on objects, interfaces or dynamic arrays is most of the time unnecessary, because the value itself is a reference, so using var means having a reference to another reference!</p>
<p>Also Const modifier has no particular meaning on objects, interfaces or dynamic arrays, because it only locks the pointer behind the scene, not the data structure to which the pointer is referring. So if we change declaration of Foo() in the code above to this:</p>
<pre class="brush: delphi; title: ; notranslate">
procedure Foo(const Param1: TStrings);
</pre>
<p>We will get the same result as the above code.</p>
<p>However, const and var modifiers have meaning for string types! This is because strings are a special auto-managed data types in Delphi.</p>
<h3>Strings, Dynamic Arrays, and Interfaces are referenced counted:</h3>
<p>Strings and dynamic arrays are both reference-counted. Interfaces in Delphi also provide reference-counting support). Reference-counted types are automatically handled by Delphi runtime. When you define a string variable in Delphi and assign it a value, you will have a data structure containing your text, and a reference-counter value which is set to 1:</p>
<pre class="brush: delphi; title: ; notranslate">
var
 A : string;
begin
  A := ‘Test’; // Memory is allocated for A
                  // on the heap, and reference
                  // counter is set to 1.
end;
</pre>
<p>Now if you change the above code to this:</p>
<pre class="brush: delphi; title: ; notranslate">
var
  A, B : string;
begin
  A := ‘Test’; // Memory is allocated for A
                  // on the heap, and reference
                  // counter is set to 1.
  B := A;      // Reference count for the data
                 // structure referred by A is incremented to 2.
end;
</pre>
<p>Value of A is not copied to B, instead of that, B refers to the same data structure as A, and reference counter of that data structure is set to 2. As soon as any of those variables goes out of scope, reference counter of that data structure would be decremented, and when reference counter reaches down to zero, the data structure would be automatically freed. This mechanism is the same for strings and dynamic arrays. For interfaces, the class which implements the interface should implement three methods defined inside IInterface to provide reference-counting support.</p>
<h3>Strings use Copy-On-Write technique:</h3>
<p>The biggest reason why Const and Var modifiers are meaningful to string types is their copy-on-write feature. To explain this, I had to explain reference-counting in brief. Now please take a look at this example:</p>
<pre class="brush: delphi; title: ; notranslate">
var
  A, B : string;
begin
  A := ‘Test’; // Memory is allocated for A
                  // on the heap, and reference
                  // counter is set to 1.
  B := A;      // Reference count for the data
                 // structure referred by A is incremented to 2.
  B := B + ‘er’;   // B = Tester , A = Test
end;
</pre>
<p>This is the same as the previous sample code, with one extra line. In the last line, we add ‘er’ to variable B. That will result in B referring to “Tester”, not “Test” anymore. How is it done? A and B were both referring to a data structure containing “Test”. Then we decided to modify B. Delphi runtime assigns a new data structure, and copies the string “Test” and the string “er” to it. It also decrements reference-counter of original “Test”, and changes B to refer to the new data structure. It also increments reference-counter of the new data structure. So at the end, we have A which refers to the old data structure, and B which refers to the new data structure. Reference-counters of both data structures are 1 now.</p>
<p>This is called <strong>copy-on-write</strong>; as long as there is no modification, there is no need to do the costly copy operation and waste the memory. Delphi waits until a modification is requested, at that time, it does the actual copy operation.</p>
<p>Please take note, this mechanism <span style="text-decoration: underline;">does not</span> exist for dynamic arrays, so if A and B in the code above were dynamic arrays, changing B would have affected A too.</p>
<h3>So, how does a string parameter work?</h3>
<p>When a string parameter is defined with no modifier, it is sent to the function as a reference to the actual data, but its reference-counter would be incremented when entering the function, and decremented when exiting the function. If a modification is done on the string parameter, then a new local string variable would be created inside the function, and the original value of the parameter would be copied to it (Copy-on-write operation). The change would be reflected on the local string variable. This local string variable would be released when execution of the function is over.</p>
<p>When a string parameter is defined as a constant, compiler is sure that the string cannot be modified inside the function, therefore, there is no need for it to add codes for automatic incrementing and decrementing of the reference-counter.</p>
<p>When a string parameter is defined with var modifier, then it is sent to the function as a reference to the actual data. When value of the parameter is changed, then the original data would be copied to a new memory location, and the modification would be applied to it in the new memory location:</p>
<pre class="brush: delphi; title: ; notranslate">
program Test04;

procedure Test(var Param: string);
begin
  Param := Param + Param;
end;

var
  A, B : string;
begin
  A := 'Test';
  B := A;
  Test(A);
  Writeln(A); //=&gt; A is modifed and is now “TestTest”
  Writeln(B); //=&gt; B still refers to “Test”
end.
</pre>
<p>Now back to the original question:</p>
<h2>When should we use Const modifier for parameters?</h2>
<ol>
<li>
<div>Whenever you have a parameter of type array or record, and you do not need to modify it inside your function; define it as a constant parameter to prevent expensive copy operation of array elements every time your function is called.</div>
</li>
<li>
<div>Whenever you have a parameter of type string or dynamic array, and you do not need to modify it inside your function, define it as a constant parameter to prevent compiler from generating protecting code to keep track of the reference-counter. When you do not use const modifier in such cases, compiler would add a hidden try-finally block to your function which contains code for keeping track of reference-counter for your string or dynamic array parameter. This would affect performance of your code. To read more about the impact of this, and see how much code compiler would produce in that case, you can read Eric Grange’s <a href="http://delphitools.info/2010/07/28/all-hail-the-const-parameters/" target="_blank">post on this</a>.</div>
</li>
</ol>
<p><strong><span style="text-decoration: underline;">Important Note:</span></strong> For the second recommendation above to work, you have to set “String format checking” in your project option to False. This option adds that protective try-finally block to your functions whether you define your string or dynamic array as const or not! This is for backward compatibility with some old C++ Builder codes. If you are not a C++ Builder developer, or are a C++ Builder developer, but do not have such old codes, then you MUST set this option to False in your projects. It reduces performance of strings in Delphi.</p>
<p style="text-align: center;"><a href="http://vcldeveloper.com/wp-content/uploads/2010/08/delphi_string_format_checking.png"><img class="wlDisabledImage aligncenter" style="margin: 0px 12px 0px 0px; display: inline; border-width: 0px;" title="delphi_string_format_checking" src="http://vcldeveloper.com/wp-content/uploads/2010/08/delphi_string_format_checking_thumb.png" border="0" alt="delphi_string_format_checking" width="354" height="269" /></a></p>
<p>OK, I hope this post is clarifying function parameter modifiers and their effects in Delphi programming; specially answering the question of when to use Const modifier. You can download source code and binary file of Function Parameters Type Demo<a href="/downloads/Function_Parameters_Type.zip"> from here</a>.</p>
<p>Have Fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/articles/different-function-parameter-modifiers-in-delphi/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>ProcessInfo 1.3 is released</title>
		<link>http://vcldeveloper.com/news/processinfo-1-3-is-released/</link>
		<comments>http://vcldeveloper.com/news/processinfo-1-3-is-released/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 00:20:25 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Components]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TAppInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>
		<category><![CDATA[کامپوننت]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=370</guid>
		<description><![CDATA[Hi, ProcessInfo 1.3 is released. The changes in this release are: CPU usage is added to TProcessItem. Is64Bit is added to TProcessItem. IsAccessible is added to TProcessItem. Setting thread priority is added to TThreadItem. Setting process base priority class is added to TProcessItem. To download ProcessInfo 1.3, please go to ProcessInfo page.]]></description>
			<content:encoded><![CDATA[<p>Hi,</p>
<p>ProcessInfo 1.3 is released. The changes in this release are:</p>
<ul>
<li>CPU usage is added to TProcessItem.</li>
<li> Is64Bit is added to TProcessItem.</li>
<li> IsAccessible is added to TProcessItem.</li>
<li> Setting thread priority is added to TThreadItem.</li>
<li> Setting process base priority class is added to TProcessItem.</li>
</ul>
<p>To download ProcessInfo 1.3, please go to <a href="/products/products-components/process-info/">ProcessInfo</a> page.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/news/processinfo-1-3-is-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to use TProcessInfo #2</title>
		<link>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo-2/</link>
		<comments>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo-2/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 23:51:07 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=371</guid>
		<description><![CDATA[I had a few e-mails and comments about using TProcessInfo, so I decided to answer those questions in new blog posts. Q1: How can we find a module which is running a specific thread, giving a thread ID: A: First of all, Threads are not assigned to modules, they are assigned to processes. You can [...]]]></description>
			<content:encoded><![CDATA[<p>I had a few e-mails and comments about using <a href="http://vcldeveloper.com/products/products-components/process-info/" target="_blank">TProcessInfo</a>, so I decided to answer those questions in new blog posts.</p>
<p><strong><span style="color: #ff0000;">Q1</span></strong>: How can we find a module which is running a specific thread, giving a thread ID:</p>
<p><strong>A</strong>: First of all, <span style="text-decoration: underline;">Threads are not assigned to modules</span>, they are assigned to processes. You can find a process which is running the thread, by searching in the list of threads owned by each running process. Here is a sample code:</p>
<pre class="brush: delphi; title: ; notranslate">
function FindProcessByThreadID(ID: Cardinal): TProcessItem;
var
  ProcessInfo : TProcessInfo;
  AProcess : TProcessItem;
begin
  Result := nil;
  ProcessInfo := TProcessInfo.Create(nil);
  try
    for AProcess in ProcessInfo.RunningProcesses do
    begin
      if Assigned(AProcess.Threads.FindByID(ID)) then
      begin
        Result := AProcess;
        Exit;
      end;
    end;
  finally
    ProcessInfo.Free;
  end;
end;
</pre>
<p>FindProcessByThreadID iterates over all running processes, and checks which of them has a thread with the given ID. If a process owns a thread with that ID, it will return that process as a TProcessItem object.</p>
<p>Once you have the process object, you can get more information about the process or the specific thread, or you can kill the process, or suspend the thread. For example:</p>
<pre class="brush: delphi; title: ; notranslate">
var
  Process : TProcessItem;
begin
  Process := FindProcessByThreadID(StrToInt(3444));
  if Assigned(Process) then
    ShowMessage(Process.FullPath);
end;
</pre>
<p>The above code looks for a thread with its ID = 3444, and if it is found, it provides full path of the EXE file for that process.</p>
<p><strong><span style="color: #ff0000;">Q2</span></strong>: How can we get memory consumption for a given process?</p>
<p><strong>A</strong>: You can read memory info for a given process using TProcessItem.MemoryInfo. It provides different info about the memory the process is consuming. Here is an example for reading memory info of Google Chrome process while it is running :</p>
<pre class="brush: delphi; title: ; notranslate">
var
  ProcessInfo : TProcessInfo;
  AProcess : TProcessItem;
begin
  ProcessInfo := TProcessInfo.Create(nil);
  try
    AProcess := ProcessInfo.RunningProcesses.FindByName('Chrome.exe');
    if Assigned(AProcess) then
      ShowMessage(Format('WorkingSet Size = %d, Peak WorkingSet Size = %d',
                         [AProcess.MemoryInfo.WorkingSetSize,
                          AProcess.MemoryInfo.PeakWorkingSetSize]));
  finally
    ProcessInfo.Free;
  end;
end;
</pre>
<p>First we search for Chrome.exe process among running processes. Once the process is found, we read its current working set size, and pick working set size through MemoryInfo property, and show them in a message box. The values returned are in Bytes.</p>
<p><strong><span style="color: #ff0000;">Q3</span></strong>: How can we get process base priority class or change it?</p>
<p><strong>A</strong>: You can access base priority class for a given process or modify it (added in <a href="http://vcldeveloper.com/uncategorized/processinfo-1-3-is-released/" target="_blank">version 1.3</a>), using TProcessItem.</p>
<p>PriorityClassBase. Be careful, adjusting a base priority class of a given process inappropriately might make other processes unresponsive! Here is a example code:</p>
<pre class="brush: delphi; title: ; notranslate">
var
  ProcessInfo : TProcessInfo;
  AProcess : TProcessItem;
begin
  ProcessInfo := TProcessInfo.Create(nil);
  try
    AProcess := ProcessInfo.RunningProcesses.FindByName('firefox.exe');
    if Assigned(AProcess) then
      AProcess.PriorityClassBase := BELOW_NORMAL_PRIORITY_CLASS;
  finally
    ProcessInfo.Free;
  end;
end;
</pre>
<p>You can also change each priority of  each thread within a process by setting BasePriority property of that TThreadItem instace.</p>
<p><strong><span style="color: #ff0000;">Q4</span></strong>: How can I check if a process is 64-bit?</p>
<p><strong>A</strong>: You can check this by reading TProcessItem.Is64Bits property.</p>
<p><strong><span style="color: #ff0000;">Q5</span></strong>: How can I get CPU usage for a given process?</p>
<p><strong>A</strong>: You can get CPU usage by reading TProcessItem.CPUUsage property.</p>
<p>I hope these few answers and sample source codes can help you use Process Info. For other examples of using Process Info, please refer to this post: <a href="http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo/">How to use TProcessInfo</a></p>
<p>If there is any question regarding using Process Info, or anything about Delphi that you think worth being mentioned in Tips &amp; Tricks section of this website, please <a href="http://vcldeveloper.com/contact-me/" target="_blank">contact me</a>, and let me know about it.</p>
<p>Have Fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ProcessInfo 1.2 is released</title>
		<link>http://vcldeveloper.com/news/processinfo-1-2-is-released/</link>
		<comments>http://vcldeveloper.com/news/processinfo-1-2-is-released/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 18:45:31 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Components]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TAppInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>
		<category><![CDATA[کامپوننت]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=250</guid>
		<description><![CDATA[Hi, ProcessInfo 1.2 is released. The changes in this release are: SuspendThread, ResumeThread, TerminateThread methods are added to TThreadItem class. Now you can pause/resume/terminate any running thread in a given process. TProcessInfo.Active and TAppInfo.Active are published properties, and can be set in design mode. TProcessInfo.RunningProcesses and TAppInfo.RunningApplications automatically populate the corresponding list if UpdateList method [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Hi,</p>
<p style="text-align: justify;">ProcessInfo 1.2 is released. The changes in this release are:</p>
<ul style="text-align: justify;">
<li>SuspendThread, ResumeThread, TerminateThread methods are added to TThreadItem class. Now you can pause/resume/terminate any running thread in a given process.</li>
<li>TProcessInfo.Active and TAppInfo.Active are published properties, and can be set in design mode.</li>
<li>TProcessInfo.RunningProcesses and TAppInfo.RunningApplications automatically populate the corresponding list if UpdateList method is not called yet. This means even if you don&#8217;t activate any of these two components, or call their UpdateList method, accessing RunningProcesses or RunningApplications does not cause Access Violation.</li>
</ul>
<p style="text-align: justify;">To download ProcessInfo 1.2, please go to <a href="../products/products-components/process-info/">ProcessInfo</a> page.</p>
<p style="text-align: justify;">Regards.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/news/processinfo-1-2-is-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Component Toolbar slows down RAD Studio 2010</title>
		<link>http://vcldeveloper.com/tips-tricks/component-toolbar-slows-down-rad-studio-2010/</link>
		<comments>http://vcldeveloper.com/tips-tricks/component-toolbar-slows-down-rad-studio-2010/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 19:04:01 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Component Toolbar]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi 2010]]></category>
		<category><![CDATA[RAD Studio 2010]]></category>
		<category><![CDATA[دلفی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=237</guid>
		<description><![CDATA[In RAD Studio 2010 there is a new IDE feature called Component Toolbar. This feature provides a component palette similar to the old Delphi component palette. Component Toolbar in RAD Studio 2010 This toolbar provides a nice search box which is able to filter components in the palette based on the search phrase. This toolbar [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">In <a title="RAD Studio 2010" href="http://www.embarcadero.com/products/rad-studio" target="_blank">RAD Studio 2010</a> there is a new IDE feature called Component Toolbar. This feature provides a component palette similar to the old Delphi component palette.</p>
<p style="text-align: justify;">
<div class="mceTemp" style="text-align: justify;">
<dl id="attachment_241" class="wp-caption alignnone" style="width: 540px;">
<dt class="wp-caption-dt"><a href="http://vcldeveloper.com/wp-content/uploads/2010/01/component_toolbar.png"><img class="size-full wp-image-241 " title="Component Toolbar" src="http://vcldeveloper.com/wp-content/uploads/2010/01/component_toolbar.png" alt="Component Toolbar" width="530" height="55" /></a></dt>
<dd class="wp-caption-dd">Component Toolbar in RAD Studio 2010</dd>
</dl>
</div>
<p style="text-align: justify;">
<p style="text-align: justify;">This toolbar provides a nice search box which is able to filter components in the palette based on the search phrase. This toolbar is disabled by default, and is shown when Classic Layout is selected. Here you can see a snapshot of Classic Layout in RAD Studio 2010:</p>
<p style="text-align: justify;">
<div class="mceTemp" style="text-align: justify;">
<dl id="attachment_242" class="wp-caption alignnone" style="width: 630px;">
<dt class="wp-caption-dt"><a href="http://vcldeveloper.com/wp-content/uploads/2010/01/classic_ide_delphi2010.png"><img class="size-full wp-image-242  " title="classic_ide_delphi2010" src="http://vcldeveloper.com/wp-content/uploads/2010/01/classic_ide_delphi2010.png" alt="" width="620" height="323" /></a></dt>
<dd class="wp-caption-dd">Classic Layout in Delphi 2010</dd>
</dl>
</div>
<p style="text-align: justify;">
<p style="text-align: justify;">A few weeks ago while I was working with Delphi 2010, I noticed a delay when switching from code view to form designer. The delay was there not only in the complex forms, but also in simple empty forms! It was not a big delay (about 1 second), but since I had to switch between code and form designer view many times, it was really annoying, so I decided to investigate it and find out what is causing this delay.</p>
<p style="text-align: justify;"><span id="more-237"></span>At first I got suspected to <a title="CnPack" href="http://www.cnpack.org/" target="_blank">CnPack</a> toolbars in form designer and code view, so I disabled them, but it had no effect on the delay!  Then I went for <a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx" target="_blank">SysInternals Process Monitor</a> to monitor RAD Studio while switching from code view to form designer. There were many Registry activities regarding to component toolbar. At that time I was thinking about standard Tool Palette in RAD Studio 2010, not the classic component toolbar, because I was not using classic layout.</p>
<p style="text-align: justify;">I tried to hide Tool Palette to see if it fixes the delay, but it didn&#8217;t! So I decided to disable its IDE package and see if it fixes the issue. While I was looking into the list of IDE packages in Registry, I found Component Toolbar Package, and I thought this is the package corresponding to Tool Palette. So I removed it from the list of known IDE packages, and restarted RAD Studio 2010; the Tool Palette was still there, BUT the switching delay was gone!</p>
<p style="text-align: justify;">I was wondering if Component Toolbar was not related</p>
<p style="text-align: justify;">to Tool Palette, then what was it related to?! Suddenly I remembered the new classic component toolbar, and switched to Classic Layout. Yes, it was the new classic component toolbar which was using Component Toolbar Package!</p>
<p style="text-align: justify;">Since I don&#8217;t use classic view, I simply disabled this IDE package to have a faster switch time from code view to form designer. But still it is weird why this toolbar is being update even when it is not being visible, and why it is making switching from code view to form designer slower. This is definitely a bug in RAD Studio 2010.</p>
<h2 style="text-align: justify;">How to disable an IDE package:</h2>
<p style="text-align: justify;">Here is how you can disable Component Toolbar Package from Registry:</p>
<p style="text-align: justify;">1- Go to<strong> HKEY_CURRENT_USER\Software\CodeGear\BDS\7.0\Known IDE Packages</strong>.</p>
<p style="text-align: justify;">2- Make a backup by right-clicking on &#8220;Known IDE Packages&#8221; key, and selecting  Export.</p>
<p style="text-align: justify;">3- Find &#8220;<span style="text-decoration: underline;">$(BDS)\bin\comptoolbar140.bpl</span>&#8221; value in &#8220;Known IDE Packages&#8221; key, and delete it.</p>
<p style="text-align: justify;">4- Run RAD Studio 2010.</p>
<p style="text-align: justify;">Regards</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/component-toolbar-slows-down-rad-studio-2010/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ProcessInfo 1.1 is released</title>
		<link>http://vcldeveloper.com/news/processinfo-1-1-is-released/</link>
		<comments>http://vcldeveloper.com/news/processinfo-1-1-is-released/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 05:45:15 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Components]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TAppInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>
		<category><![CDATA[کامپوننت]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=202</guid>
		<description><![CDATA[Hi, I released a new version of ProcessInfo. In this release I added these features: Enumerators are added for Windows, Threads, Modules, and Processes; Now you can use for-in statements in D2007 and above for iterating on running processes list, or modules\threads\windows of a given process. TProcessItem.UserName is added; This property returns domain name\user name [...]]]></description>
			<content:encoded><![CDATA[<p>Hi,</p>
<p>I released a new version of ProcessInfo. In this release I added these features:</p>
<ul>
<li> Enumerators are added for Windows, Threads, Modules, and Processes; Now you can use for-in statements in D2007 and above for iterating on running processes list, or modules\threads\windows of a given process.</li>
<li> TProcessItem.UserName is added; This property returns domain name\user name which is running the process.</li>
<li> TProocessInfo.AdjustDebugPrivilage is added; This method is called automatically.<br />
TThreadItem.ToString &amp; TProcessItem.ToString are added; TThreadItem.ToString returns ThreadID. TProcess.ToString returns process EXE name.</li>
<li> Now supports Delphi 7,2007,2009, 2010; Some conditional compiler directives are added so that it can be used in D7, 2007, 2009, and 2010. I tested it in D7, 2009, and 2010. It should work in D2007 too.</li>
</ul>
<p>To download ProcessInfo 1.1, please go to <a href="../products/products-components/process-info/">ProcessInfo</a> page.</p>
<p>Regards.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/news/processinfo-1-1-is-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to use TProcessInfo</title>
		<link>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo/</link>
		<comments>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 14:08:29 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Process Info]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=173</guid>
		<description><![CDATA[The other day I published Process Info component pack which contains TProcessInfo and TAppInfo. A sample task manager was also published as demo. I thought maybe it is a good idea to talk about these components and some of their usages by providing some sample source codes. So I will start with TProcessInfo. Updating running [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I published <a href="http://vcldeveloper.com/products/products-components/process-info/" target="_blank">Process Info component</a> pack which contains TProcessInfo and TAppInfo. A sample task manager was also published as <a title="Download ProcessInfo + Demo" href="http://vcldeveloper.com/downloads/ProcessInfo.zip" target="_blank">demo</a>.</p>
<p>I thought maybe it is a good idea to talk about these components and some of their usages by providing some sample source codes. So I will start with TProcessInfo.</p>
<p><span id="more-173"></span></p>
<h3>Updating running processes list automatically</h3>
<p>TProcessInfo has an internal timer which can update processes list automatically. This timer is controlled by Active, and UpdateInterval properties. Active activates the internal timer, and UpdateInterval specifies update interval. The default value for UpdateInterval is 1000 (1 second).</p>
<p>To update the list manually, and not using the internal timer, you can call UpdateList method.</p>
<h3>OnBeforeUpdate and OnAfterUpdate</h3>
<p>TProcessInfo has two events. They both are invoked when UpdateList is called, either automatically by internal timer or manually by the programmer.</p>
<p>OnBeforeUpdate is invoked just before updating the list. It has a Cancel parameter which lets you to cancel updating. OnAfterUpdate is invoked when the list is updated. So if you have a control (e.g. a list view) that should show processes list, you can write its updating code in the event-handler of OnAfterUpdate.</p>
<h3>Finding a running process</h3>
<p>You can iterate over all running processes to find a specific process with specific characteristics, or use FindByID, and FindByName methods to find a process by its Process ID or Process Name:</p>
<pre class="brush: delphi; title: ; notranslate">
var
  Process : TProcessItem;
begin
  Process := ProcessInfo1.RunningProcesses.FindByID(1234);
  if not Assigned(Process) then
    ShowMessage('No process found');
end;
</pre>
<p>Finding a process by its Process ID.</p>
<pre class="brush: delphi; title: ; notranslate">
var
  Process : TProcessItem;
begin
  Process := ProcessInfo1.RunningProcesses.FindByName('Project3.exe');
  if not Assigned(Process) then
    ShowMessage('No process found');
end;
</pre>
<p>Finding a process by its Process Name.</p>
<pre class="brush: delphi; title: ; notranslate">
var
  I: Integer;
  MemSize,
  MaxMemSize : Cardinal;
  ProcessName : string;
begin
  MaxMemSize := 0;
  for I := 0 to ProcessInfo1.RunningProcesses.Count - 1 do
  begin
    MemSize := ProcessInfo1.RunningProcesses[i].MemoryInfo.WorkingSetSize;
    if MemSize &gt; MaxMemSize then
    begin
      MaxMemSize := MemSize;
      ProcessName := ProcessInfo1.RunningProcesses[i].ExeFile;
    end;
  end;
  ShowMessage(ProcessName + ‘uses more memory than other processes.’);
end; </pre>
<p>Finding the process which consumes more memory than others.</p>
<h3>Terminating a running process</h3>
<p>To terminate a running process, you should first find it in the list of running processes, and then call its TerminateProcess method:</p>
<pre class="brush: delphi; title: ; notranslate"> var
  Process : TProcessItem;
begin
  Process := ProcessInfo1.RunningProcesses.FindByName('notepad.exe');
  if Assigned(Process) then
    Process.TerminateProcess;
end;
</pre>
<h3>Retrieving full path of a process</h3>
<pre class="brush: delphi; title: ; notranslate"> var
  Process : TProcessItem;
begin
  Process := ProcessInfo1.RunningProcesses.FindByName('notepad.exe');
  if Assigned(Process) then
    ShowMessage(Process.FullPath);
end;
</pre>
<h3>Listing modules which a process loaded</h3>
<pre class="brush: delphi; title: ; notranslate"> var
  Process : TProcessItem;
  I: Integer;
begin
  Process := ProcessInfo1.RunningProcesses.FindByName('Project1.exe');
  if  Assigned(Process) then
  begin
    for I := 0 to Process.Modules.Count - 1 do
      Memo1.Lines.Add(Format('%d  : %s',[Process.Modules[i].BaseAddress,
                                         Process.Modules[i].ModuleName]));
  end;
end;
</pre>
<p>You can access other information about a process (e.g. Threads list, threads count, memory consumption, and so on) in the same way.<br />
TAppInfo works very similar to TProcessInfo. I will try to explain it more with some examples in another article.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 1/45 queries in 0.208 seconds using disk: basic
Object Caching 1223/1318 objects using disk: basic

Served from: vcldeveloper.com @ 2012-02-04 21:22:50 -->
