2009-07-27 18 views
12

Có ai biết làm thế nào tôi có thể lập trình kiểm tra (sử dụng C#) cho dù chương trình của tôi sẽ có thể đọc/ghi một khóa registry cụ thể (cụ thể: "SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run")?Làm cách nào để kiểm tra xem người dùng có được phép đọc/ghi một khóa đăng ký cụ thể không?

Tôi hỏi vì chương trình của tôi có tùy chọn bật hoặc tắt hành vi 'chạy lúc khởi động'. Tôi muốn vô hiệu hóa tùy chọn này nếu người dùng hiện tại không được phép thay đổi sổ đăng ký. Khóa này luôn được cho phép được viết bởi người dùng hiện tại hay có khả năng nó đã bị khóa không? Nếu sau này, làm thế nào để kiểm tra điều này?

Tôi đã thấy một số cách xung đột kiểm tra quyền đăng ký - nhưng về cơ bản tôi không thể tìm cách kiểm tra khóa cụ thể trước khi tôi cố đọc nó. Tôi muốn thực hiện kiểm tra trước khi truy cập vào khóa hơn là cố gắng truy cập vào nó và nhận được một ngoại lệ.

Bất kỳ trợ giúp nào được đánh giá cao.

Tom

+2

Theo nguyên tắc chung, các phím máy địa phương yêu cầu quyền quản trị nhưng các khóa người dùng hiện tại thì không. – Brian

+0

Cảm ơn Brian - vì vậy có thể giả sử tôi có thể ghi vào khóa này (nó sẽ chuyển sang khóa người dùng) và chỉ giữ tùy chọn được bật mọi lúc, và sau đó chỉ xử lý bất kỳ ngoại lệ nào có thể bị ném nếu không thành công? – Beardy

Trả lời

13

Lớp RegistryPermission điều chỉnh các quyền bảo mật xung quanh phím reg. Để kiểm tra xem bạn có thể có quyền ghi vào quyền bạn sử dụng theo cách sau không:

RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); 

Sau đó, bạn sẽ sử dụng phương thức "Yêu cầu" trong thử/nắm bắt và trả về lỗi (tăng tính bảo mật) ngoại lệ). Về thành công, bạn sẽ tiếp tục và thực hiện cập nhật của mình. Mặc dù đây không phải là những gì bạn muốn, một kiểm tra về quyền truy cập trước khi truy cập, nó là cách được chấp nhận để đảm bảo bạn có quyền bạn cần trước khi bạn hoạt động trên các phím.Một cách có cấu trúc hoàn toàn này sẽ tương đương với:

try 
{ 
    RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); 
    perm1.Demand(); 
} 
catch (System.Security.SecurityException ex) 
{ 
    return; 
} 

//Do your reg updates here 

EDIT: tư duy về những gì tôi đã đề cập trong các bình luận, đây là phương pháp khuyến nông đến lớp RegistryPermission để kiểm tra sự cho phép:

using System.Security.Permissions; 
using System.Security; 

public static class RegistryExtensions 
{ 
    public static bool HavePermissionsOnKey(this RegistryPermission reg, RegistryPermissionAccess accessLevel, string key) 
    { 
     try 
     { 
      RegistryPermission r = new RegistryPermission(accessLevel, key); 
      r.Demand(); 
      return true; 
     } 
     catch (SecurityException) 
     { 
      return false; 
     } 
    } 

    public static bool CanWriteKey(this RegistryPermission reg, string key) 
    { 
     try 
     { 
      RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Write, key); 
      r.Demand(); 
      return true; 
     } 
     catch (SecurityException) 
     { 
      return false; 
     } 
    } 

    public static bool CanReadKey(this RegistryPermission reg, string key) 
    { 
     try 
     { 
      RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Read, key); 
      r.Demand(); 
      return true; 
     } 
     catch (SecurityException) 
     { 
      return false; 
     } 
    } 
} 
+0

Cảm ơn wolfwyrd :) – Beardy

+0

Không vấn đề gì, và để có được chức năng trong phong cách nhận xét về câu trả lời của Joel Coehoorn, bạn luôn có thể quấn thử này/bắt trong một phương thức trên lớp của bạn (hoặc như một phương pháp mở rộng để đăng ký có thể) và trả về true/false mà bạn muốn xem – Wolfwyrd

+0

^^ Chỉ cần thực hiện điều đó ngay bây giờ: P – Beardy

0

Tôi không chắc chắn làm thế nào để nó với C#, nhưng với Win32, bạn sẽ sử dụng RegGetKeySecurity(). Có lẽ có một wrapper C#? Nếu không, hãy sử dụng P/Invoke.

6

Một điều bạn cần biết về quyền là chúng là dễ bay hơi. Điều đó có nghĩa là bạn có thể thực hiện kiểm tra bảo mật trên khóa đăng ký, chỉ cố gắng thêm giá trị của mình nếu séc vượt qua và sau đó vẫn không thành công với ngoại lệ truy cập không đủ vì các quyền đã thay đổi giữa thời điểm bạn thực hiện séc và khi bạn hành động về kết quả. Điều này có thể xảy ra ngay cả khi chúng là các câu lệnh liên tiếp trong chương trình của bạn.

Cấp quyền bảo mật có xu hướng tương đối ổn định nhưng cơ hội vẫn tồn tại. Điều này có nghĩa là bạn phải có mã để xử lý ngoại lệ bảo mật và nếu bạn phải thực hiện điều đó thì thực sự không có bất kỳ điểm nào trong việc thực hiện kiểm tra ngay từ đầu. Thay vào đó, hãy dành thời gian của bạn để làm cho trình xử lý ngoại lệ của bạn tốt hơn một chút.

Điều đó cho biết, "boo" đối với bất kỳ ứng dụng nào muốn chạy một cái gì đó khi khởi động. YAGNI.

+0

Vâng, ứng dụng không tự thiết lập để chạy lúc khởi động theo mặc định, nhưng có một cơ hội tốt mà người dùng sẽ muốn hành vi này anyway, do tính chất/mục đích của sản phẩm. Tốt hơn là làm cho nó khả dụng hơn là buộc người dùng thực hiện nó theo cách thủ công. Tôi muốn có được/thiết lập hành vi để sử dụng xử lý ngoại lệ, nhưng trong hộp thoại tùy chọn tôi thà sử dụng một cái gì đó như RunAtStartup.Enabled = Registry.CanWriteToKey(), nếu bạn nhận được ý tưởng. Nó không có ý nghĩa với tôi để biến một ngoại lệ thành một boolean:/ – Beardy

5

Tôi nghĩ rằng bạn đặt cược tốt nhất là chỉ cố gắng thêm giá trị của bạn vào khóa và xử lý thất bại một cách duyên dáng bằng cách thông báo cho người dùng rằng họ không có đủ quyền để thực hiện điều đó.

Nếu bạn đang viết một số loại công cụ quản trị được thiết kế để luôn được quản trị viên điều hành, bạn nên chỉ ra rằng trong manifest. Bằng cách đó, ứng dụng của bạn sẽ nâng khi khởi động (thông qua lời nhắc UAC).

0

Just thử mở khóa đăng ký với quyền WRITE.

Điều đó nói rằng, những gì người khác đã nói là đúng: Không có cách nào để biết liệu một hoạt động sẽ thành công trừ khi bạn thử nó. Có lẽ someon đã xóa phím Run. Có lẽ đăng ký sẽ vượt quá bộ nhớ được cấp phát. Có lẽ đĩa đã thất bại.

1

Tùy chọn đơn giản nhất là thử và open phím có quyền ghi và xem bạn có nhận được nó hay không. Hãy nhớ đến close phím sau đó.

bool fWriteAccess; 
try { 
    Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True).Close(); 
    fWriteAccess = True; 
} catch (SecurityException) { 
    fWriteAccess = False; 
} 
Các vấn đề liên quan