<?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>JEDI Windows API &#187; HowTo</title>
	<atom:link href="http://blog.delphi-jedi.net/tag/howto/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.delphi-jedi.net</link>
	<description>Joint Endeavor of Delphi Innovators of Windows Programming</description>
	<lastBuildDate>Wed, 19 Oct 2011 18:52:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>How to Run the OnScreenKeyboard</title>
		<link>http://blog.delphi-jedi.net/2010/11/29/how-to-run-the-onscreenkeyboard/</link>
		<comments>http://blog.delphi-jedi.net/2010/11/29/how-to-run-the-onscreenkeyboard/#comments</comments>
		<pubDate>Mon, 29 Nov 2010 14:30:48 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[DLL]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=899</guid>
		<description><![CDATA[There are lots of questions on the Internt how to run the OnScreen Keyboard on a Windows 64 System from a 32bit Process. Some time ago, I investigated it but due to a lack of time I didn&#8217;t finish it. Today, I want to you show the solution of this problem. From a 32Bit application, [...]]]></description>
			<content:encoded><![CDATA[<p>There are lots of questions on the Internt how to run the OnScreen Keyboard on a Windows 64 System from a 32bit Process. Some time ago, I investigated it but due to a lack of time I didn&#8217;t finish it. Today, I want to you show the solution of this problem.</p>
<p><span id="more-899"></span>From a 32Bit application, Windows makes sure that you cannot access the Windows\System32 folder because this is the place where Windows has all its 64bit DLLs and other files. Since a 32Bit app cannot load 64Bit DLLs, Windows redirects the access to Windows\SysWOW64 folder which is (nearly) a 32Bit copy of the System32 folder. Therefore if you call ShellExecute on the e.g. Windows\System32\osk.exe you actually run Windows\SysWOW64\osk.exe. However the 32Bit version of  OnScreenKeyboard refuses to run on a 64Bit system.</p>
<p>Fortunately, we can disable the redirrection with Wow64DisableWow64FsRedirection.</p>
<p>That leads us to a problem with ShellExecute. It uses internal functions that are located in DLLs. And there is the problem. If a winapi function wasn&#8217;t called before, it will be setup by calling LoadLibrary and GetProcAddress. However, since redirection is offline, LoadLibrary will load a 64Bit DLL which, of course, fails. In such a case ShellExecuteEx returns GetLastError  $7E (127) which defines the error  &#8220;The module specified could not be found &#8220;. I wondered what module was not found and used ProcessExplorer to compare pre- and post situation of ShellExecute. There were many, but only one made ShellExecuteEx work with disabled redirection: MPR.dll (multi protocol router). Step by step disasm returned the that WNetGetConnectionW was loaded from the DLL. So the fix is to load this library before ShellExecuteEx (also ShellExecute) is called.</p>
<pre class="brush:delphi">uses
  JwaWinType,
  JwaWinBase,
  JwaShellAPI,
  JwaSHFolder,
  JwaShlObj;

function Wow64DisableWow64FsRedirection(out OldValue: PVOID): BOOL; stdcall; external 'Kernel32.dll'; //only for JWA &lt; 2.4
function Wow64RevertWow64FsRedirection(const OldValue: PVOID): BOOL; stdcall; external 'Kernel32.dll'; //only for JWA &lt; 2.4

procedure RunOnScreenKeyBoard;
  function GetNativeWindowsDirectory : String;
  var
    P : array[0..MAX_PATH] of Char;
  begin
    SHGetFolderPath(0, CSIDL_SYSTEM, 0, SHGFP_TYPE_DEFAULT, @P);

    result := P;
  end;
var
  oldValue : Pointer;
  Path : String;
  hMpr_DLL : HMODULE;
  ShInfo : SHELLEXECUTEINFO;
begin
  //CoInitializeEx(nil, COINIT_MULTITHREADED or COINIT_DISABLE_OLE1DDE); //*1

  hMpr_DLL := LoadLibrary('mpr.dll'); //*2
  try
    if not Wow64DisableWow64FsRedirection(oldValue) then
      RaiseLastOSError;
    try
      Path := GetNativeWindowsDirectory + '\osk.exe';

      ZeroMemory(@ShInfo, sizeof(ShInfo));
      ShInfo.cbSize := sizeof(ShInfo);
      ShInfo.lpVerb := 'open';
      ShInfo.fMask := SEE_MASK_FLAG_NO_UI or SEE_MASK_NOASYNC;
      ShInfo.lpFile := PChar(Path);

      if not ShellExecuteEx(ShInfo) then
        RaiseLastOSError;
    finally
       Wow64RevertWow64FsRedirection(oldValue);
    end;
  finally
    FreeLibrary(hMpr_DLL);
  end;
end;
</pre>
<p>*1 Has no use here if it was already called. But it is a reminder that it should be called for ShellExecute due to MSDN docs.<br />
 *2 Make sure you don&#8217;t call LoadLibrary when redirection is offline.</p>
<h3>Delphi (addition)</h3>
<p>I forgot to mention that in my experiences, a simple call to ShellExecute works if you run your app in Delphi. You&#8217;ll see that the app already has mpr.dll loaded if you check with Process Explorer. However, running the same app in Windows Explorer it will fail. <br />
 You see that Delphi can have an effect on your application. Therefore, always test your app separately.</p>
<h3>Download</h3>
<p>You can download this file from <a href="https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/trunk/Examples/OSK/64bit OSK/OSK 64 Example.dpr">here</a>.</p>
<h3>Remarks</h3>
<p>I tested this code on my Win7 64bit System only.</p>
<p>The string &#8220;%windir%\sysnative\osk.exe&#8221; was a first guess. However, ShellExecute fails with Error 2 (File Not Found).</p>
<p>Because this is a 64Bit Problem only, I did <strong>not </strong>make extra effort to check for a 64Bit Windows. The function Wow64DisableWow64FsRedirection is not available on a 32Bit platform, so using static linking is a bad idea if you want to use your app on 32Bit.</p>
<p><span style="font-size: large;">If you find this code useful, you may consider a donation? As usual, a donation can be also a WinAPI conversion, examples, bug fixes etc.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/11/29/how-to-run-the-onscreenkeyboard/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Is File In Use</title>
		<link>http://blog.delphi-jedi.net/2010/11/14/is-file-in-use/</link>
		<comments>http://blog.delphi-jedi.net/2010/11/14/is-file-in-use/#comments</comments>
		<pubDate>Sun, 14 Nov 2010 19:57:43 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Conversion]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=861</guid>
		<description><![CDATA[In a thread on DelphiPraxis there was a question that comes up several times a year. However, this time I could remember that there is actually an COM API that can solve the problem. The question was about how to find out which process has a lock on a file. The main problem was, in [...]]]></description>
			<content:encoded><![CDATA[<p>In a thread on DelphiPraxis there was a question that comes up several times a year. However, this time I could remember that there is actually an COM API that can solve the problem. The question was about how to find out which process has a lock on a file. The main problem was, in deed, that I could not remember the API&#8217;s name so Assarbad put some effort in retrieving it. Thanks.<span id="more-861"></span></p>
<p>The name of the API is <a href="http://msdn.microsoft.com/en-us/library/bb775874%28VS.85%29.aspx" target="_blank">IFileIsInUse</a>, an interface. It resides in Shobjidl.h, Shobjidl.idl and newly in JwaShlObj.pas. This is the translation:</p>
<pre class="brush:delphi">{$IFDEF WINVISTA_UP}
const
  IID_IFileIsInUse: TGUID = (
    D1:$64a1cbf0; D2:$3a1a; D3:$4461; D4:($91,$58,$37,$69,$69,$69,$39,$50));

type
  {$ALIGN 4}
  tagFILE_USAGE_TYPE = (
    FUT_PLAYING = 0,
    FUT_EDITING = 1,
    FUT_GENERIC = 2
  );
  FILE_USAGE_TYPE = tagFILE_USAGE_TYPE;
  TFileUsageType = FILE_USAGE_TYPE;

const
  OF_CAP_CANSWITCHTO     = $0001;
  OF_CAP_CANCLOSE        = $0002;

type
  IFileIsInUse = interface(IUnknown)
    ['{64a1cbf0-3a1a-4461-9158-376969693950}']
    function GetAppName(out ppszName: LPWSTR) : HRESULT; stdcall;
    function GetUsage(out pfut : FILE_USAGE_TYPE) : HRESULT; stdcall;
    function GetCapabilities(out pdwCapFlags : DWORD) : HRESULT; stdcall;
    function GetSwitchToHWND(out phwnd : HWND) : HRESULT; stdcall;
    function CloseFile() : HRESULT; stdcall;
  end;

{$ENDIF WINVISTA_UP}
</pre>
<p>The interface can be used as a client and also can be implemented by a server. A client usually checks if a file has a lock and retrieves a pointer to this interface to access the methods. A server usually holds a lock on a given file and implements the interface to provide the methods to the client. This article will discuss only the client side.<br />
 You see that this API only works if both sides do their jobs. A process that locks a file must also implement this interface and register it, so a client can receive a status information. There is no direct link between a file lock and the process name. If a process holds a lock on a file but does not implement the interface you are on your own again. <br />
 Eventually, this is only a shell helper for the nice Windows Explorer deletion dialog.</p>
<p><a href="http://blog.delphi-jedi.net/wp-content/uploads/2010/11/FileInUse-2.png"><img class="alignnone size-full wp-image-869" title="FileInUse Windows Explorer Dialog" src="http://blog.delphi-jedi.net/wp-content/uploads/2010/11/FileInUse-2.png" alt="" width="496" height="293" /></a></p>
<pre class="brush:delphi">  IFileIsInUse = interface(IUnknown)
    function GetAppName(out ppszName: LPWSTR) : HRESULT; stdcall;
    function GetUsage(out pfut : FILE_USAGE_TYPE) : HRESULT; stdcall;
    function GetCapabilities(out pdwCapFlags : DWORD) : HRESULT; stdcall;
    function GetSwitchToHWND(out phwnd : HWND) : HRESULT; stdcall;
    function CloseFile() : HRESULT; stdcall;
  end;
</pre>
<p>The methods of the interface are really easy to understand.</p>
<ul>
<li><em>GetAppName </em>retrieves the name of the process that holds the file. It can be any chosen name by the application designer. To get the name use always a PWideChar and don&#8217;t forget to free it with CoTaskMemFree (it uses the interface IMalloc). Don&#8217;t forget to check for the result. If you like exception you can also rewrite the code using <strong>safecall</strong> (convert the function to a procedure then).</li>
<li><em>GetUsage </em>returns the reason why the file is locked. It can be one of the enumeration constant of  TFileUsage. Either it can be playing a video or music or editing a file. If these are not sufficient the value FUT_GENERIC must be used. Maybe there will be more values in future.</li>
<li> <em>GetCapabilities </em>returns a set of flags in a DWORD. They define whether the file can be closed (OF_CAP_CANCLOSE) by calling <em>CloseFile</em> or the we can put the application into foreground (OF_CAP_CANSWITCHTO). Be aware that you should inform the user that you are about to switch the window. Otherwise she could get nervous about her missing application window. Switching the window can be done by <a href="http://msdn.microsoft.com/en-us/library/ms633539%28VS.85%29.aspx" target="_blank"><em>SetForegroundWindow</em></a>. But your application must have a focus (and some other rules, see MSDN SetForegroundWindow) to switch the window; otherwise nothing happens.</li>
<li><em>GetSwitchToHWND</em> returns a window handle of the other process. Only use this handle to switch to the window. You don&#8217;t really know what window is returned here. Don&#8217;t try to close it or anything else because this is just bad behaviour. At all costs, check the return value. Otherwise you don&#8217;t know whether the returned window handle is valid or just an random number. In worst case it is an existing window from your process. Well, COM rules tell us to nullify the out parameters but usually it is better to check.<br />
 Of course, the call is only valid if GetCapabilities returns the bit OF_CAP_CANSWITCHTO.</li>
<li><em>CloseFile</em> implements the server side of closing the file. The call is only valid if <em>GetCapabilities </em>returns the bit OF_CAP_CANCLOSE. Well, this is really nice. However, don&#8217;t trust it! Always recheck the lock on the file instead of continuing blindly.</li>
</ul>
<p>To retrieve an interface on the file you have to lock it first. Either you download and compile the MSDN example <a href="http://msdn.microsoft.com/en-us/library/ee330722(v=VS.85).aspx" target="_blank">IsFileInUse</a> or you open up an application that implements the interface (e.g. a PDF Reader, MS Office).</p>
<p>The next step is to know where the locked files are placed. The location is the running object table, short ROT (ActiveX.GetRunningObjectTable() retrieves it). It is a global* (on machine) table that holds running COM objects. You can implement your own interfaces and put it in this table. Because interfaces can be arbitrary in its structure and reason to be,  they are attached to monikers (<a href="http://msdn.microsoft.com/en-us/library/ms679705%28VS.85%29.aspx" target="_blank">IMoniker</a>) which describe them uniquely. There are several types of monikers like class, item and file moniker (more information provides IMoniker in MSDN). We are interested in the latter only. <br />
 So the whole work is an enumeration over all monikers in the ROT.  Usually there are not that much in there (I got 5 here). Each moniker is checked for its type (IsSystemMoniker) and if it is a file moniker (MKSYS_FILEMONIKER) the path is compared to the input parameter FileName. Honestly, I cannot tell why there is a comparison of the prefix at first followed by a comparison of the moniker itself, sorry. <br />
 The object itself is retrieved from the moniker by GetObject. It may fail with E_ACCESS_DENIED so a check is done using <em>Succeeded</em>. In the end, we can try to retrieve the IFileIsInUse interface. There may be such a file registered but without the implementation of the interface, thus an additional check.</p>
<p>I didn&#8217;t create this whole source by myself. In fact, there is a <a href="http://msdn.microsoft.com/en-us/library/ee330722(v=VS.85).aspx" target="_blank">FileIsInUse example </a>in MSDN that is the base of this article. The original source is located in the docx file in the download. The example FileIsInUse will create a server.</p>
<p><br class="spacer_" /></p>
<pre class="brush:delphi">function GetFileInUseInfo(const FileName : WideString) : IFileIsInUse;
var
  ROT : IRunningObjectTable;
  mFile, enumIndex, Prefix : IMoniker;
  enumMoniker : IEnumMoniker;
  MonikerType : LongInt;
  unkInt  : IInterface;
begin
  result := nil;

  OleCheck(GetRunningObjectTable(0, ROT));
  OleCheck(CreateFileMoniker(PWideChar(FileName), mFile));

  OleCheck(ROT.EnumRunning(enumMoniker));

  while (enumMoniker.Next(1, enumIndex, nil) = S_OK) do
  begin
    OleCheck(enumIndex.IsSystemMoniker(MonikerType));
    if MonikerType = MKSYS_FILEMONIKER then
    begin
      if Succeeded(mFile.CommonPrefixWith(enumIndex, Prefix)) and
         (mFile.IsEqual(Prefix) = S_OK) then
      begin
       if Succeeded(ROT.GetObject(enumIndex, unkInt)) then
        begin
          if Succeeded(unkInt.QueryInterface(IID_IFileIsInUse, result)) then
          begin
            result := unkInt as IFileIsInUse;
            exit;
          end;
        end;
      end;
    end;
  end;
end;
</pre>
<p><br class="spacer_" /></p>
<h3>Conclusion<br class="spacer_" /></h3>
<p>This whole API has some caveats</p>
<ul>
<li>This API relies on a server that registers an interface in the ROT honestly. If an application doesn&#8217;t do the effort, you will be unable to aquire the name of it.</li>
<li>If you lock a file on a shared folder and you want to access the very same file on the local file system, you cannot determine the process if you access the shared folder from localhost. The reason is Windows itself. Windows is the provider of the file to the outer world (even if it is a loopback) so Windows Explorer shows &#8220;System&#8221; as origin. In the ROT you will see the the UNC path instead of the local file system path. Thus the comparison and our function will fail.</li>
<li>*Security: A ROT is not really global. In fact, there are several ROTs in the system. ROTs are divided by a user and then the mandatory integrity control (MIC) or integrity levels (IL) high, medium and propably low (didn&#8217;t check). If you run as a user, your processes get an medium level and as an Administrator you&#8217;ll get an high integrity level. A server that runs with an medium integrity level will only be allowed to register itself into the medium ROT. So it must be started at least once as Administrator to be allowed to create some Registry keys for COM (LOCAL_MACHINE\Classes\AppID\<em>guid</em>). In this way it will be available in all ROTs if it wants. Unfortunately, this is not the end. On a multi user system, every object in a moniker has a security descriptor that tells COM who is allowed to access it. If Alice wants to access an object in the ROT that was created by Bob, Bob has to explicitily grant Alice access to it. By default the security, which allow access to SYSTEM, Administrators and the creator, is copied from the global COM security settings and can be changed either in the registry for an AppID, at process startup or for each registered object by the server. JWSCL provides all of them in JwsclComSecurity.pas (only Subversion trunk and &gt;= 0.9.4). In this way a server can change the settings to, say, allow all authenticated users access to the object. </li>
</ul>
<h3>Downloads</h3>
<p>You can download the example file from the Subversion directly.</p>
<table border="0">
<tbody>
<tr>
<td><a href="tsvn:https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/trunk/Examples/FileIsInUse/Client/FileIsInUseClientExample.dpr"><img class="size-full wp-image-387 alignnone" title="tortoisecheckout" src="http://blog.delphi-jedi.net/wp-content/uploads/2007/12/tortoisecheckout.png" alt="Checkout with TortoiseSVN" width="48" height="48" /></a></td>
<td><a href="https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/trunk/Examples/FileIsInUse/Client/FileIsInUseClientExample.dpr" target="_blank">https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/trunk/Examples/FileIsInUse/Client/FileIsInUseClientExample.dpr</a></td>
</tr>
</tbody>
</table>
<p><br class="spacer_" /></p>
<h3>Sequel</h3>
<p>The next article discusses the the implementation if the interface IFileIsInUse.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/11/14/is-file-in-use/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Windows 7 Taskbar-features via components</title>
		<link>http://blog.delphi-jedi.net/2010/08/18/using-windows-7-taskbar-features-via-components/</link>
		<comments>http://blog.delphi-jedi.net/2010/08/18/using-windows-7-taskbar-features-via-components/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 04:39:49 +0000</pubDate>
		<dc:creator>chaosben</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[Window]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows 7]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=770</guid>
		<description><![CDATA[Windows 7 gave us some nice and useful little eye-catchers in the taskbar. Those are available using the Windows shell interfaces ITaskbarList3 and ITaskbarList4. But alas, how can a Delphi developer incorporate these in his applications? You may read on if you ever wanted to&#8230; have this cool progress bar feature in the taskbar. have [...]]]></description>
			<content:encoded><![CDATA[<p>Windows 7 gave us some nice and useful little eye-catchers in the taskbar. Those are available using the Windows shell interfaces <a href="http://msdn.microsoft.com/en-us/library/dd391692%28v=VS.85%29.aspx" target="_blank">ITaskbarList3</a> and <a href="http://msdn.microsoft.com/en-us/library/dd562040%28VS.85%29.aspx">ITaskbarList4</a>. <br />
 But alas, how can a Delphi developer incorporate these in his applications?</p>
<p><span id="more-770"></span>You may read on if you ever wanted to&#8230;</p>
<ol>
<li>have this cool progress bar feature in the taskbar.</li>
<li>have an overlay icon onto your application&#8217;s icon in the taskbar.</li>
<li>multiple tabs for each window or control of your application in the taskbar.</li>
<li>have thumb buttons inside the preview of your form (like the Windows MediaPlayer).</li>
</ol>
<p>You want your application to look like that?</p>
<p><a href="http://blog.delphi-jedi.net/wp-content/uploads/2010/08/Screen1.png"><img class="aligncenter size-full wp-image-804" src="http://blog.delphi-jedi.net/wp-content/uploads/2010/08/Screen1.png" alt="" width="421" height="203" /></a></p>
<p>Are you using Windows 7? What a lucky (wo)man you are.</p>
<p>The guys from <a href="http://code.google.com/p/theunknownones/" target="_blank">TheUnknownOnes</a> just released some components to use the new features introduced in Windows 7.  <br />
 Of course, these components are based on the JEDI Windows API. At the moment (until the next release of JWAPI), you&#8217;ll have to checkout the trunk of the JWAPI in order to get the code compiled. <br />
 To get these components, checkout <a href="http://theunknownones.googlecode.com/svn/trunk/Components/TaskBarList/" target="_blank">the source</a> out of their svn repository.</p>
<p>And if you want to discuss something about them in German: use <a href="http://www.delphipraxis.net/153782-taskbarlistcomponents-fuer-windows-7-a.html" target="_blank">this thread</a>.</p>
<p>A first short demo was published <a href="http://vimeo.com/14291783" target="_blank">here</a>. Stay tuned for some more.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/08/18/using-windows-7-taskbar-features-via-components/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to (un-)install and start a service object</title>
		<link>http://blog.delphi-jedi.net/2008/04/05/how-to-un-install-and-start-a-service-object/</link>
		<comments>http://blog.delphi-jedi.net/2008/04/05/how-to-un-install-and-start-a-service-object/#comments</comments>
		<pubDate>Sat, 05 Apr 2008 11:29:43 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[Service]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/04/05/how-to-un-install-and-start-a-service-object/</guid>
		<description><![CDATA[Unfortunately Borland didn&#8217;t implement a public register and start function into the class TServiceApplication. So we have to do it ourselves. First we publish the protected RegisterServices function to allow (un-)install our service(s) programmatically. TServiceApplicationEx = class&#40;TServiceApplication&#41; public &#160; procedure RegisterServices&#40;Install, Silent: Boolean&#41;; end; { TServiceApplicationEx } procedure TServiceApplicationEx.RegisterServices&#40;Install, Silent: Boolean&#41;; begin &#160; inherited; end; [...]]]></description>
			<content:encoded><![CDATA[<p>Unfortunately Borland didn&#8217;t implement a public register and start function into the class TServiceApplication. So we have to  do it  ourselves.<br />
First we publish the protected RegisterServices function to allow (un-)install our service(s) programmatically.</p>
<p><span id="more-120"></span></p>
<div class="dean_ch" style="white-space: wrap;">TServiceApplicationEx = <span class="kw1">class</span><span class="br0">&#40;</span>TServiceApplication<span class="br0">&#41;</span><br />
<span class="kw1">public</span><br />
&nbsp; <span class="kw1">procedure</span> RegisterServices<span class="br0">&#40;</span>Install, Silent: <span class="kw4">Boolean</span><span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</p>
<p><span class="coMULTI">{ TServiceApplicationEx }</span><br />
<span class="kw1">procedure</span> TServiceApplicationEx.<span class="me1">RegisterServices</span><span class="br0">&#40;</span>Install, Silent: <span class="kw4">Boolean</span><span class="br0">&#41;</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="kw1">inherited</span>;<br />
<span class="kw1">end</span>;</div>
<p>Of course we need a tool function that starts our service</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> JwaWindows;procedure StartTheService<span class="br0">&#40;</span>Service : TService<span class="br0">&#41;</span>;<br />
<span class="kw1">var</span><br />
&nbsp; hSCM: SC_HANDLE;<br />
&nbsp; hSvc: SC_HANDLE;<br />
&nbsp; args: <span class="kw1">array</span> <span class="kw1">of</span> <span class="kw4">PChar</span>;<br />
&nbsp; i : <span class="kw4">Integer</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; hSCM := OpenSCManager<span class="br0">&#40;</span><span class="kw2">nil</span>, SERVICES_ACTIVE_DATABASEW, SC_MANAGER_CONNECT<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">if</span> hSCM = <span class="nu0">0</span> <span class="kw1">then</span><br />
&nbsp; &nbsp;<span class="kw3">RaiseLastOSError</span>;</p>
<p><span class="kw1">try</span><br />
&nbsp; &nbsp; hSvc := OpenService<span class="br0">&#40;</span>hSCM, <span class="kw4">PChar</span><span class="br0">&#40;</span>Service.<span class="me1">Name</span><span class="br0">&#41;</span>, SERVICE_START<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">if</span> hSvc = <span class="nu0">0</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">RaiseLastOSError</span>; &nbsp; &nbsp;<span class="kw1">try</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">SetLength</span><span class="br0">&#40;</span>args, <span class="kw3">ParamCount</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; <span class="kw1">for</span> i := <span class="nu0">0</span> <span class="kw1">to</span> ParamCount<span class="nu0">-1</span> <span class="kw1">do</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">begin</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">GetMem</span><span class="br0">&#40;</span>args<span class="br0">&#91;</span>i<span class="br0">&#93;</span>, <span class="kw3">Length</span><span class="br0">&#40;</span><span class="kw3">ParamStr</span><span class="br0">&#40;</span>i<span class="nu0">+1</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="nu0">+2</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; StringCchCopy<span class="br0">&#40;</span>args<span class="br0">&#91;</span>i<span class="br0">&#93;</span>, <span class="kw3">Length</span><span class="br0">&#40;</span><span class="kw3">ParamStr</span><span class="br0">&#40;</span>i<span class="nu0">+1</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="nu0">+2</span>, <span class="kw4">PChar</span><span class="br0">&#40;</span><span class="kw3">ParamStr</span><span class="br0">&#40;</span>i<span class="nu0">+1</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span>;</p>
<p>&nbsp; &nbsp; &nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> StartServiceA<span class="br0">&#40;</span>hSvc, <span class="kw3">Length</span><span class="br0">&#40;</span>args<span class="br0">&#41;</span>, @args<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">RaiseLastOSError</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> i := <span class="nu0">0</span> <span class="kw1">to</span> ParamCount<span class="nu0">-1</span> <span class="kw1">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">begin</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">FreeMem</span><span class="br0">&#40;</span>args<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">end</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span>;<br />
&nbsp; &nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; &nbsp; CloseServiceHandle<span class="br0">&#40;</span>hSvc<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">end</span>;<br />
&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; CloseServiceHandle<span class="br0">&#40;</span>hScm<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">end</span>;<br />
<span class="kw1">end</span>;</div>
<p>Finally we can adjust the main application to install, uninstall or run the service.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">program</span> xy;<br />
<span class="kw1">uses</span> SvcMgr, &#8230;;<br />
<span class="kw1">begin</span><br />
&nbsp; SvcMgr.<span class="me1">Application</span>.<span class="me1">Free</span>;<br />
&nbsp; SvcMgr.<span class="me1">Application</span> := TServiceApplicationEx.<span class="me1">Create</span><span class="br0">&#40;</span><span class="kw2">nil</span><span class="br0">&#41;</span>;<br />
&nbsp; SvcMgr.<span class="me1">Application</span>.<span class="kw3">Initialize</span>;<br />
&nbsp; SvcMgr.<span class="me1">Application</span>.<span class="me1">CreateForm</span><span class="br0">&#40;</span>TMyService, MyService<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">if</span> &lt;InstallService&gt; <span class="kw1">then</span><br />
&nbsp; &nbsp; SvcMgr.<span class="me1">Application</span>.<span class="me1">RegisterServices</span><span class="br0">&#40;</span><span class="kw2">true</span>, <span class="kw2">true</span><span class="br0">&#41;</span><br />
&nbsp; <span class="kw1">else</span><br />
&nbsp; <span class="kw1">if</span> &lt;DeInstallService&gt; <span class="kw1">then</span><br />
&nbsp; &nbsp; SvcMgr.<span class="me1">Application</span>.<span class="me1">RegisterServices</span><span class="br0">&#40;</span><span class="kw2">false</span>, <span class="kw2">true</span><span class="br0">&#41;</span><br />
&nbsp; <span class="kw1">else</span><br />
&nbsp; <span class="kw1">if</span> &lt;StartService&gt; <span class="kw1">then</span><br />
&nbsp; &nbsp; StartService<span class="br0">&#40;</span>MyService<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">and</span> <span class="kw3">exit</span> here<br />
&nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; SvcMgr.<span class="me1">Application</span>.<span class="me1">Run</span>;<br />
<span class="kw1">end</span>;</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/04/05/how-to-un-install-and-start-a-service-object/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>We support YOU developing with JWA and JWSCL!</title>
		<link>http://blog.delphi-jedi.net/2008/04/03/we-support-you-developing-with-jwa-and-jwscl/</link>
		<comments>http://blog.delphi-jedi.net/2008/04/03/we-support-you-developing-with-jwa-and-jwscl/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 18:42:59 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[support]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/04/03/we-support-you-developing-with-jwa-and-jwscl/</guid>
		<description><![CDATA[Do you need help? We can support you creating application using JWA and/or JWSCL. Visit the Get Service site on SourceForge for more information like pricing.]]></description>
			<content:encoded><![CDATA[<p>Do you need help? We can support you creating application using JWA and/or JWSCL.</p>
<p>Visit the <a href="http://sourceforge.net/services/project_services.php?project_id=121894">Get Service</a> site on SourceForge for more information like pricing.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/04/03/we-support-you-developing-with-jwa-and-jwscl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to use VCL and SetThreadDesktop</title>
		<link>http://blog.delphi-jedi.net/2008/03/19/how-to-use-vcl-and-setthreaddesktop/</link>
		<comments>http://blog.delphi-jedi.net/2008/03/19/how-to-use-vcl-and-setthreaddesktop/#comments</comments>
		<pubDate>Wed, 19 Mar 2008 09:00:49 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[Thread]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/03/19/how-to-use-vcl-and-setthreaddesktop/</guid>
		<description><![CDATA[It is impossible to use SetThreadDesktop and the VCL at the same time because a thread can only show windows on one desktop at a time. However VCL is not written for the use with multiple threads, so there is no way to show Delphi forms of same process on two different desktops. SetThreadDesktop describes [...]]]></description>
			<content:encoded><![CDATA[<p>It is impossible to use <a href="http://msdn2.microsoft.com/en-us/library/ms686250(vs.85).aspx">SetThreadDesktop</a> and the <strong>VCL </strong>at the same time because a thread can only show windows on one desktop at a time.  However <strong>VCL </strong>is not written for the use with multiple threads, so there is no way to show <strong>Delphi </strong>forms of same process on two different desktops. <em>SetThreadDesktop </em>describes this issue as followed.</p>
<blockquote><p>The  <strong>SetThreadDesktop</strong> function will fail if the calling thread has any windows or hooks on its current desktop (unless the <em>hDesktop</em> parameter is a handle to the current desktop).</p></blockquote>
<p><u>Though there is a  workaround</u> to make <strong>VCL </strong>work with <em>SetThreadDesktop </em>and <a href="http://msdn2.microsoft.com/en-us/library/ms686347(VS.85).aspx">SwitchDesktop</a>. The <em>Application </em>variable defined in unit <em>Forms </em>must be freed and then renewed. Here is the correct order :</p>
<ol>
<li>Close all your forms so the Application is going to quit.</li>
<li>Free the Application instance in your DPR file.
<div class="dean_ch" style="white-space: wrap;">Application.<span class="me1">Run</span>;<br />
Application.<span class="me1">Free</span>;</div>
</li>
<li>Then call <em>SetThreadDesktop </em>and <em>SwitchDesktop</em></li>
<li>Recreate the application object &#8211; now on the new desktop:
<div class="dean_ch" style="white-space: wrap;">Application := TApplication.<span class="me1">Create</span><span class="br0">&#40;</span><span class="kw2">nil</span><span class="br0">&#41;</span>;<br />
Application.<span class="kw3">Initialize</span>;</div>
</li>
<li>Call all the usual stuff that has to be done to show your forms</li>
</ol>
<p>&#8230;follow the same way as described to get back to the original desktop and forms (in this order!). However this has to be done in the  main project file (DPR) (except you&#8217;re going to source it out) because you cannot just free <em>Application</em> in the event method of a button click. You have to shutdown your application (not your process) and continue right after :</p>
<div class="dean_ch" style="white-space: wrap;">Application.<span class="me1">Free</span>;</div>
<p>In this way the process does not shut down and you can use <strong>VCL </strong>on one desktop at a time.</p>
<p><u>A second possibility</u> is to use <strong>VCL </strong>on one desktop and <strong>NonVCL</strong> on the other. However in this way you have to create a new thread and use your own message loop (located in the new thread).  Then you can call <em>SetThreadDesktop </em>in this thread and show the <strong>NonVCL</strong> windows.</p>
<p><u>A third possibility</u> is to execute another or the same application with <a href="http://msdn2.microsoft.com/en-us/library/ms682425.aspx"><em>CreateProcess</em></a>. This function allows you to specify the target desktop name for the new process in <em>lpDesktop </em>of the <em><a href="http://msdn2.microsoft.com/en-us/library/ms686331(VS.85).aspx">TProcessInformation</a></em> structure.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> JwaWindows;</p>
<p><span class="kw1">var</span><br />
&nbsp; StartupInfo: TStartupInfo;<br />
&nbsp; ProcInfo : TProcessInformation;<br />
<span class="kw1">begin</span><br />
&nbsp; StartupInfo.<span class="me1">cb</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= <span class="kw3">SizeOf</span><span class="br0">&#40;</span>StartupInfo<span class="br0">&#41;</span>;<br />
&nbsp; StartupInfo.<span class="me1">lpDesktop</span> &nbsp; := <span class="st0">&#8216;winsta0\default&#8217;</span>;</p>
<p>&nbsp; CreateProcess<span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;appname.exe&#8217;</span>,<span class="co1">//__in_opt &nbsp; &nbsp; LPCTSTR lpApplicationName,</span><br />
&nbsp; &nbsp; <span class="kw2">nil</span>,<span class="co1">//__inout_opt &nbsp;LPTSTR lpCommandLine,</span><br />
&nbsp; &nbsp; <span class="kw2">nil</span>,<span class="co1">//__in_opt &nbsp; &nbsp; LPSECURITY_ATTRIBUTES lpProcessAttributes,</span><br />
&nbsp; &nbsp; <span class="kw2">nil</span>,<span class="co1">//__in_opt &nbsp; &nbsp; LPSECURITY_ATTRIBUTES lpThreadAttributes,</span><br />
&nbsp; &nbsp; <span class="kw2">true</span>,<span class="co1">//__in &nbsp; &nbsp; &nbsp; &nbsp; BOOL bInheritHandles,</span><br />
&nbsp; &nbsp; CREATE_NEW_CONSOLE,<span class="co1">//__in &nbsp; &nbsp; &nbsp; &nbsp; DWORD dwCreationFlags,</span><br />
&nbsp; &nbsp; <span class="kw2">nil</span>,<span class="co1">//__in_opt &nbsp; &nbsp; LPVOID lpEnvironment,</span><br />
&nbsp; &nbsp; <span class="kw2">nil</span>,<span class="co1">//__in_opt &nbsp; &nbsp; LPCTSTR lpCurrentDirectory,</span><br />
&nbsp; &nbsp; StartInfo,<span class="co1">//__in &nbsp; &nbsp; &nbsp; &nbsp; LPSTARTUPINFO lpStartupInfo,</span><br />
&nbsp; &nbsp; ProcInfo,<span class="co1">//__out &nbsp; &nbsp; &nbsp; &nbsp;LPPROCESS_INFORMATION lpProcessInformation</span><br />
&nbsp; <span class="br0">&#41;</span>;<br />
&nbsp; CloseHandle<span class="br0">&#40;</span>ProcInfo.<span class="me1">hProcess</span><span class="br0">&#41;</span>;<br />
&nbsp; CloseHandle<span class="br0">&#40;</span>ProcInfo.<span class="me1">hThread</span><span class="br0">&#41;</span>;<br />
&#8230;</div>
<hr size="2" width="100%" /><u><strong>JWSCL</strong></u><br />
Did you know that there is already a desktop class that provides all necessary function to administer desktops? Yes, there is! It is called <a href="http://jwscldoc.delphi-jedi.net/JwsclDesktops.TJwSecurityDesktop.html">TJwSecurityDesktop</a> and resides in unit <a href="http://jwscldoc.delphi-jedi.net/JwsclDesktops.html" class="bold">JwsclDesktops</a>.<br />
<hr size="2" width="100%" /><strong>Tell me how you liked this blog entry by adding a comment.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/03/19/how-to-use-vcl-and-setthreaddesktop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to get the process of a window?</title>
		<link>http://blog.delphi-jedi.net/2008/03/18/how-to-get-the-process-of-a-window/</link>
		<comments>http://blog.delphi-jedi.net/2008/03/18/how-to-get-the-process-of-a-window/#comments</comments>
		<pubDate>Tue, 18 Mar 2008 18:00:35 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[ID]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[Thread]]></category>
		<category><![CDATA[Window]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/03/18/how-to-get-the-process-of-a-window/</guid>
		<description><![CDATA[This answer is very easy &#8211; just use GetWindowThreadProcessId JWA declares it as followed: function GetWindowThreadProcessId&#40;hWnd: HWND; lpdwProcessId: LPDWORD&#41;: DWORD; stdcall; The function returns an identifier (not a handle) and also may set lpdwProcessId to the identifier (again not a handle!) if it is not nil. Be aware that identifiers aren&#8217;t handles, so you must [...]]]></description>
			<content:encoded><![CDATA[<p>This answer is very easy &#8211; just use <a href="http://msdn2.microsoft.com/en-us/library/ms633522(VS.85).aspx">GetWindowThreadProcessId</a></p>
<p>JWA declares it as followed:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">function</span> GetWindowThreadProcessId<span class="br0">&#40;</span>hWnd: HWND; lpdwProcessId: LPDWORD<span class="br0">&#41;</span>: <span class="kw4">DWORD</span>; <span class="kw1">stdcall</span>;</div>
<p>The function returns an identifier (not a handle) and also may set lpdwProcessId to the identifier (again not a handle!) if it is not nil. Be aware that identifiers aren&#8217;t handles, so you must not close them by using CloseHandle. Identifiers are only numbers that makes an object distinguishable from other objects of the same type.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> JwaWindows;</p>
<p><span class="kw1">var</span> ProcessID,<br />
&nbsp;ThreadID &nbsp;: <span class="kw4">DWORD</span>;<br />
&nbsp;WndHandle : HWND;</p>
<p><span class="kw1">begin</span><br />
&nbsp; WndHandle := FindWindow<span class="br0">&#40;</span>&#8230;<span class="br0">&#41;</span>;<br />
&nbsp; ThreadID := GetWindowThreadProcessId<span class="br0">&#40;</span>WndHandle, @ProcessID<span class="br0">&#41;</span>;<br />
&#8230;</div>
<p><strong>Tell me how you liked this blog entry by adding a comment.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/03/18/how-to-get-the-process-of-a-window/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to submit header conversions</title>
		<link>http://blog.delphi-jedi.net/2008/03/13/how-to-submit-header-conversions/</link>
		<comments>http://blog.delphi-jedi.net/2008/03/13/how-to-submit-header-conversions/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 21:38:34 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JWA Downloads]]></category>
		<category><![CDATA[Conversion]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[submit]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/03/13/how-to-submit-header-conversions/</guid>
		<description><![CDATA[Please read this &#8220;How to&#8221; before submitting any Header Conversions to us. Then you can submit the headers to us by mail.]]></description>
			<content:encoded><![CDATA[<p>Please read this <a href="http://delphi-jedi.org/apipackspec.html">&#8220;How to&#8221;</a> before submitting any Header Conversions to us.</p>
<p>Then you can submit the headers to us by <a href="http://mailhide.recaptcha.net/d?k=01MeKrDPlF4UMY4OOGe4JcPA==&amp;c=qu6RnFAF5jjxh0bbfE7ymCJCa5TFUIfZS6RdKFzWmME=">mail</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/03/13/how-to-submit-header-conversions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to setup JWSCL?</title>
		<link>http://blog.delphi-jedi.net/2008/03/03/how-to-setup-jwscl/</link>
		<comments>http://blog.delphi-jedi.net/2008/03/03/how-to-setup-jwscl/#comments</comments>
		<pubDate>Mon, 03 Mar 2008 13:30:40 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[Setup]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/03/03/how-to-setup-jwscl/</guid>
		<description><![CDATA[The JWSCL does only need a minor setup. You need to create a binary unit file (DCU-file) for the JEDI API Headers as described here. You must setup JEDI API first before you can start with JWSCL! Otherwise if you set Delphi source path to include JwaWindows.pas you&#8217;ll get an error like: Incompatible types: JwaWindows.XXX [...]]]></description>
			<content:encoded><![CDATA[<p>The JWSCL does only need a minor setup. You need to create a binary unit file (DCU-file) for the JEDI API Headers as described <a title="how-to-setup-the-library" href="http://blog.delphi-jedi.net/2007/12/27/how-to-setup-the-library/">here</a>.</p>
<p><strong>You must setup JEDI API first before you can start with JWSCL! Otherwise if you set Delphi source path to include JwaWindows.pas you&#8217;ll get an error like:</strong></p>
<pre>Incompatible types: JwaWindows.XXX and JwaWinNT.XXX</pre>
<p>JWSCL works with JwaWindows from the JEDI API. However this only works with some compiler directives defined in the packages in the package folder of JEDI API. Use these packages to compile and create a JwaWindows.dcu file.<br />
 <strong>ERROR:</strong> Adding the source path of JWA (folder Win32API) to your project options and then use JwaWindows and JWSCL does not work!</p>
<p>1. Adapt this source path to include some necessary files for JWSCL:</p>
<pre>"path to JEDI API"\"version"\COM
e.g. C:\Projects\jwapi\2.3\COM</pre>
<p>2. Make sure that you have added the path of JwaWindows.dcu to your project or general library path. After this step you can also add the source path to the JWSCL source folder (\source) to the project or general library path so all projects can easily use JWA and JWSCL.</p>
<p>3. Eventually you can start using JWA and JWSCL in the simplest way: Just add the units to your uses clause.</p>
<p>4. Consider to update your JEDI files using Subversion (with a Subversion client like TortoiseSVN). With TortoiseSVN you can just right click on the JEDI JWSCL folder and hit &#8220;SVN Update&#8221; (<span style="text-decoration: underline;">not </span>Checkout or Import!). The code is then updated.</p>
<p><br class="spacer_" /></p>
<h2>Source and Library Path Settings &#8211; Overview</h2>
<p>This is a quick overview of the path settings you can use.</p>
<ul>
<li>Replace &lt;path&gt; with your absolute path settings to your download location of JWA and JWSCL.</li>
<li>Replace &lt;version&gt; with your downloaded JWA  and JWSCL, e.g. by <em>2.3</em> and <em>0.9.3</em> or even <em>trunk</em>.</li>
</ul>
<table style="width: 620px; height: 177px;" border="1">
<caption></caption>
<thead>
<tr class="wp-caption">
<td>
<h3>JEDI API Library</h3>
</td>
<td>Paths</td>
<td>Description</td>
</tr>
</thead>
<tbody>
<tr>
<td>Source Paths</td>
<td>&lt;path&gt;\jwapi\&lt;version&gt;\Win32API</td>
<td>
<p>Allows to open JwaXXXX units in Delphi-Editor with Ctrl+Enter</p>
</td>
</tr>
<tr>
<td></td>
<td>&lt;path&gt;\jwapi\&lt;version&gt;\Win32API\jwaWindows</td>
<td>Allows to browse Jwa identifiers in Delphi</td>
</tr>
<tr>
<td>Library Paths</td>
<td>&lt;path&gt;\jwapi\&lt;version&gt;\Packages\&lt;packages&gt;\bin\release\dynamic</td>
<td>Tells Delphi where to find JwaWindows.dcu</td>
</tr>
<tr>
<td></td>
<td>&lt;path&gt;\jwapi\&lt;version&gt;\COM</td>
<td>
<p>Tells Delphi where to find COM Type Libraries used by JEDI API&amp;WSCL</p>
</td>
</tr>
</tbody>
</table>
<p>The JWSCL sources can be added in this way:</p>
<table style="width: 620px; height: 121px;" border="1">
<caption></caption>
<thead>
<tr>
<td>
<h3>JWSCL</h3>
</td>
<td>Paths</td>
<td>Description</td>
</tr>
</thead>
<tbody>
<tr>
<td>Source Paths</td>
<td>&lt;path&gt;\jwscl\&lt;version&gt;\source</td>
<td>
<p>Allows to open JWSCL units in Delphi-Editor with Ctrl+Enter</p>
</td>
</tr>
<tr>
<td>Library Paths</td>
<td>&lt;path&gt;\jwscl\&lt;version&gt;\source</td>
<td>Tells Delphi where to find the JWSCL libraries. You don&#8217;t need to create separate DCU files<br />
 because JWSCL files are compiled fast.</td>
</tr>
</tbody>
</table>
<p>These settings are also available as <a href="http://jedi-apilib.svn.sourceforge.net/viewvc/jedi-apilib/jwscl/trunk/documentation/Path%20Settings.txt?view=log" target="_blank">documentation</a> in the Subversion Repository.</p>
<p><strong>You are finished here</strong> or you can read on to get some more information:</p>
<p>Be aware that the order of including units may change Delphi&#8217;s behavior if an identifier with the same name is declared in several units.</p>
<ol>
<li>JwaWindows instead of Borland&#8217;s Windows unit.</li>
<li>JwaVista for Vista enhancements. (This unit is no more available in newer versions than 2.2)</li>
</ol>
<p>Some types in these JWA units are duplicate. JwaVista recreates and extends them to add Vista support. Example:<br />
 The new <em>_TOKEN_INFORMATION_CLASS</em> type from JwaVista.pas has several new additions:</p>
<div class="dean_ch" style="white-space: wrap;">_TOKEN_INFORMATION_CLASS =<br />
JwaWindows._TOKEN_INFORMATION_CLASS +<br />
<span class="br0">&#40;</span><br />
TokenElevationType<br />
TokenLinkedToken<br />
TokenElevation<br />
TokenHasRestrictions<br />
TokenAccessInformation<br />
TokenVirtualizationAllowed<br />
TokenVirtualizationEnabled<br />
TokenIntegrityLevel<br />
TokenUIAccessTokenMandatoryPolicy<br />
TokenLogonSid<br />
<span class="br0">&#41;</span>;</div>
<p>However, if you add JwaVista and JwaWindows in this order into your uses clause you will only use the types from JwaVista. Some functions in JwaWindows or other libraries that use JWA won&#8217;t not know these types. To get the correct type you have to explicit adress the JwaWindows type.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">var</span> fooTokenInfo : jwaWindows._TOKEN_INFORMATION_CLASS;<br />
&#8230;<br />
<span class="me1">foo</span><span class="br0">&#40;</span>fooTokenInfo<span class="br0">&#41;</span>;</div>
<p>JWSCL does not really need an order of its units.</p>
<p>Newer versions of JWSCL and JWA do no more support JwaVista.</p>
<h2>Subversion</h2>
<p><a href="http://sourceforge.net/svn/?group_id=121894">Sourceforge </a>gives a short introduction how you can access the Subversion repository of the JEDI project.</p>
<p>The download packages (from Sourceforge) contain Subversion information so you can use your subversion tool to just update them. (Tortoisesvn: Right click the JWSCL folder and choose Subversion Update)</p>
<p>To get the latest release updates you can use this path with your Subversion client. Be aware that new versions (currently 0.9.3) can make this path obsolete (but still valid). The downloadable release packages are already provided with Subversion information so you can just update them to get the newest updates.<br />
 Click on the turtle to checkout the repository with TortoiseSVN.</p>
<table border="0">
<tbody>
<tr>
<td><a href="tsvn:https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwscl/branches/0.9.3"><img class="size-full wp-image-387 alignnone" title="tortoisecheckout" src="http://blog.delphi-jedi.net/wp-content/uploads/2007/12/tortoisecheckout.png" alt="Checkout with TortoiseSVN" width="48" height="48" /></a></td>
<td>https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwscl/branches/0.9.3</td>
</tr>
</tbody>
</table>
<p>There is also a development branch that contains new untested features. Use it with care:</p>
<table border="0">
<tbody>
<tr>
<td><a href="tsvn:https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwscl/trunk"><img class="size-full wp-image-387 alignnone" title="tortoisecheckout" src="http://blog.delphi-jedi.net/wp-content/uploads/2007/12/tortoisecheckout.png" alt="Checkout with TortoiseSVN" width="48" height="48" /></a></td>
<td>https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwscl/trunk</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/03/03/how-to-setup-jwscl/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to setup the library</title>
		<link>http://blog.delphi-jedi.net/2007/12/27/how-to-setup-the-library/</link>
		<comments>http://blog.delphi-jedi.net/2007/12/27/how-to-setup-the-library/#comments</comments>
		<pubDate>Thu, 27 Dec 2007 17:14:37 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[Setup]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2007/12/27/how-to-setup-the-library/</guid>
		<description><![CDATA[The JEDI API library provides you two ways of using it. Either you can use all the single units like JwaWinUser.pas and JwaWinTypes.pas or you can use just one unit that includes all these single units. It is called JwaWindows.pas. The 1. Single units use: Single units are included into your project by adding the [...]]]></description>
			<content:encoded><![CDATA[<p>The JEDI API library provides you two ways of using it. Either you can use all the single units like JwaWinUser.pas and JwaWinTypes.pas or you can use just one unit that includes all these single units. It is called JwaWindows.pas. The</p>
<p><span style="text-decoration: underline;">1. Single units use:<br />
 </span>Single units are included into your project by adding the JEDI API source folder to your Delphi search path. Then you can use the units like</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span><br />
&nbsp; &nbsp;JwaWinUser,<br />
&nbsp; &nbsp;JwaWinTypes,<br />
&nbsp; &nbsp;&#8230;.<br />
&nbsp;</div>
<p>Be aware that some JEDI API examples use the single units approach. So if you want to compile them you have to add the folders to Delphi source path.<br />
 However, it is possible to use it in combination with the JwaWindows.dcu approach.</p>
<p>Add these folders to your Delphi <strong>source </strong>path (located in the JWA folder)</p>
<ul>
<li>\Common and</li>
<li>\Win32API</li>
<li>\COM</li>
</ul>
<p>Thats all.</p>
<p>We suggest to add these paths to your global source path of Delphi. To do so open the options dialog of Delphi (menu Tools -&gt; Options) and navigate to the tab Library or Library Win32 (in newer Delphi). <br />
 There you add the three folders to the library path edit. Of course, you need to add absolute paths here like shown in example.</p>
<h3>Example</h3>
<p>So you saved the download &#8220;<em>JEDI API 2.3 and JEDI WSCL 0.9.3.zip</em>&#8220;  in this location</p>
<pre>C:\Program Files\JEDI\</pre>
<p>The zip file contains two projects located in folder <em>jwa</em> and <em>jwscl</em>. So you need to find the folders above by following the directory structure to :</p>
<pre>C:\Program Files\JEDI\jwa\branches\2.3</pre>
<p>In this folder you&#8217;ll find the folders <em>Common</em>, <em>Win32API </em>and <em>COM</em> that you need to add to your Delphi source path.<br />
 (You must not add qotation marks (&#8220;) since the space in <em>Program Files</em> is not a separator.)</p>
<p><br class="spacer_" /></p>
<p><span style="text-decoration: underline;">2. JwaWindows.pas (also for the use with <a href="http://blog.delphi-jedi.net/security-library/">JWSCL</a>)<br />
 </span></p>
<p>There is also the possibility to use only one file that includes all other Jedi API headers. It is called <em>JwaWindows.pas</em>.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> SysUtils, JwaWindows;</div>
<p>Do not mix up the Jwa units like this:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> SysUtils, JwaWindows, JwaWinNT;</div>
<p>It is possible to do so but in this way you will create duplicate and incompatible identifiers which will also collide with JWSCL.</p>
<p>We also suggest that you compile the file at first and then use the <strong>binary dcu</strong> file instead of the source directly. So you should add the location of JwaWindows.dcu to your Delphi source path to avoid rebuilding the file everytime you rebuild your project.</p>
<p>So again:<br />
 There are packages in the <strong>jwapi\Packages</strong> folder for the different Delphi versions. If not just use an older package version. That should suffice.</p>
<p>You can load the project group for your Delphi version and compile the different package types :</p>
<ol>
<li>static debug = for static linked functions and debugger information and no optimization</li>
<li>static release = for static linked functions and optimization</li>
<li>dynamic debug = for dynamic linked functions and debugger information and no optimization (<strong>recommended for using with JWSCL</strong> for debugging)</li>
<li>dynamic release = for dynamic linked functions and optimization (<strong>recommended for using with JWSCL</strong> in releases)</li>
</ol>
<p>The project group contains all four package types and are predefined to save the output in different folders.</p>
<p>After a successful compilation, copy the folder or point the compiler path to the directory of your choice e.g. \jwapi\trunk\Packages\d7\bin\debug\dynamic . Now your Delphi will use the dcu files instead of the source files.<br />
 The packages contains JwaWindows AND jwaVista. Both units must be included in a uses clause. JwaWindows does <span style="text-decoration: underline;">not</span> contain jwaVista!</p>
<p><strong>The JEDI Windows Security Code Library uses the second choice (</strong>JwaWindows.pas and JwaVista.pas<strong> (JwaVista is deprecated in future versions)) only. See <a title="Go to blog entry." href="http://blog.delphi-jedi.net/2008/03/03/how-to-setup-jwscl/">here</a> how to setup JWSCL. Furthermore </strong><strong>it is recommended to use any of the <span style="text-decoration: underline;">dynamic</span> linking packages for JWSCL.</strong></p>
<h2>Source and Library Path Settings &#8211; Overview</h2>
<p>This is a quick overview of the path settings you can use.</p>
<ul>
<li>Replace &lt;path&gt; with your absolute path settings to your download location of JWA and JWSCL.</li>
<li>Replace &lt;version&gt; with your downloaded JWA , e.g. by <em>2.3</em> or even <em>trunk</em>.</li>
</ul>
<table style="width: 620px; height: 177px;" border="1">
<caption>
</caption>
<thead>
<tr>
<td>
<h3>JEDI API Library</h3>
</td>
<td>Paths</td>
<td>Description</td>
</tr>
</thead>
<tbody>
<tr>
<td>Source Paths</td>
<td>&lt;path&gt;\jwapi\&lt;version&gt;\Win32API</td>
<td>
<p>Allows to open JwaXXXX units in Delphi-Editor with Ctrl+Enter</p>
</td>
</tr>
<tr>
<td>
</td>
<td>&lt;path&gt;\jwapi\&lt;version&gt;\Win32API\jwaWindows</td>
<td><strong>2nd choice:</strong><br />
Allows to browse Jwa identifiers in Delphi.
</td>
</tr>
<tr>
<td>Library Paths</td>
<td>&lt;path&gt;\jwapi\&lt;version&gt;\Win32API</td>
<td><strong>1st choice:</strong><br />
Tells Delphi where to find JwaXXXX.pas</td>
</tr>
<tr>
<td>
</td>
<td>&lt;path&gt;\jwapi\&lt;version&gt;\Packages\&lt;packages&gt;\bin\release\dynamic</td>
<td><strong>2nd choice:</strong><br />
Tells Delphi where to find JwaWindows.dcu
</td>
</tr>
<tr>
<td>
</td>
<td>&lt;path&gt;\jwapi\&lt;version&gt;\COM</td>
<td>
<p>Tells Delphi where to find COM Type Libraries used by JEDI API&amp;WSCL</p>
</td>
</tr>
</tbody>
</table>
<p>These settings are also available as <a href="http://jedi-apilib.svn.sourceforge.net/viewvc/jedi-apilib/jwscl/trunk/documentation/Path%20Settings.txt?view=log" target="_blank">documentation</a> in the Subversion Repository.</p>
<h2>Subversion</h2>
<p><a href="http://sourceforge.net/svn/?group_id=121894">Sourceforge </a>gives a short introduction how you can access the Subversion repository of the JEDI project.</p>
<p>The download packages (from Sourceforge) contain Subversion information so you can use your subversion tool to just update them. (Tortoisesvn: Right click the JWA folder and choose Subversion Update)</p>
<p>To get the latest release updates directly you can use this path with your Subversion client. Be aware that new versions (currently 2.2a) can make this path obsolete (but still valid). The downloadable release packages are already provided with Subversion information so you can just update them to get the newest updates.<br />
 Click on the turtle to checkout the repository with TortoiseSVN.</p>
<table border="0">
<tbody>
<tr>
<td><a href="tsvn:https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/branches/2.3"><img class="size-full wp-image-387 alignnone" title="tortoisecheckout" src="http://blog.delphi-jedi.net/wp-content/uploads/2007/12/tortoisecheckout.png" alt="Checkout with TortoiseSVN" width="48" height="48" /></a></td>
<td>https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/branches/2.3</td>
</tr>
</tbody>
</table>
<p><a href="tsvn:https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/branches/2.2a"></a></p>
<p>There is also a development branch that contains new untested features. Use it with care:</p>
<table border="0">
<tbody>
<tr>
<td><a href="tsvn:https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi"><img class="size-full wp-image-387 alignnone" title="tortoisecheckout" src="http://blog.delphi-jedi.net/wp-content/uploads/2007/12/tortoisecheckout.png" alt="Checkout with TortoiseSVN" width="48" height="48" /></a></td>
<td>https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2007/12/27/how-to-setup-the-library/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

