Forum Discussion

Gadzilla's avatar
Gadzilla
Contributor
14 years ago

How to set process affinity from JScript

Could you please explain whether it is possible to set process affinity from JScript?

I am trying translate VBscript from the following thread into JScript

http://www.automatedqa.com/newsgroups/d.cgi?cmd=article&group=automatedqa.public.testcomplete&item=35676&utag

but looks like this does not work for me.



My script is the following:




function getProcessAffinity(iProcID)

{

  var ProcessAffinityMask, SystemAffinityMask;

  var Kernel32Def, Kernel32Lib;

  var ProcHandle, R;





  Kernel32Def = DLL.DefineDLL("Kernel32");

  Kernel32Def.DefineProc("GetProcessAffinityMask", vt_i4, vt_byref | vt_i4, vt_byref | vt_i4, vt_bool);

  Kernel32Lib = DLL.Load("Kernel32");





  ProcHandle = Win32API.OpenProcess(Win32API.PROCESS_ALL_ACCESS, true, iProcID);

  R = Kernel32Lib.GetProcessAffinityMask(ProcHandle, ProcessAffinityMask, SystemAffinityMask);

  Win32API.CloseHandle(ProcHandle);





  return [ProcessAffinityMask, SystemAffinityMask];

}


"Kernel32Lib.GetProcessAffinityMask(...)" line returns true, but "ProcessAffinityMask" and "SystemAffinityMask" variable still undefined after execution of this line of code.



The same situation for setProcessAffinity function:




function setProcessAffinity(iProcID, iAffinityMask)

{

  var Kernel32Def, Kernel32Lib;

  var ProcHandle, R;





  Kernel32Def = DLL.DefineDLL("Kernel32");

  Kernel32Def.DefineProc("SetProcessAffinityMask", vt_i4, vt_i4, vt_bool);

  Kernel32Lib = DLL.Load("Kernel32");





  ProcHandle = Win32API.OpenProcess(Win32API.PROCESS_ALL_ACCESS, true, iProcID);

  R = Kernel32Lib.SetProcessAffinityMask(ProcHandle, iAffinityMask);

  Win32API.CloseHandle(ProcHandle)

  return R;

}


"Kernel32Lib.SetProcessAffinityMask()" line returns false, and process affinity is not settled up on any Win platform.



Could somebody help me to solve the problem?



Thanks in advance.

3 Replies


  • Hi John,





    AFAIK, this function involves calling the SetProcessAffinityMask API function to set the affinity and the OpenProcess function to obtain the target process handle. There's a problem with this - JScript/C#Script/C++Script cannot call functions that accept pointers as parameters. Such parameters should be passed by a reference, which is unsupported in JScript. 





    If you need to set the affinity from your JScript code, I suggest that you try using the following function:



    function SetProcessAffinity(app, affinity)

    {

      var affinityPtr = dotNET.System.IntPtr.zctor(affinity);

      var process = dotNET.System_Diagnostics.Process.GetProcessById(app.ProcessID);

      process.ProcessorAffinity = affinityPtr;

    }

    ...

      var app = Sys.Process("MyApp");

      SetProcessAffinity(app, 1);

    ...







    To make this function work, you need to add the System.dll assembly to the list of available assemblies in the project's CLR Bridge property (Project Explorer | <double-click your project>| Properties | CLR Bridge).





    Does this help?
  • Hi David,


    Thanks for your help!


    Your suggestion was helpful, but only partially. Function provided by you works fine only on XP platform. But I failed at attempt to run this function on Vista, Server 2008 R2 and Win 7 platforms (both x32 and x64 bit platforms).


    I am following all the steps described in “Calling Functions From .Net Assemblies” topic, but attempt to run your function on platforms described above leads to “dotNet undefined” error message appearing.


    Also in the “Calling Functions From .Net Assemblies” topic described that In order for the script engine to be able to call functions of .NET assemblies, TestComplete loads these assemblies into a special helper process. But this process is displayed only on XP and Vista platform (on Server 2008 and Win 7 it not available after following all the steps described in the topic).


    The problem is that I should set process affinity especially on Vista, Server 2008 and Win 7 platform.


    In our test cases, I work a lot with Explorer.exe and iexplore.exe processes. But these processes are very often crashes on Vista, 2008 and Win7 platforms (especially which are installed on multi-core PC) during the test cases run (description of my problem you can find here: http://www.automatedqa.com/forums/forum/post/?mode=singlethread&thread=2dfcc8b3-97e2-49cf-9201-f933a138b481). 


    I noticed that these applications crash much less when I set affinity of these processes to 1. But I can't set process affinity on Vista, Server 2008 and Win 7 platforms using .Net assemblies.


    Could someone help me to solve any of my problems?



    Thanks.


  • Hi John,





    You shouldn't face any issues with this script on Vista, Windows 7, and Windows Server 2008 operating systems. The error message you get makes me suppose that the ".NET Classes Support" plug-in is either not installed, or corrupted in some way. Please make sure that the plug-in is enabled (File | Install Extension...). If it is, but the issue still persists, make sure that .NET framework v.4 is not installed on the problematic machines. This version of the framework is not supported by the current version of TC. Installing .NET 4 may cause different problems. If this is the case, please contact us via the web form, we'll provide you with a fix for the issue.