c-允许程序权限在启动时从任何帐户更改电脑名称



我正在编写一个基本程序,该程序在启动时将电脑的活动NIC发送到服务器,并适当更改电脑的主机名。该过程概述如下。

程序执行过程:

  1. 由任何帐户自动启动
  2. 收集活动NIC地址
  3. 将NIC地址发送到服务器
  4. 接收指定的PC主机名
  5. 比较当前主机名和分配的主机名
  6. 如有必要,更改主机名

我的程序完美地执行了步骤1-5。它能够收集活动NIC地址,为服务器准备数据包并接收响应。问题是程序何时到达步骤6。在Windows XP上,如果仅以管理员身份登录,则程序更改主机名时不会出现问题。在Windows Vista、7和8上,该程序无法更改计算机主机名(由于需要UAC提升),或者如果登录到没有管理员权限的用户帐户,则会缺少必要的权限。

在向程序添加应用程序清单以向用户和Windows发出程序需要管理员权限的信号后,程序无法启动,因为Windows Vista及更高版本在启动时不会启动需要管理员权限。

在之前的清单修改之后,我在作为管理员的计算机上创建了一个单独的用户帐户,这样程序就可以模拟管理员帐户并完全访问计算机,而不需要活动用户是管理员。在Windows XP上,它再次完美地工作。当在Windows7上运行时,程序会抛出一条"权限被拒绝"的消息。我已经尝试了Process.Start以及使用advapi32.dll和userenv.dll的C Sharp模拟,如下所示。

允许程序权限在启动时从任何帐户更改PC名称的最佳方法是什么?

进程启动方法

ProcessStartInfo myProcess = new ProcessStartInfo(path);
myProcess.UserName = username;
myProcess.Password = MakeSecureString(password);
myProcess.WorkingDirectory = @"C:WindowsSystem32";
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() + "rn");
            }
            finally
            {
                if (token != IntPtr.Zero) CloseHandle(token);
                if (tokenDuplicate != IntPtr.Zero) CloseHandle(tokenDuplicate);
                Console.WriteLine("After finished impersonation: " +
                                  WindowsIdentity.GetCurrent().Name);
            }

您可以在Windows中使用任务调度程序设置任务。将任务设置为在启动时运行,无论是否有人登录。还要确保任务以最高权限运行(复选框)。这应该能解决你的问题。

最新更新