win7管理员权限问题

时间:2022-01-15 15:20:58
在win7下用管理员进程都知道会有一个“用户账户控制提醒”,如何让我的程序屏闭掉这个提醒呢,
尝试过一个方法,创建一个服务,因为服务一定是管理员运行的,在服务里去启动我的进程,启动起来的进程应该是有管理员权限的,但是会有一个问题,因为我的程序是有界面的,这样的话,只能看到进程,看不到界面。
win7管理员权限问题路过的有没有好好的建议。

12 个解决方案

#1


提权操作行不行

#2


在服务中用管理员权限创建一个可弹出UI的进程:http://blog.csdn.net/woshinia/article/details/7850295

#3


服务提权可以的, 而且界面有什么关系, 开机启动只要判断explorer进程在 然后在开始启动界面程序就可以了

#4


你的界面是Hide?

#5


引用 3 楼 qicaofeng 的回复:
服务提权可以的, 而且界面有什么关系, 开机启动只要判断explorer进程在 然后在开始启动界面程序就可以了


引用 4 楼 shen_wei 的回复:
你的界面是Hide?


可能是我没表述清楚,是这样的,在服务里启动程序时,会出现一个交互式服务检测的对话框,如下图, win7管理员权限问题

点查看消息之后会进入另一个界面,应该是SYSTEM的界面,在里面可以看到启动起来的程序及界面,点返回之后,回到我的当前用户下,只能看到进程在,但是看不到界面,就是这样的, win7管理员权限问题

#6


查看到的进程,用户是SYSTEM的。

#7


进程在Service Session,不在当前session,所以你看不到界面

#8


用调试器(OD,WINDBG等)调试服务程序
To debug the initialization code of a service application, the debugger must be attached when the service is started. This is accomplished by creating a registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ProgramName


The ProgramName is the image file for the service application you are debugging. Do not specify a path. For example, the ProgramName might look like MyService.exe.

Under this key create a string data value called Debugger. The value of this string should be set to the full path of the debugger that will be used. For example,

c:\Debuggers\windbg.exe



In addition to setting this registry key, the service application must be marked as "interactive". This allows your service to interact with the desktop, and allows the debugger window to appear on your desktop.

This again requires modifying a registry key: you must bitwise-or the type entry for your service with 0x100 (this is the value for SERVICE_INTERACTIVE_PROCESS according to Winnt.h). The exact location and name of this registry entry varies. For example:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyServiceKey


Finally, you need to adjust the service application timeout. Otherwise, the service application will kill the debugger within 20 seconds after starting. Adjusting the timeout involves setting an entry in the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control


Under this key, create a DWORD data value called ServicesPipeTimeout. Set this entry to the amount of time in milliseconds that you want the service to wait before timing out. For example, 60,000 is one minute, while 86,400,000 is 24 hours.

设置ServicesPipeTimeout后需要重启系统才生效

Now, when the service is started, the debugger will also start. When the debugger starts, it will stop at the initial process breakpoint, before the service has begun running. This allows you to set breakpoints or otherwise configure your debugging session to let you monitor the startup of your service. Another option is to place calls to the DebugBreak function in your service from the point at which you would like to break into the debugger. (For more information, see DebugBreak in the Platform SDK documentation.)

If your service is running with other services in a Service Host Process, you may need to isolate the service into its own Service Host Process.

#9


引用 7 楼 oyljerry 的回复:
进程在Service Session,不在当前session,所以你看不到界面


嗯,有什么办法满足这个需求吗,
说白了就是以管理员身份运行我的程序,但我不想让系统弹出“用户账户控制提醒”这个提醒框,有招没?

#10


void OnServer()
{
HANDLE hToken = NULL;
if (!GetTokenByProcessName(hToken, _T("EXPLORER.EXE")))
{
continue;
}
::KsWriteLog("查找EXPLORER成功");
SECURITY_DESCRIPTOR  sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, (PACL)NULL, FALSE);

SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = &sd;

CString strAppName = _T("C:\\Program Files\\DecoderServer\\DecoderService.exe");//strModulePath + _T("testAutoStart.exe");


//STARTUPINFOEX siEx;

HANDLE ProcessHandle = NULL;   
HANDLE CurrentToken = NULL;   
HANDLE TokenDup = NULL;   
ProcessHandle = GetCurrentProcess();   
if (!OpenProcessToken(ProcessHandle, TOKEN_ALL_ACCESS, &CurrentToken))   
{      
::TRACE1("OpenProcessToken failed.Last Error is:%d", GetLastError());   
continue;   
}   
if (!DuplicateTokenEx(CurrentToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &TokenDup))   
{     
::TRACE1("DuplicateTokenEx failed.Last error is:%d", GetLastError());   
continue;   
}   
DWORD dwSessionID = WTSGetActiveConsoleSessionId();   
::KsWriteLog("WTSGetActiveConsoleSessionId:%d", dwSessionID);   
if (!SetTokenInformation(TokenDup, TokenSessionId, &dwSessionID, sizeof(DWORD)))   
{     
::TRACE1("SetTokenInformation failed.Last error is:%d", GetLastError());   
continue;   
}

LPVOID pEnv = NULL;    
DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT;
if (!CreateEnvironmentBlock(&pEnv, TokenDup, FALSE))   
{   
int error1 = GetLastError();   
::TRACE1("CreateEnvironmentBlock failed.Last error is:%d", GetLastError());   
continue;   



STARTUPINFOEX si;
memset(&si,0, sizeof(si));
si.StartupInfo.cb = sizeof(si);
si.StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
si.StartupInfo.wShowWindow = SW_NORMAL;
si.StartupInfo.lpDesktop = _T("WinSta0\\Default");
PROCESS_INFORMATION pi;

::TRACE1("TokenDup  %0x\n", TokenDup);
if (!CreateProcessAsUser(TokenDup, strAppName, NULL, &sa, &sa, FALSE, dwCreationFlags, pEnv, strModulePath, (STARTUPINFO*)&si, &pi))
{
::TRACE1("%d", GetLastError());
CloseHandle(hToken);
continue;
}
::KsWriteLog("启动其他进程成功");
CloseHandle(hToken);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
DestroyEnvironmentBlock(pEnv);
pEnv = NULL;   
CloseHandle(ProcessHandle);   
CloseHandle(TokenDup); 
}



#11


int CheckProccessExist(wchar_t *p)
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);

HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
//::KsWriteLog("CreateToolhelp32Snapshot error");
return -1;
}

BOOL bProcess = Process32First(hProcessSnap, &pe32);
while (bProcess)
{
if (_tcscmp(_tcsupr(pe32.szExeFile), _tcsupr(p)) == 0)
{
CloseHandle(hProcessSnap);
return 1;
}
bProcess = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return 0;
}

BOOL GetTokenByProcessName(HANDLE & hToken, CString strName)
{
if (strName.IsEmpty())
{
return FALSE;
}
PROCESSENTRY32 pe32;
memset(&pe32, 0, sizeof(PROCESSENTRY32));
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return FALSE;
}
BOOL bProcess = Process32First(hProcessSnap, &pe32);
while (bProcess)
{
if (_tcscmp(_tcsupr(pe32.szExeFile), strName.MakeUpper()) == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
CloseHandle(hProcessSnap);
if (hProcess == NULL)
{
return FALSE;
}
BOOL bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
CloseHandle(hProcess);
return bRet;
}
bProcess = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return FALSE;
}

#12


试一试吧,  应该不会有提示框的

#1


提权操作行不行

#2


在服务中用管理员权限创建一个可弹出UI的进程:http://blog.csdn.net/woshinia/article/details/7850295

#3


服务提权可以的, 而且界面有什么关系, 开机启动只要判断explorer进程在 然后在开始启动界面程序就可以了

#4


你的界面是Hide?

#5


引用 3 楼 qicaofeng 的回复:
服务提权可以的, 而且界面有什么关系, 开机启动只要判断explorer进程在 然后在开始启动界面程序就可以了


引用 4 楼 shen_wei 的回复:
你的界面是Hide?


可能是我没表述清楚,是这样的,在服务里启动程序时,会出现一个交互式服务检测的对话框,如下图, win7管理员权限问题

点查看消息之后会进入另一个界面,应该是SYSTEM的界面,在里面可以看到启动起来的程序及界面,点返回之后,回到我的当前用户下,只能看到进程在,但是看不到界面,就是这样的, win7管理员权限问题

#6


查看到的进程,用户是SYSTEM的。

#7


进程在Service Session,不在当前session,所以你看不到界面

#8


用调试器(OD,WINDBG等)调试服务程序
To debug the initialization code of a service application, the debugger must be attached when the service is started. This is accomplished by creating a registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ProgramName


The ProgramName is the image file for the service application you are debugging. Do not specify a path. For example, the ProgramName might look like MyService.exe.

Under this key create a string data value called Debugger. The value of this string should be set to the full path of the debugger that will be used. For example,

c:\Debuggers\windbg.exe



In addition to setting this registry key, the service application must be marked as "interactive". This allows your service to interact with the desktop, and allows the debugger window to appear on your desktop.

This again requires modifying a registry key: you must bitwise-or the type entry for your service with 0x100 (this is the value for SERVICE_INTERACTIVE_PROCESS according to Winnt.h). The exact location and name of this registry entry varies. For example:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyServiceKey


Finally, you need to adjust the service application timeout. Otherwise, the service application will kill the debugger within 20 seconds after starting. Adjusting the timeout involves setting an entry in the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control


Under this key, create a DWORD data value called ServicesPipeTimeout. Set this entry to the amount of time in milliseconds that you want the service to wait before timing out. For example, 60,000 is one minute, while 86,400,000 is 24 hours.

设置ServicesPipeTimeout后需要重启系统才生效

Now, when the service is started, the debugger will also start. When the debugger starts, it will stop at the initial process breakpoint, before the service has begun running. This allows you to set breakpoints or otherwise configure your debugging session to let you monitor the startup of your service. Another option is to place calls to the DebugBreak function in your service from the point at which you would like to break into the debugger. (For more information, see DebugBreak in the Platform SDK documentation.)

If your service is running with other services in a Service Host Process, you may need to isolate the service into its own Service Host Process.

#9


引用 7 楼 oyljerry 的回复:
进程在Service Session,不在当前session,所以你看不到界面


嗯,有什么办法满足这个需求吗,
说白了就是以管理员身份运行我的程序,但我不想让系统弹出“用户账户控制提醒”这个提醒框,有招没?

#10


void OnServer()
{
HANDLE hToken = NULL;
if (!GetTokenByProcessName(hToken, _T("EXPLORER.EXE")))
{
continue;
}
::KsWriteLog("查找EXPLORER成功");
SECURITY_DESCRIPTOR  sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, (PACL)NULL, FALSE);

SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = &sd;

CString strAppName = _T("C:\\Program Files\\DecoderServer\\DecoderService.exe");//strModulePath + _T("testAutoStart.exe");


//STARTUPINFOEX siEx;

HANDLE ProcessHandle = NULL;   
HANDLE CurrentToken = NULL;   
HANDLE TokenDup = NULL;   
ProcessHandle = GetCurrentProcess();   
if (!OpenProcessToken(ProcessHandle, TOKEN_ALL_ACCESS, &CurrentToken))   
{      
::TRACE1("OpenProcessToken failed.Last Error is:%d", GetLastError());   
continue;   
}   
if (!DuplicateTokenEx(CurrentToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &TokenDup))   
{     
::TRACE1("DuplicateTokenEx failed.Last error is:%d", GetLastError());   
continue;   
}   
DWORD dwSessionID = WTSGetActiveConsoleSessionId();   
::KsWriteLog("WTSGetActiveConsoleSessionId:%d", dwSessionID);   
if (!SetTokenInformation(TokenDup, TokenSessionId, &dwSessionID, sizeof(DWORD)))   
{     
::TRACE1("SetTokenInformation failed.Last error is:%d", GetLastError());   
continue;   
}

LPVOID pEnv = NULL;    
DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT;
if (!CreateEnvironmentBlock(&pEnv, TokenDup, FALSE))   
{   
int error1 = GetLastError();   
::TRACE1("CreateEnvironmentBlock failed.Last error is:%d", GetLastError());   
continue;   



STARTUPINFOEX si;
memset(&si,0, sizeof(si));
si.StartupInfo.cb = sizeof(si);
si.StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
si.StartupInfo.wShowWindow = SW_NORMAL;
si.StartupInfo.lpDesktop = _T("WinSta0\\Default");
PROCESS_INFORMATION pi;

::TRACE1("TokenDup  %0x\n", TokenDup);
if (!CreateProcessAsUser(TokenDup, strAppName, NULL, &sa, &sa, FALSE, dwCreationFlags, pEnv, strModulePath, (STARTUPINFO*)&si, &pi))
{
::TRACE1("%d", GetLastError());
CloseHandle(hToken);
continue;
}
::KsWriteLog("启动其他进程成功");
CloseHandle(hToken);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
DestroyEnvironmentBlock(pEnv);
pEnv = NULL;   
CloseHandle(ProcessHandle);   
CloseHandle(TokenDup); 
}



#11


int CheckProccessExist(wchar_t *p)
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);

HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
//::KsWriteLog("CreateToolhelp32Snapshot error");
return -1;
}

BOOL bProcess = Process32First(hProcessSnap, &pe32);
while (bProcess)
{
if (_tcscmp(_tcsupr(pe32.szExeFile), _tcsupr(p)) == 0)
{
CloseHandle(hProcessSnap);
return 1;
}
bProcess = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return 0;
}

BOOL GetTokenByProcessName(HANDLE & hToken, CString strName)
{
if (strName.IsEmpty())
{
return FALSE;
}
PROCESSENTRY32 pe32;
memset(&pe32, 0, sizeof(PROCESSENTRY32));
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return FALSE;
}
BOOL bProcess = Process32First(hProcessSnap, &pe32);
while (bProcess)
{
if (_tcscmp(_tcsupr(pe32.szExeFile), strName.MakeUpper()) == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
CloseHandle(hProcessSnap);
if (hProcess == NULL)
{
return FALSE;
}
BOOL bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
CloseHandle(hProcess);
return bRet;
}
bProcess = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return FALSE;
}

#12


试一试吧,  应该不会有提示框的