Как запустить PnPUtil как администратор из приложения C#?
У меня есть директива для установки драйвера принтера программно из приложения C# (WPF). Пользователю не должно быть разрешено выходить из приложения и устанавливать его из Windows. Мне удалось заставить это отлично работать вручную:
Установка драйвера через
pnputil -i -a file.inf
,
(Это прекрасно работает как в PowerShell, так и в командной строке, если он повышен.)Добавьте драйвер принтера через PowerShell.
Добавьте порт принтера через PowerShell.
Добавьте принтер через PowerShell.
Если я добавлю драйвер для хранения, запустив #1 вручную, мой код будет работать отлично. Но по какой-то причине я не могу заставить ps или cmd запустить (успешно) ту же команду из C#. Он возвращается с ошибкой Драйвер не в магазине. Вот мой код из приложения песочницы.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
namespace NetworkPrinterDriver
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Runspace rs;
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
// Create OpenFileDialog
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
// Set filter for file extension and default file extension
dlg.DefaultExt = ".exe";
dlg.Filter = "Information Files (.inf)|*.inf";
//dlg.Filter = "Executables (.exe)|*.exe";
// Display OpenFileDialog by calling ShowDialog method
Nullable<bool> result = dlg.ShowDialog();
// Get the selected file name and display in a TextBox
if (result == true)
{
// Open document
string filename = dlg.FileName;
FileNameTextBox.Text = filename;
}
}
private void btnInstall_Click(object sender, RoutedEventArgs e)
{
driverInstall(FileNameTextBox.Text);
AddPrinterDriver(txtDriverName.Text);
AddPrinterPort(txtPortName.Text, txtHostIP.Text);
AddPrinter(txtPrinterName.Text, txtDriverName.Text, txtPortName.Text);
}
private void driverInstall(string driverPath)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Verb = "runas";
startInfo.UseShellExecute = true;
startInfo.Arguments = string.Format("/C pnputil -i -a \"{0}\"", driverPath);
process.StartInfo = startInfo;
process.Start();
System.Threading.Thread.Sleep(500);
}
private void AddPrinterPort(string portName, string printerAddress)
{
string script = string.Format("Add-printerport -Name \"{0}\" -PrinterHostAddress \"{1}\"", portName, printerAddress);
RunScript(script);
}
private void AddPrinterDriver(string driverName)
{
string script = string.Format("Add-printerdriver -Name \"{0}\"", driverName);
RunScript(script);
}
private void AddPrinter(string printerName, string driverName, string portName)
{
string script = string.Format("Add-printer -Name \"{0}\" -DriverName \"{1}\" -Port \"{2}\"", printerName, driverName, portName);
RunScript(script);
}
private void RunScript(string script)
{
rs = RunspaceFactory.CreateRunspace();
rs.Open();
using (PowerShell ps = PowerShell.Create())
{
ps.AddScript(script);
ps.Runspace = rs;
ps.Invoke();
foreach (ErrorRecord err in ps.Streams.Error)
{
MessageBox.Show(err.ToString());
}
}
// rs.Close();
}
} // class MainWindow
} // namespace NetworkPrinterDriver
Может кто-нибудь объяснить мне, что я сделал не так?
Приглашение cmd действительно запускается (Windows просит меня внести изменения), но драйвер не устанавливается. Если я скопирую ту же строку из приложения и вставлю ее в командную строку с повышенными правами, это сработает. Любая помощь приветствуется.
1 ответ
Решено:
Я изменил это, чтобы использовать повышенный PowerShell CMD:
var newProcessInfo = new System.Diagnostics.ProcessStartInfo();
newProcessInfo.FileName = @"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe";
newProcessInfo.Verb = "runas";
newProcessInfo.Arguments = string.Format("pnputil -i -a \"{0}\"", driverPath);
System.Diagnostics.Process.Start(newProcessInfo);
Спасибо @Aybe за подсказку. Работает как шарм. Погнался за кроликом.......