S60 平台:应用程序进程管理
应用程序进程管理
作者:Mark15021
邮箱: Mark15021@devdiv.com
适用平台:S60 V2 V3 V5
开发工具:Carbide.C++
摘要:进程介绍,枚举进程相关信息,启动进程,杀死进程,进程监控
应用程序进程介绍
进程是操作系统结构的基础,是一个正在执行的程序。计算机中正在运行的程序实例,可以分配给处理器并由处理器执行的一个实体。由单一顺序的执行显示,一个当前状态和一组相关的系统资源所描述的活动单元。进程即然是运行程序的实例是如此的重要,那么进程管理就会更加重要和必须了。下需就让我们进入进程管理的相关介绍吧。
枚举进程相关信息
得到进程相关信息是我们经常要用到的。那么如何得到进程信息呢?比如UID,进程名,进程的路径等等。
void CProcessManage::GetAllProcessInfo()
{
//得到所有进程信息
TApaAppInfo appInfo;
RApaLsSession apaSession;
User::LeaveIfError( apaSession.Connect() );
CleanupClosePushL( apaSession );
User::LeaveIfError( apaSession.GetAllApps() );
//枚举所有的应用程序
while ( apaSession.GetNextApp( appInfo ) == KErrNone )
{
appInfo.iFullName;//得到应用程序的EXE的全路径
//得到应用程序全路径这是一个比较重要的信息,试想如果我们有这样一个需求
//判断应用程序是否是系统进程,怎么办呢?应用程序全路径的作用就出来了。
//我们在全路径里查找”Z:”如果路径中有”Z:”字符串我们就认为是系统进程。
appInfo.iCaption;//得到应用程序的名字
appInfo.iShortCaption; //得到应用程序的名字
appInfo.iUid.Name();//得到应用程序的UID
备注:在这里可以得到所有的应用程序包括JAVA应用程序,那么JAVA应用程序和
Symbian应用程序有什么区别呢。或者说我们希望得到JAVA应用程序应用怎么办呢?
if(appInfo.iFullName.FindF(appInfo.iUid.Name()) != -1)
{
//此办法在V2上可以得到是JAVA应用程序
}
if(appInfo.iFullName.Right(8).CompareF(_L(".fakeapp")) == 0)
{
//此办法在V3V5上可以得到是JAVA应用程序
}
备注:关于JAVA应用程序的启动或者更多信息不在本篇文章的讨论范围之类,更详细的信息请参考我的blog: http://www.devdiv.com/blog/space-9147-do-blog-id-1212.html
}
CleanupStack::PopAndDestroy();//close apaSession
}
启动进程
更多的时候我们得到了进程的相关信息后,我们要对进程进行管理。其实启动进程是一个经常要用到的。比如我们设计一种CS结构架应用程序。而Server进程必须长注后台并且必须一直存在。但是因为某些特定的条件导致Server进程挂了怎么办呢?那么如果能保证Client进程仍然能启动Server进程那就能解决问题了。那么让我们来看看如何启动进程吧。那么如果我们想启动进程,必须要知道进程的相关信息才能启动进程。比如进程的UID,进程的路径,进程的名字等等。在这里除了进程的UID和进程全路径唯一之外,其他数据都不可能完全唯一。那在这里我们不去着重讨论这些情况了。首先就假设我们知道相应进程的UID看我们如何启动进程了。
启动进程其实方法比较多,在这里介绍二种方法。
方法1:
void CUsuallyTools::StartApp(const TUid& aUid)
{
RApaLsSession ras;
User::LeaveIfError(ras.Connect());
CleanupClosePushL(ras);
TThreadId threadId;
//在这里可以根据进程句柄监听进程的状态
TInt err = ras.StartDocument(_L(""), aUid, threadId);
CleanupStack::Pop();
}
方法2:
void CUsuallyTools::StartApp(const TUid& aUid)
{
RApaLsSession ras;
User::LeaveIfError(ras.Connect());
CleanupClosePushL(ras);
TApaAppInfo appInfo;
ras.GetAppInfo(appInfo,aUid); //appUid是要启动程序的UID
CApaCommandLine*cmd = CApaCommandLine::NewLC();
cmd->SetExecutableNameL(appInfo.iFullName);
cmd->SetCommandL(EApaCommandRun);
ras.StartApp(*cmd);
CleanupStack::PopAndDestroy(cmd);
CleanupStack::Pop();
}
Kill进程
进程的查杀也是非常重要,或者说是常用技巧。比如我们有这样的需求做一个杀毒软件。还有一些特别的场合需要处理,比如在手机平台上经常会出现多实例的情况。也就是说
自己的应用程序出现二个实例。这样就会导致很多问题产生。那么杀死进程就是我们必须学习到的技巧了。在这里假设我们知道了进程的名字,我们来根据名字来Kill进程。
void KillProcess(const TDesC& aProcessName)
{
TFullName name;
TFindProcess finder;
while(finder.Next(name) == KErrNone)
{
//查找所有进程判断是否有你指定的进程
if(name.FindF(aProcessName) != KErrNotFound)
{
//找到了指定的进程
RProcess process;
if(process.Open(finder, EOwnerProcess) == KErrNone) // Open process
{
process.Kill(KErrNone); // Kill process
process.Close();
break;
}
}
}
}
进程监控
进程监控我们会在有些项目中用到,这个功能应该实于进阶层。暂时把他定位于高级应用吧。
好的应用用在坏的地方那就威力无比了。比如我们用进程相互守候,当发现其中一个进程挂了,就直接把他启来,这样会产生什么后果。这样的后果会导致安装了相关SIS的应用程序卸载不了。此问题不在本文的讨论范围之类,本文只作技术层面的探讨与学习。当然这里的监控其实就是检查程序退出了没有,让我们来看看如何实现。
其实进程和线程的监控只需要得到进程或者线程的句柄可以了。
得到进程的句柄方法很多,我们可以根据名字,也可以根据进程ID。下面我们就以名字为参数来看看如何处理吧。限于篇幅的原因我们不能附上完整的代码。只把最核心的代码附上吧。以下代码假定您已经具备了一定的经验,并且能熟练了解活动对象的基础上。
void StartMonitor (const TDesC& aProcessName)
{
TFullName name;TFindProcess finder;
while(finder.Next(name) == KErrNone)
{
//查找所有进程判断是否有你指定的进程
if(name.FindF(aProcessName) != KErrNotFound)
{
//找到了指定的进程
RProcess process;//这里的process应该是全局的参数
//在这里写成局部变量,易于理解
if(process.Open(finder, EOwnerProcess) == KErrNone) // Open process
{
process.Logon(iStatus);
SetActive();
}
}
}
}
//当指定进程退出后,活动对象runL中回调。
void CMonitorProcess::RunL()
{
if(iStatus == KErrNone)
{
iThread.ExitReason();//这里可以得到程序退出的原因
}
}
应用程序进程管理
作者:Mark15021
邮箱: Mark15021@devdiv.com
适用平台:S60 V2 V3 V5
开发工具:Carbide.C++
摘要:进程介绍,枚举进程相关信息,启动进程,杀死进程,进程监控
应用程序进程介绍
进程是操作系统结构的基础,是一个正在执行的程序。计算机中正在运行的程序实例,可以分配给处理器并由处理器执行的一个实体。由单一顺序的执行显示,一个当前状态和一组相关的系统资源所描述的活动单元。进程即然是运行程序的实例是如此的重要,那么进程管理就会更加重要和必须了。下需就让我们进入进程管理的相关介绍吧。
枚举进程相关信息
得到进程相关信息是我们经常要用到的。那么如何得到进程信息呢?比如UID,进程名,进程的路径等等。
void CProcessManage::GetAllProcessInfo()
{
//得到所有进程信息
TApaAppInfo appInfo;
RApaLsSession apaSession;
User::LeaveIfError( apaSession.Connect() );
CleanupClosePushL( apaSession );
User::LeaveIfError( apaSession.GetAllApps() );
//枚举所有的应用程序
while ( apaSession.GetNextApp( appInfo ) == KErrNone )
{
appInfo.iFullName;//得到应用程序的EXE的全路径
//得到应用程序全路径这是一个比较重要的信息,试想如果我们有这样一个需求
//判断应用程序是否是系统进程,怎么办呢?应用程序全路径的作用就出来了。
//我们在全路径里查找”Z:”如果路径中有”Z:”字符串我们就认为是系统进程。
appInfo.iCaption;//得到应用程序的名字
appInfo.iShortCaption; //得到应用程序的名字
appInfo.iUid.Name();//得到应用程序的UID
备注:在这里可以得到所有的应用程序包括JAVA应用程序,那么JAVA应用程序和
Symbian应用程序有什么区别呢。或者说我们希望得到JAVA应用程序应用怎么办呢?
if(appInfo.iFullName.FindF(appInfo.iUid.Name()) != -1)
{
//此办法在V2上可以得到是JAVA应用程序
}
if(appInfo.iFullName.Right(8).CompareF(_L(".fakeapp")) == 0)
{
//此办法在V3V5上可以得到是JAVA应用程序
}
备注:关于JAVA应用程序的启动或者更多信息不在本篇文章的讨论范围之类,更详细的信息请参考我的blog: http://www.devdiv.com/blog/space-9147-do-blog-id-1212.html
}
CleanupStack::PopAndDestroy();//close apaSession
}
启动进程
更多的时候我们得到了进程的相关信息后,我们要对进程进行管理。其实启动进程是一个经常要用到的。比如我们设计一种CS结构架应用程序。而Server进程必须长注后台并且必须一直存在。但是因为某些特定的条件导致Server进程挂了怎么办呢?那么如果能保证Client进程仍然能启动Server进程那就能解决问题了。那么让我们来看看如何启动进程吧。那么如果我们想启动进程,必须要知道进程的相关信息才能启动进程。比如进程的UID,进程的路径,进程的名字等等。在这里除了进程的UID和进程全路径唯一之外,其他数据都不可能完全唯一。那在这里我们不去着重讨论这些情况了。首先就假设我们知道相应进程的UID看我们如何启动进程了。
启动进程其实方法比较多,在这里介绍二种方法。
方法1:
void CUsuallyTools::StartApp(const TUid& aUid)
{
RApaLsSession ras;
User::LeaveIfError(ras.Connect());
CleanupClosePushL(ras);
TThreadId threadId;
//在这里可以根据进程句柄监听进程的状态
TInt err = ras.StartDocument(_L(""), aUid, threadId);
CleanupStack::Pop();
}
方法2:
void CUsuallyTools::StartApp(const TUid& aUid)
{
RApaLsSession ras;
User::LeaveIfError(ras.Connect());
CleanupClosePushL(ras);
TApaAppInfo appInfo;
ras.GetAppInfo(appInfo,aUid); //appUid是要启动程序的UID
CApaCommandLine*cmd = CApaCommandLine::NewLC();
cmd->SetExecutableNameL(appInfo.iFullName);
cmd->SetCommandL(EApaCommandRun);
ras.StartApp(*cmd);
CleanupStack::PopAndDestroy(cmd);
CleanupStack::Pop();
}
Kill进程
进程的查杀也是非常重要,或者说是常用技巧。比如我们有这样的需求做一个杀毒软件。还有一些特别的场合需要处理,比如在手机平台上经常会出现多实例的情况。也就是说
自己的应用程序出现二个实例。这样就会导致很多问题产生。那么杀死进程就是我们必须学习到的技巧了。在这里假设我们知道了进程的名字,我们来根据名字来Kill进程。
void KillProcess(const TDesC& aProcessName)
{
TFullName name;
TFindProcess finder;
while(finder.Next(name) == KErrNone)
{
//查找所有进程判断是否有你指定的进程
if(name.FindF(aProcessName) != KErrNotFound)
{
//找到了指定的进程
RProcess process;
if(process.Open(finder, EOwnerProcess) == KErrNone) // Open process
{
process.Kill(KErrNone); // Kill process
process.Close();
break;
}
}
}
}
进程监控
进程监控我们会在有些项目中用到,这个功能应该实于进阶层。暂时把他定位于高级应用吧。
好的应用用在坏的地方那就威力无比了。比如我们用进程相互守候,当发现其中一个进程挂了,就直接把他启来,这样会产生什么后果。这样的后果会导致安装了相关SIS的应用程序卸载不了。此问题不在本文的讨论范围之类,本文只作技术层面的探讨与学习。当然这里的监控其实就是检查程序退出了没有,让我们来看看如何实现。
其实进程和线程的监控只需要得到进程或者线程的句柄可以了。
得到进程的句柄方法很多,我们可以根据名字,也可以根据进程ID。下面我们就以名字为参数来看看如何处理吧。限于篇幅的原因我们不能附上完整的代码。只把最核心的代码附上吧。以下代码假定您已经具备了一定的经验,并且能熟练了解活动对象的基础上。
void StartMonitor (const TDesC& aProcessName)
{
TFullName name;TFindProcess finder;
while(finder.Next(name) == KErrNone)
{
//查找所有进程判断是否有你指定的进程
if(name.FindF(aProcessName) != KErrNotFound)
{
//找到了指定的进程
RProcess process;//这里的process应该是全局的参数
//在这里写成局部变量,易于理解
if(process.Open(finder, EOwnerProcess) == KErrNone) // Open process
{
process.Logon(iStatus);
SetActive();
}
}
}
}
//当指定进程退出后,活动对象runL中回调。
void CMonitorProcess::RunL()
{
if(iStatus == KErrNone)
{
iThread.ExitReason();//这里可以得到程序退出的原因
}
}