2016-10-14 52 views
1

我遇到正在運行的進程問題,其中進程用戶的配置文件目錄尚未創建。如何強制Windows創建正在運行的用戶配置文件目錄

爲了解釋,這裏是這是如何發生的細節:

我們運行一個大型分佈式服務器的網格,並使用(部分)DataSynapse公司對這個網格執行過程。對於那些熟悉DataSynapse的人來說,引擎被配置爲使用「RunAs」運行特定的服務,我們在服務進程中使用某個AD域服務帳戶。我相信問題是DataSynapse在「runas」下運行該進程時,不會設置LoadUserProfile標誌(也不應該)。無論具體原因如何,如果「runas」服務帳戶(和AD域帳戶)從未登錄過某些網格計算機,那麼這些計算機將沒有該帳戶的用戶配置文件目錄。

對於那些不熟悉DataSynapse的人來說,這裏是一個更通用的解釋。在網格上的每臺計算機上,都有一個進程正在運行,我將其稱爲dsService,並在本地計算機的系統帳戶(或具有提升的憑據的某些類似帳戶)的憑據下運行。流程dsService將產生子流程,例如childProcess,但它會在我們的AD域帳戶的憑據下運行childProcess,我將調用serviceUser。網格上有成千上萬的機器,通常他們從不登錄到手動。特別是,配置文件目錄C:\users\serviceUser最初可能不存在。一旦創建一次,就沒有更多的問題。但是如果新節點添加到網格中,通常它們最初不會有C:\users\serviceUser。問題是,當dsService產生childProcessC:\users\serviceUser沒有得到創建,我們需要它。

相信,這是因爲產卵childProcessdsService不設置LoadUserProfile標誌爲真,但我不能肯定。

在任何情況下,childProcess是(.NET)的過程我們的控制之下(如serviceUser運行),並我想知道是否有一種方法(在C#),其childProcess可以強制OS創建當它確定它不存在時運行用戶的配置文件目錄C:\users\serviceUser

編輯: 實驗已經證實,如果一個人在另一個用戶ID啓動的過程,以及用戶的配置文件目錄是不存在的(更具體地說,如果用戶的本地配置文件尚未被創建 - 僅僅刪除預 - 現有的配置文件目錄創建了一個不同的情況,我們不感興趣),然後(1)如果過程開始於LoadUserProfile設置爲true,則創建配置文件目錄(以及一個假定的本地配置文件);和(2)如果過程以LoadUserProfile設置爲false開始,則不會創建配置文件目錄(以及假定的本地配置文件)。這是有道理的,並且是人們所期望的。

相關崗位:stackoverflow.com/q/9008742/1082063

+0

您是否需要使用「用戶目錄?」這似乎是應該將數據保存在自己的程序目錄中的應用程序的類型,或者只是在其在硬盤驅動器的其他位置創建的目錄中... –

+0

不,您不能從用戶的上下文中執行此操作。如果DataSynapse沒有提供創建用戶配置文件的選項,並且您無法繞過用戶配置文件存在的要求,則需要安排一些代碼作爲本地系統或其他適當的特權帳戶運行。 –

+0

首先,您應該測試簡單創建配置文件是否足夠。如果你的代碼要求配置文件被初始化*而不僅僅是加載*,那麼你遇到了一個難題。初始化配置文件的唯一方法是用戶以交互方式登錄。 –

回答

0

如果運行的帳戶具有管理員權限,下面的代碼將導致運行帳戶的配置文件的創建,包括其用戶配置目錄。如果沒有管理員,我不知道這是否是可能的:

using System.Runtime.InteropServices; 
... 
[DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)] 
public static extern int CreateProfile(
    [In] string pszUserSid, 
    [In] string pszUserName, 
    System.Text.StringBuilder pszProfilePath, 
    int cchProfilePath); 

.... 
public static string getUserProfilePath() 
{ 
    string userProfilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); 
    if(string.IsNullOrWhiteSpace(userProfilePath) || !Directory.Exists(userProfilePath)) 
    { //This will only work if we have admin... 
     var pathBuf = new System.Text.StringBuilder(240); 
     var Up = System.DirectoryServices.AccountManagement.UserPrincipal.Current; 
     if(0 == CreateProfile(Up.Sid.ToString(), Up.SamAccountName, pathBuf, pathBuf.Capacity) } 
     { 
      userProfilePath = pathBuf.ToString(); 
     } 
    } 
    return userProfilePath; 
} 

如果有人能告訴我如何做到這一點時,該帳戶不是管理員,他們會得到他們的答案接受爲正確答案。在此之前,這至少給了別人一些想法。

相關問題