2012-11-02 76 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的協助下幫助我解決了這個問題。