Creating a Microsoft NET Compact Frameworkbased Process Manager Application.docx
- 文档编号:14289897
- 上传时间:2023-06-22
- 格式:DOCX
- 页数:17
- 大小:41.10KB
Creating a Microsoft NET Compact Frameworkbased Process Manager Application.docx
《Creating a Microsoft NET Compact Frameworkbased Process Manager Application.docx》由会员分享,可在线阅读,更多相关《Creating a Microsoft NET Compact Frameworkbased Process Manager Application.docx(17页珍藏版)》请在冰点文库上搜索。
CreatingaMicrosoftNETCompactFrameworkbasedProcessManagerApplication
CreatingaMicrosoft.NETCompactFramework-basedProcessManagerApplication
AlexYakhnin
IntelliProg,Inc.
March2003
Appliesto:
Microsoft®.NETCompactFramework
Microsoft®VisualStudio®.NET2003
Summary:
Learnhowtomarshalstructuresasbytearrays.(14printedpages)
DownloadProcessManager.msi.
Contents
Background
StructuresasByteArrays?
HandlingProcesses
DisplaytheResults
Conclusion
Background
The.NETCompactFrameworkprovidesmanagedinterfacestoasubstantialsetoftheWindowsCEAPIs,buttherearesomesectionsthathavenotbeencovered.ThisiswherePlatformInvoke(P/Invoke)servicescometoourrescue.P/InvokeisaservicethatenablesmanagedcodetocallunmanagedfunctionssuchasthoseintheWindowsCEAPI.
P/Invokelocatesandinvokesanexportedfunctionandmarshalsitsarguments(integers,strings,arrays,structures,andsoon)acrosstheprocessboundariesasneeded.Themarshallingsupportinthe.NETCompactFrameworkisasubsetofthatavailableonthefull.NETFramework.Forexample,the.NETCompactFrameworkcommonlanguageruntimecannotmarshalobjectswithinstructuresorreferencetypes.Thisiscalleddeepmarshalling.However,ifastructurecontainssimpletypes,theycanbemarshalediftheunmanagedcodeisabletoconformtothestructure.Therefore,inthecaseswhenanativeAPIfunctionexpectsacomplexstructurethatmayincludenestedstructuresorpointerstootherthestructures,stringsorsomeothernot-blittabletypes,itispossibletoprovideconversionofthestructurestothebytearraysandpassthemasanargumentstothenativefunctions.ItisalittlebitmoreworkthanjustsimplyconvertingthestructuredeclarationsfromCheaderfiles,butitisworthwhileintheend,especiallyiftherequirednativefunctioncallistheonlywaytoachievetherequiredfunctionality.
StructuresasByteArrays?
Whatdoweknowaboutstructures?
Intheirmostgeneralform,structuresarecollectionsofvariablesunderasinglename.Thesevariablescanbeofdifferenttypes,andeachhasanamethatisusedtoselectitfromthestructure.ForexamplethePOINTstructurehasthefollowingunmanageddefinition:
Copy
typedefstructtagPOINT
{
LONGx;
LONGy;
}POINT;
Astructureisnothingmorethanacontiguousblockofmemorycontainingsequentialdata,formattedasperitsdeclaration.WeknowthatunmanagedLONGdatatypetakes4bytesinmemory.So,onourPOINTexampleweshouldhaveanaddressinmemorywith8sequentialbytesallocatedforitsxandymembers.Thisleadsustoanotherproblem:
fromthe4bytesinmemoryforaLONGdatatypewhichbyteisthemostsignificantbyte(MSB)?
Whichistheleastsignificantbyte(LSB)?
TheanswertothesequestionscanbefoundonMSDN:
"Windowswasdesignedaroundthelittle-endianarchitecture"whichmeans"thelittleendisstoredfirst".Anumberlike0x1234isstoredinmemoryintwoconsecutivebytes:
thefirstbytecontainsthelittleend(0x34);thesecondbytecontainsthebigend(0x12).
HandlingProcesses
TheWindowsCEplatformcontainsaveryusefulDLL:
toolhelp.dll,whichimplementsasetofAPIsthatallowyoutogetinformationaboutprocessesandthreadsinsidetheseprocessesrunningonthedevice.Forexample,thefunctionCreateToolhelp32Snapshottakesasnapshotoftheprocesses,theheaps,modules,andthreadsusedbytheprocesses.Inordertoretrieveinformationaboutthefirstprocessencounteredinasystemsnapshot,theProcess32Firstisused,andProcess32Nextafterwards.ThesefunctionsreturninformationaboutprocessesinthePPROCESSENTRY32structurethathasthefollowingunmanageddefinition:
Copy
typedefstructtagPROCESSENTRY32
{
DWORDdwSize;
DWORDcntUsage;
DWORDth32ProcessID;
DWORDth32DefaultHeapID;
DWORDth32ModuleID;
DWORDcntThreads;
DWORDth32ParentProcessID;
LONGpcPriClassBase;
DWORDdwFlags;
TCHARszExeFile[MAX_PATH];
DWORDth32MemoryBase;
DWORDth32AccessKey;
}PROCESSENTRY32;
AllmembersofthisstructureareblittabletypesexceptfortheTCHARarray(szExeFile).Forthisreason,thisstructurecannotbeautomaticallymarshaledbythe.NETCompactFramework.Hereiswheretheknowledgethatastructureissimplyabytearraycomesinhandy.WecancovertthisstructuretoabytearrayandpassthattotheWindowsCEAPI.
Let'sstartfromcreationthePROCESSENTRY32classandinsertinganoffsetsforeachmemberdefinedinthisstructure:
Copy
privateclassPROCESSENTRY32
{
//constantsforstructuredefinition
privateconstintSizeOffset=0;
privateconstintUsageOffset=4;
privateconstintProcessIDOffset=8;
privateconstintDefaultHeapIDOffset=12;
privateconstintModuleIDOffset=16;
privateconstintThreadsOffset=20;
privateconstintParentProcessIDOffset=24;
privateconstintPriClassBaseOffset=28;
privateconstintdwFlagsOffset=32;
privateconstintExeFileOffset=36;
privateconstintMemoryBaseOffset=556;
privateconstintAccessKeyOffset=560;
privateconstintSize=564;//thewholesizeofthestructure
privateconstintMAX_PATH=260;
//datamembers
publicuintdwSize;
publicuintcntUsage;
publicuintth32ProcessID;
publicuintth32DefaultHeapID;
publicuintth32ModuleID;
publicuintcntThreads;
publicuintth32ParentProcessID;
publicintpcPriClassBase;
publicuintdwFlags;
publicstringszExeFile;
publicuintth32MemoryBase;
publicuintth32AccessKey;
}
Thereareseveralwaystopushthesesimpledatatypesintoabytearray.I'vechosentousetheSystem.BitConverterclass.Thisclassconvertsbasedatatypestoanarrayofbytes,andarraysofbytestobasedatatypes.Bytheway:
theimplementationofthisclassshouldtakecareofthebyteorder("endianess")inwhichdataisstoredinanydevice.SowecanaddthefollowinghelperfunctionsintothePROCESSENTRY32class:
Copy
//utility:
getauintfromthebytearray
privatestaticuintGetUInt(byte[]aData,intOffset)
{
returnBitConverter.ToUInt32(aData,Offset);
}
//utility:
setauintintothebytearray
privatestaticvoidSetUInt(byte[]aData,intOffset,intValue)
{
byte[]buint=BitConverter.GetBytes(Value);
Buffer.BlockCopy(buint,0,aData,Offset,buint.Length);
}
//utility:
getaushortfromthebytearray
privatestaticushortGetUShort(byte[]aData,intOffset)
{
returnBitConverter.ToUInt16(aData,Offset);
}
//utility:
setaushortintthebytearray
privatestaticvoidSetUShort(byte[]aData,intOffset,intValue)
{
byte[]bushort=BitConverter.GetBytes((short)Value);
Buffer.BlockCopy(bushort,0,aData,Offset,bushort.Length);
}
Andforconversionofthestringdatatype,wecanusetheSystem.Text.Encodingclass:
Copy
//utility:
getaunicodestringfromthebytearray
privatestaticstringGetString(byte[]aData,intOffset,intLength)
{
StringsReturn=Encoding.Unicode.GetString(aData,Offset,Length);
returnsReturn;
}
//utility:
setaunicodestringinthebytearray
privatestaticvoidSetString(byte[]aData,intOffset,stringValue)
{
byte[]arr=Encoding.ASCII.GetBytes(Value);
Buffer.BlockCopy(arr,0,aData,Offset,arr.Length);
}
Atthispoint,weshouldbeabletoaddtheconstructortothePROCESSENTRY32classthatacceptsthebytearrayandpopulatesallthemembersofthe"virtual"structure:
Copy
//createaPROCESSENTRYinstancebasedonabytearray
publicPROCESSENTRY32(byte[]aData)
{
dwSize=GetUInt(aData,SizeOffset);
cntUsage=GetUInt(aData,UsageOffset);
th32ProcessID=GetUInt(aData,ProcessIDOffset);
th32DefaultHeapID=GetUInt(aData,DefaultHeapIDOffset);
th32ModuleID=GetUInt(aData,ModuleIDOffset);
cntThreads=GetUInt(aData,ThreadsOffset);
th32ParentProcessID=GetUInt(aData,ParentProcessIDOffset);
pcPriClassBase=(long)GetUInt(aData,PriClassBaseOffset);
dwFlags=GetUInt(aData,dwFlagsOffset);
szExeFile=GetString(aData,ExeFileOffset,MAX_PATH);
th32MemoryBase=GetUInt(aData,MemoryBaseOffset);
th32AccessKey=GetUInt(aData,AccessKeyOffset);
}
TheAPIReferencesuggeststhatthedwSizememberbesetwiththesizeofthePROCESSENTRY32structure;otherwisethecalltotheProcess32Firstwillfail.So,theToByteArraymethodshouldtakecareofallocatingtherequiredmemoryandsettingthedwSizemember:
Copy
//createaninitializeddataarray
publicbyte[]ToByteArray()
{
byte[]aData;
aData=newbyte[Size];
//settheSizemember
SetUInt(aData,SizeOffset,Size);
returnaData;
}
Let'sjustaddafewpropertiestothePROCESSENTRY32classtoexposesomeofthemostinterestingmembers:
Copy
publicstringName
{
get
{
returnszExeFile.Substring(0,szExeFile.IndexOf('\0'));
}
}
publiculongPID
{
get
{
returnth32ProcessID;
}
}
publiculongBaseAddress
{
get
{
returnth32MemoryBase;
}
}
publiculongThreadCount
{
get
{
returncntThreads;
}
}
AndofcourseweshouldnotforgetaboutaP/Invokefunctiondeclarations:
Copy
privateconstintTH32CS_SNAPPROCESS=0x00000002;
[DllImport("toolhelp.dll")]
publicstaticexternIntPtrCreateToolhelp32Snapshot(uintflags,uintprocessid);
[DllImport("toolhelp.dll")]
publicstaticexternintCloseToolhelp32Snapshot(IntPtrhandle);
[DllImport("toolhelp.dll")]
publicstaticexternintProcess32First(IntPtrhandle,byte[]pe);
[DllImport("toolhelp.dll")]
publicstaticexternintProcess32Next(IntPtrhandle,byte[]pe);
[DllImport("coredll.dll")]
privatestaticexternIntPtrOpenProcess(intflags,boolfInherit,intPID);
privateconstintPROCESS_TERMINATE=1;
[DllImport("coredll.dll")]
privatestaticexternboolTerminateProcess(IntPtrhProcess,uintExitCo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Creating Microsoft NET Compact Frameworkbased Process Manager Application
![提示](https://static.bingdoc.com/images/bang_tan.gif)
链接地址:https://www.bingdoc.com/p-14289897.html