2013-08-04 29 views
1

我正在寫在啓動時將PC的活動NIC到服務器,並適當地改變了PC的主機名的基本程序。該過程概述如下。允許程序員在啓動時從任何賬戶更改PC名稱?

計劃執行過程:

  1. 任何帳戶自動啓動
  2. 收集活動網卡地址
  3. 發送網卡地址到服務器
  4. 接收分配PC主機名
  5. 比較電流並指定主機名
  6. 必要時更改主機名稱

我的程序執行步驟1-5完全按設計完成。它能夠收集活動的NIC地址,爲服務器準備數據包並接收響應。問題出在程序到達第6步時。在Windows XP上,如果只以管理員身份登錄,程序將更改主機名而不會出現問題。在Windows Vista 7和8上,該程序無法更改計算機主機名(由於要求UAC提升),或者如果登錄到不具有管理員權限的用戶帳戶,它缺少必要的權限。

在添加應用程序清單的程序對信號的用戶和Windows程序所需的程序無法啓動Windows Vista或以上無法啓動,需要在啓動管理員權限的程序的管理員權限。

之前的清單修改之後,我在作爲管理員的計算機上創建了一個分隔用戶帳戶,以便程序可以模擬管理員帳戶,並且完全訪問計算機而無需活動用戶成爲管理員。再次在Windows XP上它完美無缺地工作。在Windows 7上,程序會拋出「權限被拒絕」消息。我已經嘗試使用Process.Start以及C Sharp模擬advapi32.dll和userenv.dll,如下所示。

什麼是允許的程序權限,才能在啓動任何帳戶更改計算機名最好的方法是什麼?

的Process.Start方法

ProcessStartInfo myProcess = new ProcessStartInfo(path); 
myProcess.UserName = username; 
myProcess.Password = MakeSecureString(password); 
myProcess.WorkingDirectory = @"C:\Windows\System32"; 
myProcess.UseShellExecute = false; 
myProcess.Verb = "runas"; 
Process.Start(myProcess); 

模擬方法

static void Imp() 
     { 
      WindowsImpersonationContext m_ImpersonationContext = null; 
      WindowsIdentity m_ImpersonatedUser; 
      IntPtr token = IntPtr.Zero; 
      IntPtr tokenDuplicate = IntPtr.Zero; 
      const int SecurityImpersonation = 2; 
      const int TokenType = 1; 
      const int LOGON32_LOGON_INTERACTIVE = 2; 
      const int LOGON32_PROVIDER_DEFAULT = 0; 

      try 
      { 
       if (RevertToSelf()) 
       { 
        Console.WriteLine("Before impersonation: " + 
             WindowsIdentity.GetCurrent().Name); 

        String userName = "sfadmin"; 
        //IntPtr password = GetPassword(); 

        if (LogonUser(userName, Environment.MachineName, 
            "d31ux3", LOGON32_LOGON_INTERACTIVE, 
            LOGON32_PROVIDER_DEFAULT, ref token) != 0) 
        { 
         if (DuplicateToken(token, SecurityImpersonation, ref tokenDuplicate) != 0) 
         { 
          m_ImpersonatedUser = new WindowsIdentity(tokenDuplicate); 
          using (m_ImpersonationContext = m_ImpersonatedUser.Impersonate()) 
          { 
           if (m_ImpersonationContext != null) 
           { 
            Console.WriteLine("After Impersonation succeeded: " + 
             Environment.NewLine + 
             "User Name: " + 
             WindowsIdentity.GetCurrent(
              TokenAccessLevels.MaximumAllowed).Name + 
             Environment.NewLine + 
             "SID: " + 
             WindowsIdentity.GetCurrent(
              TokenAccessLevels.MaximumAllowed).User.Value); 

            #region LoadUserProfile 
            // Load user profile 
            ProfileInfo profileInfo = new ProfileInfo(); 
            profileInfo.dwSize = Marshal.SizeOf(profileInfo); 
            profileInfo.lpUserName = userName; 
            profileInfo.dwFlags = 1; 
            Boolean loadSuccess = 
              LoadUserProfile(tokenDuplicate, ref profileInfo); 

            if (!loadSuccess) 
            { 
             Console.WriteLine("LoadUserProfile() failed with error code: " + 
                  Marshal.GetLastWin32Error()); 
             throw new Win32Exception(Marshal.GetLastWin32Error()); 
            } 

            if (profileInfo.hProfile == IntPtr.Zero) 
            { 
             Console.WriteLine(
              "LoadUserProfile() failed - HKCU handle " + 
              "was not loaded. Error code: " + 
              Marshal.GetLastWin32Error()); 
             throw new Win32Exception(Marshal.GetLastWin32Error()); 
            } 
            #endregion 

            CloseHandle(token); 
            CloseHandle(tokenDuplicate); 

            // Do tasks after impersonating successfully 
            //AccessFileSystem(); 

            RunAs("SolarFrost.exe", "sfadmin", "d31ux3"); 


            // Access HKCU after loading user's profile 
            //AccessHkcuRegistry(profileInfo.hProfile); 

            // Unload user profile 
            // MSDN remarks 
            // http://msdn.microsoft.com/en-us/library/bb762282(VS.85).aspx 
            // Before calling UnloadUserProfile you should 
            // ensure that all handles to keys that you have opened in the 
            // user's registry hive are closed. If you do not 
            // close all open registry handles, the user's profile fails 
            // to unload. For more information, see Registry Key 
            // Security and Access Rights and Registry Hives. 
            UnloadUserProfile(tokenDuplicate, profileInfo.hProfile); 

            // Undo impersonation 
            m_ImpersonationContext.Undo(); 
           } 
          } 
         } 
         else 
         { 
          Console.WriteLine("DuplicateToken() failed with error code: " + 
               Marshal.GetLastWin32Error()); 
          throw new Win32Exception(Marshal.GetLastWin32Error()); 
         } 
        } 
       } 
      } 
      catch (Exception Ex) 
      { 
       System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "log.txt", Ex.ToString() + "\r\n"); 
      } 
      finally 
      { 
       if (token != IntPtr.Zero) CloseHandle(token); 
       if (tokenDuplicate != IntPtr.Zero) CloseHandle(tokenDuplicate); 

       Console.WriteLine("After finished impersonation: " + 
            WindowsIdentity.GetCurrent().Name); 
      } 

回答

0

您可以安裝在Windows中使用Task Scheduler的任務。將任務設置爲在啓動時運行,以確定是否有人已經登錄。還要確保任務運行在highest privilege(複選框)。這應該可以解決你的問題。

+0

我的印象是,任務計劃程序是爲用戶計劃任務的工作站下。考慮到我計劃在完成時將該程序聯機以供其他人使用,在任務計劃程序中列出的程序看起來沒有ms-config >>啓動(或Windows 8任務管理器>>啓動)中列出的程序更專業。 ? – CoderWalker

+0

我最初的代碼程序作爲Windows服務,但是因爲我打算啓用編程安裝.NET框架,以及更高版本(需要桌面交互),我相信,殺死我以前的服務理念爲好。 – CoderWalker

+0

@CoderWalker我沒有看到兩個變體之間的「專業性」有什麼不同。你有沒有看過你係統上預定的東西? - 舉個例子,即使Adobe通過這種機制來調度它的更新。我也沒有看到有理由將此程序作爲服務保留在系統中,因爲它只對系統啓動有用...... – junix

相關問題