1.前言
桌面運維同學經常會處理列印機驅動安裝這類工單,手動安裝列印機驅動通常包含以下步驟:
1.根據列印機型号網上查找對應列印機驅動
2.使用cmd指令進入管理者界面
3.将列印機驅動添加到window系統中
人工安裝需要經過三個步驟,操作繁瑣,效率較低。基于此,我們想開發一個自動化安裝列印機驅動的程式,讓使用者可以自行安裝列印機驅動,以此減少列印機驅動安裝工單,提高運維效率。
2.技術實作
我們可以使用代碼的方式實作人工操作的三個步驟。這裡,我們程式上實作也和這三個步驟類似。
1.背景管理系統統一維護列印機驅動
2.使用程式提權,自動進入管理者環境
3.使用Devcon程式執行列印機驅動安裝指令
後續的所有示例代碼以C#為例。
2.1.背景管理系統
我們開發一個背景管理系統,統一維護列印機驅動,這樣可以減少重複查找列印機驅動的工作,提升效率。
系統界面如下:
通過這個頁面維護列印機型号、硬體ID和驅動等相關資訊。
任何裝置的硬體ID都是唯一的,我們可以通過程式識别列印機的硬體ID,然後根據硬體ID查詢到驅動下載下傳。
這裡我們使用window的Win32_PnPEntity來擷取硬體的相關資訊,其結構如下:
[Dynamic, Provider("CIMWin32"), UUID("{FE28FD98-C875-11d2-B352-00104BC97924}"), AMENDMENT]
class Win32_PnPEntity : CIM_LogicalDevice
{
uint16 Availability;
string Caption;
string ClassGuid;
string CompatibleID[];
uint32 ConfigManagerErrorCode;
boolean ConfigManagerUserConfig;
string CreationClassName;
string Description;
string DeviceID;
boolean ErrorCleared;
string ErrorDescription;
string HardwareID[];
datetime InstallDate;
uint32 LastErrorCode;
string Manufacturer;
string Name;
string PNPClass;
string PNPDeviceID;
uint16 PowerManagementCapabilities[];
boolean PowerManagementSupported;
boolean Present;
string Service;
string Status;
uint16 StatusInfo;
string SystemCreationClassName;
string SystemName;
};
其中Name表示硬體名稱,HardwareID表示硬體id。
列印機硬體ID識别部分代碼如下:
namespace JwPrinterManage.Helper
{
internal class USBUtilTest
{
public static List<USBDeviceInfo> GetAllPrinterUsbList()
{
List<USBDeviceInfo> list = new List<USBDeviceInfo>();
ManagementObjectCollection collection;
using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_PnPEntity"))
collection = searcher.Get();
foreach (ManagementObject device in collection)
{
string name = Convert.ToString(device["Name"]);
string deviceId = Convert.ToString(device["DeviceID"]);
string[] HardwareIDArr = (string[])device["HardwareID"];
if (HardwareIDArr == null || HardwareIDArr.Length == 0)
{
continue;
}
foreach (var curHardwareId in HardwareIDArr)
{
if (curHardwareId.Contains("USBPRINT"))
{
list.Add(new USBDeviceInfo(curHardwareId, name));
}
}
}
collection.Dispose();
return list;
}
}
}
以上代碼可以擷取到計算機的所有硬體名稱、裝置ID以及硬體ID,通過此方法,我們可以快速擷取列印機的硬體ID,然後根據硬體ID從背景系統中查找驅動并下載下傳到使用者本地。
2.2.程式提權
安裝列印機驅動,程式需要具有管理者權限,這裡我們需要通過cmd指令給程式提權,保證程式具有管理者權限。
其原理是使用管理者賬号和密碼執行cmd運作程式,這樣程式就具有管理者權限。
部分核心代碼如下:
namespace JwPrinterManage.Helper
{
internal class AdminUtilsTest
{
// 使用特定賬号和密碼運作程式
private static void run(string userName, string pass, string exePath)
{
Process process = new Process();
string str = pass;
SecureString secureString = new SecureString();
foreach (char c in str)
secureString.AppendChar(c);
process.StartInfo.UserName = userName;
process.StartInfo.Password = secureString;
process.StartInfo.FileName = exePath;
process.StartInfo.UseShellExecute = false;
process.Start();
}
}
}
2.3.使用Devcon安裝驅動
2.3.1.Devcon.exe簡介
DevCon (Devcon.exe)(即裝置控制台)是一種指令行工具,用于顯示有關運作 Windows 的計算機上的裝置的詳細資訊。 可以使用 DevCon 啟用、禁用、安裝、配置以及删除裝置。
其主要文法如下:
devcon [/r] command [arguments]
其主要指令如下:
•DevCon Enable
•DevCon Disable
•DevCon Update
•DevCon UpdateNI
•DevCon Install
•DevCon Remove
•DevCon Rescan
•DevCon Restart
•DevCon Reboot
•DevCon SetHwID
•DevCon ClassFilter
•DevCon Dp_add
•DevCon Dp_delete
這裡我們不詳細介紹這些指令,感興趣的同學可以檢視官方文檔: Devcon指令文檔。
2.3.2.Devcon指令安裝驅動
我們可以使用update指令來安裝列印機驅動程式,devcon update指令可以安裝任意驅動程式包,具體如下:
devcon update INFfile HardwareID
其中INFfile表示列印機驅動的INF檔案,HardwareID表示列印機的硬體ID。
當出現如下圖所示的結果時,表示列印機驅動安裝成功。
3.總結
本文主要介紹列印機驅動自動化安裝的一個基本實作思路,通過運維工具,我們可以實作部分桌面工單自動化,幫助運維同僚提高工作效率。同時,本文也介紹了通過Win32_PnPEntity擷取window硬體資訊以及通過Devcon指令安裝驅動的方法,這兩個方法不僅限于列印機驅動安裝的應用,其實際應用場景比較廣泛,大家可以通過這些方法開發自動化工具,幫助提高運維工作效率。