2010-03-09 44 views
10

Tôi có một exe C# cần chạy bằng WMI và truy cập một mạng chia sẻ. Tuy nhiên, khi tôi truy cập vào phần chia sẻ, tôi nhận được một UnauthorizedAccessException. Nếu tôi chạy exe trực tiếp chia sẻ có thể truy cập. Tôi đang sử dụng cùng một tài khoản người dùng trong cả hai trường hợp.Xác thực mạng khi chạy exe từ WMI

Có hai phần trong ứng dụng của tôi, một trình khách GUI chạy trên máy tính cục bộ và một quy trình phụ trợ chạy trên máy tính từ xa. Khi máy khách cần kết nối với backend, đầu tiên nó khởi chạy quá trình từ xa bằng WMI (mã được sao chép dưới đây). Quá trình từ xa thực hiện một số thứ bao gồm việc truy cập một mạng chia sẻ bằng cách sử dụng Directory.GetDirectories() và báo cáo lại cho máy khách.

Khi quá trình từ xa được khởi chạy tự động bởi ứng dụng khách bằng WMI, nó không thể truy cập vào mạng chia sẻ. Tuy nhiên, nếu tôi kết nối với máy từ xa bằng Remote Desktop và khởi động thủ công quá trình phụ trợ, truy cập vào mạng chia sẻ thành công.

Người dùng được chỉ định trong cuộc gọi WMI và người dùng đã đăng nhập cho phiên Máy tính từ xa giống nhau, vì vậy quyền sẽ giống nhau, phải không?

Tôi thấy trong mục MSDN cho Directory.Exists() nó nói "Phương thức tồn tại không thực hiện xác thực mạng. Nếu bạn truy vấn chia sẻ mạng hiện có mà không được xác thực trước, phương thức Exists sẽ trả về false". Tôi cho rằng điều này có liên quan? Làm cách nào để đảm bảo người dùng được xác thực chính xác trong phiên WMI?

ConnectionOptions opts = new ConnectionOptions(); 

opts.Username = username; 
opts.Password = password; 

ManagementPath path = new ManagementPath(string.Format("\\\\{0}\\root\\cimv2:Win32_Process", remoteHost)); 

ManagementScope scope = new ManagementScope(path, opts); 

scope.Connect(); 

ObjectGetOptions getOpts = new ObjectGetOptions(); 
using (ManagementClass mngClass = new ManagementClass(scope, path, getOpts)) 
{ 
    ManagementBaseObject inParams = mngClass.GetMethodParameters("Create"); 
    inParams["CommandLine"] = commandLine; 
    ManagementBaseObject outParams = mngClass.InvokeMethod("Create", inParams, null); 
} 
+1

vấn đề tương tự http://stackoverflow.com/questions/2291921/c-wmi-runs-an-exe-on-a-remote-computer-that-then-runs-another-exe-on-the- same-co/2291991 # 2291991 – lsalamon

+0

Cảm ơn, tìm kiếm của tôi đã không hiển thị điều đó. Tôi sẽ đọc và xem nó có giúp ích gì không. – Andy

+0

Tôi đã thêm người dùng và được cấp đầy đủ, nhưng nó không tạo ra bất kỳ sự khác biệt nào: ( – Andy

Trả lời

2

Sau khi đi theo liên kết được đề xuất bởi Isalamon trên (nhờ) Tôi làm theo lời khuyên Jestro và đã viết lại sử dụng psexec.exe (mà có thể được tải về từ http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx) thay vì WMI. Nó cảm thấy như một chút của một kludge để làm điều đó theo cách này, nhưng nó có vẻ làm việc.

Code mới cho những ai đang gặp vấn đề tương tự:

Process proc = new Process(); 
proc.StartInfo.FileName = "PsExec.exe"; 
proc.StartInfo.Arguments = string.Format("\\\\{0} -d -u {1}\\{2} -p {3} {4}", 
             remoteHost, 
             domain, 
             username, 
             password, 
             commandLine); 
proc.StartInfo.CreateNoWindow = true; 
proc.StartInfo.UseShellExecute = false; 
proc.Start(); 
1

WMI chỉ sử dụng mạo danh khi thực hiện quá trình từ xa, mà không cung cấp cho bạn truy cập mạng. Nếu bạn đang đi bên ngoài mã được quản lý, bạn chỉ có thể ánh xạ đường dẫn UNC trong quá trình từ xa WMI bắt đầu sử dụng bất kỳ thông tin đăng nhập nào bạn muốn. Sau đó, bạn có quyền truy cập mạng mà bạn muốn. Tôi sử dụng NetUseAdd và NetUseDel từ netapi32.dll để ánh xạ đường dẫn UNC. Xem http://pinvoke.net/ để biết chi tiết về cách sử dụng API.

0

Bạn có thể viết tất cả các lệnh của bạn vào tệp hàng loạt cho máy từ xa bao gồm sử dụng mạng (không cần sử dụng ký tự ổ đĩa) để thực hiện xác thực. Hoạt động tốt theo cách đó. Tôi vẫn đang làm việc trên một phương án thay thế.

+0

Thực ra nếu bạn làm như thế này nó sẽ hoạt động tốt, tôi chỉ kiểm tra nó: – Will

+0

OOps ở đây là: inParams ["CommandLine"] = "cmd/c \" "+" sử dụng mạng \\\\\\\\\ \\ c $ mật khẩu/người dùng: tên miền \\ tên người dùng && <\\ server \ share \ whatever.bat> "+" \ "> c: \\ temp \\ r_output.txt"; Tôi đăng nhập nó để truy xuất đầu ra sau trong mã của tôi. Trong trường hợp này nó ghi nhật ký chạy tập tin thực thi không phải lệnh trong đó. – Will

1

Tôi biết bạn đã sắp xếp nó bằng cách sử dụng PSEXEC, mà là một chương trình tuyệt vời, nhưng nếu bạn đã muốn quay trở lại để WMI, có bạn đã cố gắng tạo điều kiện cho những điều sau đây trong ConnectionOptions của bạn:

  • Lá cờ EnablePrivileges
  • đặt Mạo danh thành Mạo danh.Mạo danh

nào nào sau đây:

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.impersonation.aspx

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.enableprivileges.aspx

Tôi nghĩ rằng họ nên nói với WMI của bạn để thực sự cho phép chương trình để có thông tin chính xác và do đó truy cập mạng chia sẻ của bạn

Các vấn đề liên quan