DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: jeff1314
今日帖子: 10
在线用户: 7
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/21 11:46:25
标题:
求教!主进程以管理员模式运行,在里面运行另外进程,如何才能让其不以管理员模式运行? 浏览:3003
加入我的收藏
楼主: 求教大神,开发了一个应用,主进程A必须以管理员模式运行,在A里面启动B进程,这时候发现B进程尽然也是管理员模式,无论用WINEXEC还是SHELL方式,请问有什么方法能让A(管理员模式)进程运行B时,B以普通权限运行呢?感谢!!!!!
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/6/21 12:31:37
1楼: run as
----------------------------------------------
(C)(P)Flying Wang
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/21 12:58:35
2楼: function RunAs(User, Password, Command: String): Integer;
var  dwSize:        DWORD;
     hToken:        THandle;
     lpvEnv:        Pointer;
     pi:          TProcessInformation;
     si:          TStartupInfo;
     szPath:        Array [0..MAX_PATH] of WideChar;
begin
  ZeroMemory(@szPath, SizeOf(szPath));
  ZeroMemory(@pi, SizeOf(pi));
  ZeroMemory(@si, SizeOf(si));
  si.cb:=SizeOf(TStartupInfo);

  if LogonUser(PChar(User), nil, PChar(Password), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken) then
  begin
     if CreateEnvironmentBlock(lpvEnv, hToken, True) then
     begin
        dwSize:=SizeOf(szPath) div SizeOf(WCHAR);
        if (GetCurrentDirectoryW(dwSize, @szPath) > 0) then
        begin
          if (CreateProcessWithLogon(PWideChar(WideString(User)), nil, PWideChar(WideString(Password)),
          LOGON_WITH_PROFILE, nil, PWideChar(WideString(Command)), CREATE_UNICODE_ENVIRONMENT,
          lpvEnv, szPath, si, pi)) then
          begin
          result:=ERROR_SUCCESS;
          CloseHandle(pi.hProcess);
          CloseHandle(pi.hThread);
          end
          else
          result:=GetLastError;
        end
        else
          result:=GetLastError;
        DestroyEnvironmentBlock(lpvEnv);
     end
     else
        result:=GetLastError;
     CloseHandle(hToken);
  end
  else
     result:=GetLastError;
end;

@wang_80919 如何以普通权限运行呢?求教
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2017/6/21 15:00:39
3楼: 用createprocessasuser就可以了。
以当前资源管理器进程的token作为createprocessasuser的token就可以创建一个普通权限的进程了。
----------------------------------------------
--
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/22 11:45:20
4楼: 找到一个代码,可惜实在能力有限,没法转DELPHI,求大神出手帮忙译成DELPHI吧!!!不胜感激!!!
----------------------------------------------
-
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/22 11:45:44
5楼: -------- CreateProcessEx.h文件 --------
#ifndef _CREATE_PROCESS_EX_H_
#define _CREATE_PROCESS_EX_H_
#include <windows.h>
#include "tchar.h"
#pragma comment(lib, "shell32")
#pragma comment(lib, "user32")
#pragma comment(lib, "Advapi32.lib")

//以普通权限启动进程
BOOL CreateProcessLow(TCHAR * lpApplicationName, 
 TCHAR * lpCommandLine = NULL, 
 TCHAR * lpDirectory = NULL,
 UINTnShow = SW_SHOWNORMAL);
//以管理员权限启动进程
BOOL CreateProcessHigh(TCHAR * strProcessName, 
 TCHAR * strCommandLine = NULL, 
 TCHAR * lpDirectory = NULL,
 UINTnShow = SW_SHOWNORMAL);
#endif //_CREATE_PROCESS_EX_H_
-------- CreateProcessEx.h文件 --------


-------- CreateProcessEx.cpp文件 --------
#include "CreateProcessEx.h"
#include <string>
using namespace std;

typedef BOOL (WINAPI *F_CreateProcessWithTokenW)(
__in          HANDLE hToken,
__in          DWORD dwLogonFlags,
__in          LPCWSTR lpApplicationName,
__in          LPWSTR lpCommandLine,
__in          DWORD dwCreationFlags,
__in          LPVOID lpEnvironment,
__in          LPCWSTR lpCurrentDirectory,
__in          LPSTARTUPINFOW lpStartupInfo,
__out         LPPROCESS_INFORMATION lpProcessInfo
);

HANDLE DupExplorerToken();
BOOL IsVistaOrLater();
BOOL IsAdminPrivilege();


//以普通权限启动进程
BOOL CreateProcessLow(TCHAR * lpApplicationName, 
 TCHAR * lpCommandLine, 
 TCHAR * lpDirectory,
 UINTnShow)
{
if (!IsVistaOrLater()
|| !IsAdminPrivilege())
{
HINSTANCE hRet = ShellExecute(NULL, _T("open"), lpApplicationName, lpCommandLine, lpDirectory, nShow);
return ((int)hRet > 32);
}
HANDLE hToken = DupExplorerToken();

if (hToken == NULL)
return FALSE;

static HMODULE hDll = LoadLibrary(_T("ADVAPI32.dll"));
if (!hDll)
{
CloseHandle(hToken);
return FALSE;
}
F_CreateProcessWithTokenW pfn = (F_CreateProcessWithTokenW)GetProcAddress(hDll, "CreateProcessWithTokenW");
if (!pfn)
{
CloseHandle(hToken);
return FALSE;
}

STARTUPINFO si = {sizeof(STARTUPINFO)};
PROCESS_INFORMATION pi = {0};
BOOL ret = pfn(hToken, 
LOGON_WITH_PROFILE, 
lpApplicationName, 
lpCommandLine, 
NORMAL_PRIORITY_CLASS, 
NULL, 
lpDirectory, 
&si, 
&pi);
if (ret)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}

CloseHandle(hToken);
return ret;
}

//以管理员权限启动进程
BOOL CreateProcessHigh(TCHAR * lpApplicationName, 
  TCHAR * lpCommandLine, 
  TCHAR * lpDirectory,
  UINTnShow)
{
#ifdef _UNICODE
wstring command;
#else
string command;
#endif

if (lpCommandLine)
{
command = lpCommandLine;
}
if (IsVistaOrLater()
&& !IsAdminPrivilege())
{
command += _T(" -Admin");
}

HINSTANCE hRet = ShellExecute(NULL, _T("runas"), lpApplicationName, command.c_str(), lpDirectory, nShow);
return ((int)hRet > 32);
}


HANDLE DupExplorerToken()
{
DWORD dwPid = 0;
HWND hwnd = FindWindow(_T("Shell_TrayWnd"), NULL);
if (NULL == hwnd)
return NULL;

GetWindowThreadProcessId(hwnd, &dwPid);
if (dwPid == 0)
return NULL;

HANDLE hExplorer = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
if (hExplorer == NULL)
return NULL;

HANDLE hToken = NULL;
OpenProcessToken(hExplorer, TOKEN_DUPLICATE, &hToken);
CloseHandle(hExplorer);

HANDLE hNewToken = NULL;
DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hNewToken);
CloseHandle(hToken);

return hNewToken;
}

BOOL IsVistaOrLater()
{
OSVERSIONINFOEX version = {sizeof(OSVERSIONINFOEX)};
if (!GetVersionEx((LPOSVERSIONINFO)&version))
{
version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx((LPOSVERSIONINFO)&version))
{
return FALSE;
}
}

return (version.dwMajorVersion >= 6);
}

BOOL IsAdminPrivilege()
{
BOOL bIsAdmin = FALSE;
BOOL bRet = FALSE;
SID_IDENTIFIER_AUTHORITY idetifier = SECURITY_NT_AUTHORITY;
PSID pAdministratorGroup;
if (AllocateAndInitializeSid(
&idetifier,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0,0,0,0,0,0,
&pAdministratorGroup))
{
if (!CheckTokenMembership(NULL, pAdministratorGroup, &bRet))
{
bIsAdmin = FALSE;
}
if (bRet)
{
bIsAdmin = TRUE;
}
FreeSid(pAdministratorGroup);
}

return bIsAdmin;
}
-------- CreateProcessEx.cpp文件 -------
----------------------------------------------
-
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/22 13:58:47
6楼: 武大侠以前写过一个,但实际运行发现A是ADMIN时,被运行的B也是ADMIN、、、

{ **********

以低权限启动一个进程(例如IE)

版权所有 (C) 2013 wr960204 武稀松

********** }

unit LowIntergrityLevelProcess;

interface

uses
WinApi.Windows;

const
SECURITY_MANDATORY_UNTRUSTED_RID = $00000000;
SECURITY_MANDATORY_LOW_RID = $00001000;
SECURITY_MANDATORY_MEDIUM_RID = $00002000;
SECURITY_MANDATORY_HIGH_RID = $00003000;
SECURITY_MANDATORY_SYSTEM_RID = $00004000;
SECURITY_MANDATORY_PROTECTED_PROCESS_RID = $00005000;

function CreateLowIntegrityProcess(const ExeName: string;
const Params: string = ”; TimeOut: DWORD = 0): HResult;
function GetIntegrityLevel(): DWORD;

implementation

type
PTokenMandatoryLabel = ^TTokenMandatoryLabel;

TTokenMandatoryLabel = packed record
Label_: TSidAndAttributes;
end;

function GetIntegrityLevel(): DWORD;
var
hProcess, hToken: THandle;
pTIL: PTokenMandatoryLabel;
dwReturnLength: DWORD;
dwTokenUserLength: DWORD;
psaCount: PUCHAR;
SubAuthority: DWORD;
begin
Result := 0;
dwReturnLength := 0;
dwTokenUserLength := 0;
pTIL := nil;

hProcess := GetCurrentProcess();
OpenProcessToken(hProcess, TOKEN_QUERY or TOKEN_QUERY_SOURCE, hToken);
if hToken = 0 then
Exit;
if not GetTokenInformation(hToken, WinApi.Windows.TTokenInformationClass
(TokenIntegrityLevel), pTIL, dwTokenUserLength, dwReturnLength) then
begin
if GetLastError = ERROR_INSUFFICIENT_BUFFER then
Begin
pTIL := Pointer(LocalAlloc(0, dwReturnLength));
if pTIL = nil then
Exit;
dwTokenUserLength := dwReturnLength;
dwReturnLength := 0;

if GetTokenInformation(hToken, WinApi.Windows.TTokenInformationClass
(TokenIntegrityLevel), pTIL, dwTokenUserLength, dwReturnLength) and
IsValidSid((pTIL.Label_).Sid) then
begin
psaCount := GetSidSubAuthorityCount((pTIL.Label_).Sid);
SubAuthority := psaCount^;
SubAuthority := SubAuthority – 1;
Result := GetSidSubAuthority((pTIL.Label_).Sid, SubAuthority)^;
end;
LocalFree(Cardinal(pTIL));
End;
end;

CloseHandle(hToken);
end;

const
userenvlib = ‘userenv.dll’;

function CreateEnvironmentBlock(lpEnvironment: PPointer; hToken: THandle;
bInherit: BOOL): BOOL; stdcall; external userenvlib;
function DestroyEnvironmentBlock(lpEnvironment: Pointer): BOOL; stdcall;
external userenvlib;

function CreateLowIntegrityProcess(const ExeName, Params: string;
TimeOut: DWORD): HResult;
type
_TOKEN_MANDATORY_LABEL = Record
Label_: SID_AND_ATTRIBUTES;
End;

TOKEN_MANDATORY_LABEL = _TOKEN_MANDATORY_LABEL;
PTOKEN_MANDATORY_LABEL = ^TOKEN_MANDATORY_LABEL;

const
SECURITY_MANDATORY_LABEL_AUTHORITY: TSidIdentifierAuthority =
(Value: (0, 0, 0, 0, 0, 16));
SE_GROUP_INTEGRITY = $00000020;
SE_GROUP_INTEGRITY_ENABLED = $00000040;
var
hToken, hNewToken: THandle;
MLAuthority: SID_IDENTIFIER_AUTHORITY;
pIntegritySid: PSID;
tml: TOKEN_MANDATORY_LABEL;
si: TStartupInfo;
pi: PROCESS_INFORMATION;
pszCommandLine: string;
dwCreationFlag: DWORD;
pEnvironment: LPVOID;
begin

Result := ERROR_SUCCESS;
pszCommandLine := ExeName + Params;
hToken := 0;
hNewToken := 0;
MLAuthority := SECURITY_MANDATORY_LABEL_AUTHORITY;
pIntegritySid := nil;
FillChar(tml, sizeof(tml), 0);
FillChar(si, sizeof(si), 0);
FillChar(pi, sizeof(pi), 0);

si.cb := sizeof(si);
si.lpDesktop := ‘Winsta0\Default’;
dwCreationFlag := NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE;
pEnvironment := nil;

try
// 从自己获取一个令牌
if (not OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE or
TOKEN_QUERY or TOKEN_ADJUST_DEFAULT or TOKEN_ASSIGN_PRIMARY, hToken)) then
begin
Result := GetLastError();
Exit;
end;

// 复制令牌
if (not DuplicateTokenEx(hToken, 0, nil, SecurityImpersonation,
TokenPrimary, hNewToken)) then
begin
Result := GetLastError();
Exit;
end;

// 创建一个低权限的SID
if (not AllocateAndInitializeSid(MLAuthority, 1, SECURITY_MANDATORY_LOW_RID,
0, 0, 0, 0, 0, 0, 0, pIntegritySid)) then
begin
Result := GetLastError();
Exit;
end;

tml.Label_.Attributes := SE_GROUP_INTEGRITY;
tml.Label_.Sid := pIntegritySid;

// 设置这个低权限SID到令牌
if (not SetTokenInformation(hNewToken, TokenIntegrityLevel, @tml,
(sizeof(tml) + GetLengthSid(pIntegritySid)))) then
begin
Result := GetLastError();
Exit;
end;

// 创建一个环境变量
if (CreateEnvironmentBlock(@pEnvironment, hToken, FALSE)) then
dwCreationFlag := dwCreationFlag or CREATE_UNICODE_ENVIRONMENT
else
pEnvironment := nil;

// 创建一个低权限的进程
if (not CreateProcessAsUser(hNewToken, nil, PChar(pszCommandLine), nil, nil,
FALSE, dwCreationFlag, pEnvironment, nil, si, pi)) then
begin
Result := GetLastError();
Exit;
end;

WaitForSingleObject(pi.hProcess, TimeOut);
finally
// 清理现场
if pEnvironment <> nil then
begin
DestroyEnvironmentBlock(pEnvironment);
pEnvironment := nil;
end;

if (hToken <> 0) then
begin
CloseHandle(hToken);
hToken := 0;
end;
if (hNewToken <> 0) then
begin
CloseHandle(hNewToken);
hNewToken := 0;
end;
if (pIntegritySid <> nil) then
begin
FreeSid(pIntegritySid);
pIntegritySid := nil;
end;
if (pi.hProcess <> 0) then
begin
CloseHandle(pi.hProcess);
pi.hProcess := 0;
end;
if (pi.hThread <> 0) then
begin
CloseHandle(pi.hThread);
pi.hThread := 0;
end;

if (ERROR_SUCCESS <> Result) then
begin
SetLastError(Result);
end
else
begin
Result := ERROR_SUCCESS;
end;
end;
end;

end.
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2017/6/22 15:38:24
7楼: function GetProcessByName(const szFileName: String): THANDLE;
var
  dwProcessIds: array[0..MAXWORD] of DWORD;
  cbNeeded: DWORD;
  nIndex, nCount: Integer;
  hProcess, hModule: THANDLE;
  pszProcessName: array[0..MAXWORD] of Char;
begin
  if (not EnumProcesses(@dwProcessIds[0], SizeOf(dwProcessIds), cbNeeded)) then
    Exit(0);

  nCount := cbNeeded div SizeOf(DWORD);
  for nIndex := 0 to nCount - 1 do
  begin
    hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, dwProcessIds[nIndex]);
    if (0 = hProcess) then
      Continue;

    pszProcessName[0] := #0;
    if (EnumProcessModules(hProcess, @hModule, SizeOf(hModule), cbNeeded)) then
    begin
      GetModuleBaseName(hProcess, hModule, pszProcessName, SizeOf(pszProcessName) div SizeOf(Char));

      if SameText(ExtractFileName(pszProcessName), szFileName) then
        Exit(hProcess);
    end;

    CloseHandle(hProcess);
  end;

  Exit(0);
end;

function GetTokenByName(const szFileName: String): THANDLE;
var
  hProcess: THANDLE;
begin
  hProcess := GetProcessByName(szFileName);
  if (0 = hProcess) then
    Exit(0);

  if (not OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, Result)) then
    Result := 0;

  CloseHandle(hProcess);
end;

function CreateProcessAsExplorer(const szAppName: String; const szParameters: String = ''): BOOL;
var
  pStartupInfo: TStartupInfo;
  pProcessInfo: TProcessInformation;
  pszAppName, pszParameters: PChar;
  hToken: THANDLE;
begin
  GetStartupInfo(pStartupInfo);
  if ('' = szAppName) then
    pszAppName := nil
  else
    pszAppName := PChar(szAppName);

  if ('' = szParameters) then
    pszParameters := nil
  else
    pszParameters := PChar(szParameters);

  FillChar(pProcessInfo, SizeOf(pProcessInfo), 0);
  hToken := GetTokenByName('explorer.exe');
  if (0 = hToken) then
    CreateProcess(pszAppName, pszParameters, nil, nil, FALSE, 0, nil, nil, pStartupInfo, pProcessInfo)
  else
    CreateProcessAsUser(hToken, pszAppName, pszParameters, nil, nil, FALSE, 0, nil, nil, pStartupInfo, pProcessInfo);

  CloseHandle(hToken);

  if (0 <> pProcessInfo.hProcess) then
  begin
    CloseHandle(pProcessInfo.hThread);
    CloseHandle(pProcessInfo.hProcess);
    Exit(TRUE);
  end
  else
  begin
    ShowMessage(SysErrorMessage(GetLastError()));
    Exit(FALSE);
  end;
end;
----------------------------------------------
--
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2017/6/22 15:39:11
8楼: 大概就是这个意思。
调用如下:
CreateProcessAsExplorer('c:/windows/system32/cmd.exe', '/c ping 127.0.0.1 -t');


其他如果还要加一些别的校验就自己加好了。
----------------------------------------------
--
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/23 10:09:28
9楼: 非常感谢bahamut8348 (leonna),马上就试试,再次感谢。
----------------------------------------------
-
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/23 14:21:17
10楼: @bahamut8348 (leonna)
已经用CreateProcessAsExplorer运行B进程,但B进程依然具备ADMIN权限。。。很晕。。。

唉,B进程必须不能以ADMIN权限运行,因为WIN10里具备ADMIN权限的程序,在做MOUSERHOOK时有问题。。。现在也不知道怎么办了。。。请大神们只招一下。
----------------------------------------------
-
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/23 14:32:47
11楼: 跟了一下 GetTokenByName('explorer.exe'); 取不到句柄
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2017/6/23 15:59:50
12楼: 这里的gettokenbyname其实是复制目标进程的token令牌。这个需要你的exe和目标进程相同。例如目标进程,也就是explorer.exe是64位的,那么你的本程序也必须是64位的。


其实,既然你有登录的账号和密码,可以直接用账号密码登录获取token就可以了。
----------------------------------------------
--
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2017/6/23 16:00:51
13楼: 还有就是,不明白你所谓的管理员权限是个什么状态。
如果是服务程序的话,倒是可以走个捷径。
----------------------------------------------
--
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/23 17:02:28
14楼: @bahamut8348 (leonna)
主进程需要管理员权限是因为需要加载驱动,
本来也不需要搞双进程,但VISTA后,WINDOWS权限控制实在太
复杂,比如做一个MOUSE或KEY的HOOK,只要用ADMINISTRATOR执
行,这时,HOOK只能在本窗口响应,所以为了获得全局鼠标键盘
HOOK信息,只能开第二个进程(非ADMIN)权限的去做HOOK,而
驱动由主进程加载。
----------------------------------------------
-
作者:
男 jackalan (nVicen) ★☆☆☆☆ -
盒子活跃会员
2017/6/24 9:22:25
15楼: 既然降权这么累,为什么不反过来?
A以普通身份运行调用B后退出,让B以ADMIN身份运行A。这样A就是ADMIN,B就是普通不也一样吗?

function MyRunAsAdmin(Const sFile: String; Const sParameters: String = ''; Handle: HWND = 0):Boolean;
var
  seiInfo : TShellExecuteInfo;
begin
  Result := False;

  FillChar(seiInfo, SizeOf(seiInfo), 0);
  with seiInfo do
  begin
    cbSize       := SizeOf(seiInfo);
    Wnd          := Handle;
    fMask        := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
    lpVerb       := 'runas';
    lpFile       := PWideChar(sFile);
    lpParameters := PWideChar(sParameters);
    nShow        := SW_SHOWNORMAL;
  end;
  Result := ShellExecuteEx(@seiInfo);
end;
----------------------------------------------
简单做人,认真做事。
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2017/6/25 13:45:47
16楼: http://www.raysoftware.cn/?p=49
注意,你管理员和非管理员,跟当前用户关系不大.可能是同一个用户,但权限可以是非管理员或者是管理员
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/25 14:44:19
17楼: 非常感谢武大侠的指点,WdcRunTaskAsInteractiveUser这个函数对于系统版本要求太高,现在项目用户多10万,各种系统都有,考虑兼容性还是不敢冒险用WdcRunTaskAsInteractiveUser这个函数。目前已经用jackalan给的方法,虽然要改动两个进程,但已经实现需求,再次感谢大家的指点。
----------------------------------------------
-
作者:
男 djhfwk (djhfwk) ▲▲▲▲▲ -
普通会员
2017/6/25 14:56:36
18楼: 好奇什么应用有10多万用户
----------------------------------------------
-
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2017/6/25 21:52:41
19楼: 10多万用户是小意思啊,你可以判断是WIN7以后采用.我记得我的代码有处理GetProcAddress能得到WdcRunTaskAsInteractiveUser函数地址的才调用
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/25 23:24:49
20楼: 武大侠,测试了一下,vista下调用ShellExecuteEx结果又回到之前的问题,admin程序ShellExecuteEx的程序也是admin
----------------------------------------------
-
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/25 23:28:04
21楼: 微软实在是个怪物,每次更新系统都改一堆规则,无语😓
----------------------------------------------
-
作者:
男 nevergrief (孤独骑士) ★☆☆☆☆ -
盒子活跃会员
2017/6/25 23:40:42
22楼: to magiewang

ShellExecuteEx这个函数的lpVerb参数很关键,你分别设置空,以及 'runas'试试,应该会有不同的结果。前提是主程序分别是普通权限以及admin权限都要试试。一共4种组合 。你这样空叫ShellExecuteEx有问题是没有用的,连参数都不讲清楚。
----------------------------------------------
只有偏执狂才能生存!
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2017/6/26 16:13:53
23楼: 楼上的兄弟,都试过了,没用的。武大侠wdcruntask除了在vista下无效,7和10都测试了,手头没其他平台了,暂时不知道了。
----------------------------------------------
-
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2018/3/19 11:18:35
24楼: admin和管理员权限根本就是两个概念。
我写的博客上的技术就是让管理员权限程序以非管理员全线启动进程。

请先区分清楚账号和权限的概念,不知道你是要换账号运行还是要换权限运行。
----------------------------------------------
武稀松http://www.raysoftware.cn
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行78.125毫秒 RSS