以不同用户身份运行程序(使用CreateProcessAsUser函数)cool

http://blog.sina.com.cn/s/blog_65977dde0100s7tm.html

--------------------------------------------------

以不同用户身份运行程序

(2011-07-09 09:15:25)

一直想方便的处理CCProxy代理的帐号管理,所以梦想做一个比较好的管理工具。但一个最麻烦的问题就是帐号的更新,CCProxy有一个网页管理功 能,可以加帐号,但加的帐号就是不可以立即更新。中午上网的时候发现CCProxy有一功能就是支持命令行的操作,如:
  CCProxy -reboot  重启软件
  CCProxy -reset   更新配置
  CCProxy -update  更新帐号
   
   试着改了AccInfo.ini中帐号信息,在DOS中运行CCProxy -update的确更新了账号,所以开始用PHP做管理工具,做到调用CCProxy -update时,用了PHP中的exec(),system()等函数一直没有效果,后又通过调用批处理文件来调用命令行参数都不行。 处理得正没耐心的时候,一气之下狂刷新PHP网页,电脑卡死,用进程管理器查看时发现打开了多个CCProxy进程,认真一看,除了一个CCProxy是用户进程外其它CCProxy全是system进程。认真一想有可能是运行用户身份不同所产生的结果。
  Apache服务调用的外部程序以system身份运行,自己双击运行的程序以用户身份运行。 如 果CCProxy -update以用户身份运行是不是就可以了呢?本人在网络上找到了runas这个命令,的确可以指定以哪个用户运行,但是每次都要输密码,没有密码的帐 号就要加上密码才可以用,“/savecred”这个参数可以用,只要输入一次密码就可以了,但在PHP中发现要以system的身份输入一次才行,根本 没有机会输入。打算用C程序来处理这个问题。可是发现用WinExec(),ShellExecute(),CreateProcess()都不好处理这个问题,好在发现了CreateProcessAsUser()这个函数。把网络上的程序改了几处,编译后一试问题终于解决。
   以下为相关代码:
// Update.cpp : 定义控制台应用程序的入口点。

  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include <tlhelp32.h>
  4. BOOL GetTokenByName(HANDLE &hToken,LPSTR lpName)
  5. {
  6. if(!lpName)
  7. return FALSE;
  8. HANDLE         hProcessSnap = NULL;
  9. BOOL           bRet      = FALSE;
  10. PROCESSENTRY32 pe32      = {0};
  11. hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  12. if (hProcessSnap == INVALID_HANDLE_VALUE)
  13. return (FALSE);
  14. pe32.dwSize = sizeof(PROCESSENTRY32);
  15. if (Process32First(hProcessSnap, &pe32))
  16. {
  17. do
  18. {
  19. if(!strcmp(_strupr(pe32.szExeFile),_strupr(lpName)))
  20. {
  21. HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
  22. FALSE,pe32.th32ProcessID);
  23. bRet = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);
  24. CloseHandle (hProcessSnap);
  25. return (bRet);
  26. }
  27. }
  28. while (Process32Next(hProcessSnap, &pe32));
  29. bRet = TRUE;
  30. }
  31. else
  32. bRet = FALSE;
  33. CloseHandle (hProcessSnap);
  34. return (bRet);
  35. }
  36. BOOL RunProcess(LPCSTR lpImage,LPSTR lpCommandLine)
  37. {
  38. if(!lpImage)
  39. return FALSE;
  40. HANDLE hToken;
  41. if(!GetTokenByName(hToken,"EXPLORER.EXE"))
  42. return FALSE;
  43. STARTUPINFO si;
  44. PROCESS_INFORMATION pi;
  45. ZeroMemory(&si, sizeof(STARTUPINFO));
  46. si.cb= sizeof(STARTUPINFO);
  47. si.lpDesktop = TEXT("winsta0\\default");
  48. BOOL bResult = CreateProcessAsUser(hToken,lpImage, lpCommandLine,NULL,NULL,
  49. FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
  50. CloseHandle(hToken);
  51. if(bResult)
  52. {
  53. OutputDebugString("CreateProcessAsUser ok!\r\n");
  54. printf("CreateProcessAsUser ok!\r\n");
  55. }
  56. else
  57. {
  58. OutputDebugString("CreateProcessAsUse* **lse!\r\n");
  59. printf("CreateProcessAsUse* **lse!\r\n");
  60. }
  61. return bResult;
  62. }
  63. int _tmain(int argc, _TCHAR* argv[])
  64. {
  65. RunProcess("CCProxy.exe"," -update");
  66. return 0;
  67. }

http://www.cnblogs.com/-clq/archive/2012/01/19/2326263.html

3楼 likang0712 2012-02-02 11:58发表 [回复]
谢谢 :)

2楼 santalence 2009-05-23 17:29发表 [回复]
这个方法确实很好,to aguiwang :解决 GetSaveFileName 的问题,可在调用CreateProcessAsUser前调用下面这个函数:
BOOL LoadProfile(HANDLE hToken, LPTSTR lpszUserName)
{
BOOL bRet = FALSE;

PROFILEINFO pi;
pi.dwSize = sizeof(PROFILEINFO);
pi.dwFlags = 0;
pi.lpUserName = lpszUserName;
pi.lpDefaultPath = NULL;
pi.lpPolicyPath = NULL;
pi.lpServerName = NULL;
pi.lpProfilePath = NULL;

bRet = ::LoadUserProfile(hToken, &amp;pi);

return bRet;
}

其中的lpszUsername 就是当前登陆用户名

1楼 aguiwang 2006-08-30 09:00发表 [回复]
idAnts的方法很好,但这样从服务里用CreateProcessAsUser创建的进程,还是有调用者的性质.比如在创建出来的进程里弹出Save file的common dialog是(即调用API GetSaveFileName),上面的桌面和我的文件夹还是LocalService下的,而不是当前登陆用户下的.而Localservice又没有桌面和我的文件夹目录,所以在选择桌面和我的文件夹时common dialog会出现这样的错误提示错误.C:/documents and settings/localservice/desktop refers to a location that is unavailable. It could be on a hard drive on this computer,on a network, or on a different computer on your home network. Check to make sure that the disk is properly inserted, or that you are connected to the Internet or home network, and then try again.

时间: 2024-11-08 21:50:46

以不同用户身份运行程序(使用CreateProcessAsUser函数)cool的相关文章

windows 10 中为开始菜单中的应用程序增加&ldquo;以其他用户身份运行&rdquo;菜单

最近切换到windows 10,要以其他身份来解密下RMS加密的文档,于是想以其他身份来运行下office ,但是即使是按住Shift键也看不到"以其他用户身份运行"菜单项.只好用折中的办法先运行cmd ,然后执行runas 命令.后来查找了互联网,发现组策略中有个这样的设置.看来应该设置为全域的整体配置,这样会比较方便用户. 开启方法: 效果:

C# windows权限问题 程序如何以管理员身份运行程序

程序如何以管理员身份运行程序 最近在项目运行过程中遇到了一个问题,就是打开程序的过程中,软件会出现打开数据库是一个只读数据库,我们需要将客户端设置为以管理员身份运行才能解决这种问题.这样虽然可以解决问题但是却给用户和与用与沟通的人员带来了不便,使软件的简易性与易操作性大打折扣. 那么我们能否在开发的过程中使软件直接以管理员的身份进行运行呢,答案是肯定的.结合在网上查询的资料和我个人的理解下介绍一下. 第一步:打开VS2013右键点击项目->属性->安全性->勾选启用ClickOnce安全

Win7、Win8、Win10始终以管理员身份运行程序。

Win7.Win8.Win10始终以管理员身份运行程序. 在Win7.Win8.Win10系统中,以管理员身份运行程序很麻烦,一般有以下几种方式: 1.在可执行程序或快捷方式上右键,以管理员身份运行: 2.在可执行程序或快捷方式上右键->属性->兼容性->勾选以管理员身份运行选项->确定: 3.修改安全策略,这也是一劳永逸的方式,使当前用户的所有操作以管理员身份进行,不进行询问. 本文中主要对第三种方式进行详细说明. 首先,进入用户帐户,操作顺序为:控制面板->用户帐户,如图

.NET以管理员身份运行程序

using System; using System.ComponentModel; using System.Diagnostics; using System.Windows.Forms; namespace RunAsAdministratorDemo { /// <summary> /// .NET以管理员身份运行程序 /// LDH @ 2018-1-5 /// </summary> internal class Program { /// <summary>

C# 以管理员身份运行程序

using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace MyWebBrowser { static class Program { /// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static void Main() { //获得当前登录的Windows用户标示 Sy

C# 管理员身份运行程序

在使用winform程序获取调用cmd命令提示符时,如果是win7以上的操作系统,会需要必须以管理员身份运行才会执行成功,否则无效果或提示错误. 比如在通过winform程序执行cmd命令时,某些情况下如果不是以管理员身份运行,则会提示命令无效. 或者通过winform程序执行Windows Service 服务时,也需要以管理员身份才能调用Service服务. 下面讲解一下如何使程序获取管理员权限来运行. 一: 在Visual Studio 中--解决方案资源管理器--右键项目名称--属性,找

[Winform]默认以管理员身份运行程序

摘要 在使用setupfactory打包之后,想让程序默认以管理员身份运行,因为涉及到创建文件删除文件的操作,如果权限比较低的话,会出现没有权限操作的bug. 解决办法 在项目中找到app.manifest清单文件 修改requestedExecutionLevel 的属性level为requireAdministrator <?xml version="1.0" encoding="utf-8"?> <asmv1:assembly manifes

C#默认以管理员身份运行程序实现代码

using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace yyy { static class Program { /// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static void Main(string[] Args) { /** * 当前用户是管理员的时候,直

C#默认以管理员身份运行程序

由于WIN8的权限限制,很多程序安装后没有写入权限,导致程序无法正常运行,以下是让程序以管理员身份运行,解决此问题 static void Main(string[] Args) { /** * 当前用户是管理员的时候,直接启动应用程序 * 如果不是管理员,则使用启动对象启动程序,以确保使用管理员身份运行 */ //获得当前登录的Windows用户标示 System.Security.Principal.WindowsIdentity identity = System.Security.Pri