2012-11-02 77 views
0

嗨,我对编程完全陌生。并请有人帮助我。CreateProcessWithLogonW:无法启动进程

我想从服务启动一个pocess。 我需要通过提示用户输入管理员凭证来启动新流程。我试图使用CreateProcessWithLogonW()

我正在使用正确的功能。 我试图给本地主机输入用户名,密码,域名。我完全佩服了我需要启动的.exe文件。

这是一段代码。

CreateProcessWithLogonW(L"Administrator", 
         L"localhost", 
         L"password", 
         0, 
         NULL, 
         L"c:\myupdates\myapp.exe", 
         NORMAL_PRIORITY_CLASS | CREATE_CONSOLE, 
         NULL, 
         NULL, 
         &si, 
         &pi); 

Si.cb = sizeof(si); 
Si.lpDesktop = L"winsta0\\default"; 

但是这个过程从未开始。你们能告诉我我做错了什么吗? 我需要做些什么来提醒用户输入管理员的凭据,而不是硬编码。

+0

GetLastError()是什么意思? – Benj

+0

你在做错的一件事是在你调用'CreateProcessWithLogonW'后分配给'si'结构。你应该先做。 – john

+4

是我还是正确使用Windows API'CreateProcessWithLogin()'和“我完全是编程新手”似乎有点不安...... – WhozCraig

回答

1

没有一个CreateProcess *函数可以做任何提示。它们是低级API,对GUI不了解。

如果您希望提示用户,请使用ShellExecuteExrunas命令。 Windows将首先要求提升权限,然后提示输入凭据。

+1

请记住,这是从服务内部完成的,该服务在自己的桌面上运行,并且ShellExecuteEx()没有提供在另一台桌面上运行新进程的规定。你需要使用'CreateProcess ...()'函数。如果您需要运行提升进程,请尝试['CreateProcessElevated()'](http://www.codeproject.com/KB/vista-security/UAC__The_Definitive_Guide.aspx)。 –

1

一个问题是传递字符串作为命令行参数,因为该参数必须是可修改的。从CreateProcessWithLogon()相关的命令行参数:

该函数可以修改这个字符串的内容。因此,该参数不能是指向只读内存的指针(例如const变量或文字字符串)。如果此参数是一个常量字符串,则该函数可能会导致访问冲突。

您还需要避开反斜杠。改为:

WCHAR cmdLine[] = L"c:\\myupdates\\myapp.exe"; /* 'cmdLine' is a 
                copy of the string 
                literal. */ 

并且通过cmdLine来代替。

任何WINAPI功能失败后检查GetLastError(),因为它会通知您失败的原因。

+0

你可以建议我如何传递路径可执行文件而不是字符串文字 – Vivek

+0

@Vivek,我有。 – hmjd

+0

我尝试了您所做的更改,但该过程未启动。我试图捕获最后的错误,我回来了没有:3221225477 – Vivek

1

您可能想要逃离程序字符串正确,以及:

L"c:\myupdates\myapp.exe" 

至少应该是:

L"c:\\myupdates\\myapp.exe" 

坦率地说,有事情不对的代码众多,从不当SI的设置,传递给API本身的参数。我建议你阅读更多。

0

访问冲突取决于lpCommandLine参数。这意味着一个可编辑的内存,LPWSTR和API函数确实修改缓冲区。但是你传递一个指向不可修改内存的指针。

但还有一个更基本的问题。你说你想提示服务的凭据。服务不应该显示UI,而在现代版本的Windows中,服务根本无法显示UI。你的设计是有缺陷的,你需要重新考虑它。

0

也许为时已晚,无法帮助您。但它可能对其他人有帮助。如果您使用CreateProcessWithLogonW功能,并且您正在使用Default桌面,请将lpDesktop保留为NULL。

如果lpDesktop不为空,你必须输入用户的SID(与LookupAccountNamean越来越)在桌面上的一个ACE和winstation的DACL

因此,这里有您需要做的添加一个ACE为桌面的步骤:与OpenDesktop

  1. 享受台式手柄,使用权dwDesiredAccess
  2. GetSecurityInfo和获取作为securityinfo
  3. 从你Security Descriptor
  4. DACL与用户的SID的SID添加AddAccessAllowedAce
  5. 的修饰DACL到桌面手柄

现在重复这些步骤winsta0 winstation

Furious先生在documantary的协助下帮助我解决了这个问题。