我正在寫在啓動時將PC的活動NIC到服務器,並適當地改變了PC的主機名的基本程序。該過程概述如下。允許程序員在啓動時從任何賬戶更改PC名稱?
計劃執行過程:
- 任何帳戶自動啓動
- 收集活動網卡地址
- 發送網卡地址到服務器
- 接收分配PC主機名
- 比較電流並指定主機名
- 必要時更改主機名稱
我的程序執行步驟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);
}
我的印象是,任務計劃程序是爲用戶計劃任務的工作站下。考慮到我計劃在完成時將該程序聯機以供其他人使用,在任務計劃程序中列出的程序看起來沒有ms-config >>啓動(或Windows 8任務管理器>>啓動)中列出的程序更專業。 ? – CoderWalker
我最初的代碼程序作爲Windows服務,但是因爲我打算啓用編程安裝.NET框架,以及更高版本(需要桌面交互),我相信,殺死我以前的服務理念爲好。 – CoderWalker
@CoderWalker我沒有看到兩個變體之間的「專業性」有什麼不同。你有沒有看過你係統上預定的東西? - 舉個例子,即使Adobe通過這種機制來調度它的更新。我也沒有看到有理由將此程序作爲服務保留在系統中,因爲它只對系統啓動有用...... – junix