2012-09-24 33 views
6

Tôi có một thư viện mà tôi sử dụng trên nhiều ứng dụng ClickOnce. Trong trường hợp có lỗi trong thư viện này, tôi muốn viết lỗi cho các cửa sổ EventLog.Sử dụng EventLog trong ứng dụng ClickOnce

Tôi đã tìm thấy KB article về cách thực hiện nhưng dường như điều này yêu cầu quyền của quản trị viên để tìm kiếm nguồn. Cụ thể, nó sẽ bị rung khi cố gắng tìm kiếm nhật ký sự kiện Security.

Có cách nào để giải quyết vấn đề này và ghi vào nhật ký sự kiện trong ứng dụng ClickOnce không? Tôi đã thấy một người trying to write to a known source, nhưng họ dường như không thể tìm thấy một nguồn luôn có sẵn.

EDIT:

Dựa trên câu trả lời ở đây tôi tạo ra một chương trình đó là bao gồm trong ứng dụng của tôi mà tôi có thể chạy trên chạy đầu tiên để thiết lập nguồn sự kiện mà có thể nhận được đặc quyền quản trị. Tuy nhiên một khi nguồn được tạo ra có vẻ như tôi vẫn không thể viết cho nó.

/// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     if (!EventLog.SourceExists("ATE")) 
     { 
      EventLog.CreateEventSource("ATE", "Application"); 
     } 
    } 

Tạo đúng nguồn (tương đương với chỉnh sửa đăng ký do Yannick Blondeau cung cấp). Khi tôi viết thư cho nguồn trong ứng dụng không nâng cao của tôi, tôi nhận được một lỗi mới, nhưng nó vẫn không hoạt động. Các lỗi mới là:

Cannot open log for source 'ATE'. You may not have write access.

EDIT 2:

bây giờ tôi đã cố gắng để làm cho nó làm việc thông qua registry chỉnh sửa trên CustomSD key. Tôi đã thử thêm (A ;; 0x7 ;;; AU) để cung cấp cho người dùng được xác thực quyền truy cập đầy đủ nhưng dường như không có bất kỳ ảnh hưởng nào.

Trả lời

8

Thật không may, nguồn sự kiện yêu cầu phải có các tư cách quản trị viên hành chính. Tuy nhiên, bạn không cần quyền quản trị để ghi vào sổ ghi sự kiện hoặc đọc từ đó.

Có hai cách để giải quyết vấn đề này.

Bạn thêm nguồn sự kiện mới khi cài đặt ứng dụng với tư cách quản trị viên.

Bạn tạo một ứng dụng đơn giản mà bạn chạy với tư cách quản trị viên để định cấu hình ứng dụng của mình. Điều này thậm chí có thể được bao gồm trong trình cài đặt.

Nếu bạn không có hoặc muốn trình cài đặt, tải ứng dụng lên máy tính với tư cách quản trị viên và chạy chương trình một lần. Khởi động ứng dụng của bạn nên định cấu hình nguồn sự kiện nếu nó chưa có ở đó, phải không? (Được rồi, đó là ba cách.)

Đoạn mã này là từ microsoft: http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx và được thiết kế để chạy với tư cách người dùng quản trị viên.

using System; 
using System.Diagnostics; 
using System.Threading; 

class MySample 
{ 
    public static void Main() 
    { 
     // Create the source, if it does not already exist. 
     if (!EventLog.SourceExists("MySource")) 
     { 
      //An event log source should not be created and immediately used. 
      //There is a latency time to enable the source, it should be created 
      //prior to executing the application that uses the source. 
      //Execute this sample a second time to use the new source. 
      EventLog.CreateEventSource("MySource", "MyNewLog"); 
      Console.WriteLine("CreatedEventSource"); 
      Console.WriteLine("Exiting, execute the application a second time to use the source."); 
      // The source is created. Exit the application to allow it to be registered. 
      return; 
     } 
     // Create an EventLog instance and assign its source. 
     EventLog myLog = new EventLog(); 
     myLog.Source = "MySource"; 

     // Write an informational entry to the event log.  
     myLog.WriteEntry("Writing to event log."); 
    } 
} 

Tôi biết nó có thể không chính xác như sau, nhưng tôi cho rằng đó là cách duy nhất để thực hiện việc này.

EDIT 1: Thêm một số mã khác

public class EventLogger 
{ 
    private const string logName = "Application"; 
    private static string appName = ""; 
    private static bool sourceExists = false; 

    public static string AppName 
    { 
     get { return appName; } 
     set { appName = value; } 
    } 

    public static void Init(string appName) 
    { 
     AppName = appName; 
     sourceExists = EventLog.SourceExists(AppName); 

     if (!sourceExists) 
     { 
      EventLog.CreateEventSource(AppName, logName); 
      sourceExists = true; 
     } 
    } 

    private static void Write(string entry, EventLogEntryType logType, int eventID) 
    { 
     if (sourceExists) 
     { 
      EventLog.WriteEntry(AppName, entry, logType, eventID); 
     } 
    } 

    public static void Warning(string entry) { Write(entry, EventLogEntryType.Warning, 200); } 
    public static void Warning(string entry, int eventID) { Write(entry, EventLogEntryType.Warning, eventID); } 
    public static void Error(string entry) { Write(entry, EventLogEntryType.Error, 300); } 
    public static void Error(string entry, int eventID) { Write(entry, EventLogEntryType.Error, eventID); } 
    public static void Info(string entry) { Write(entry, EventLogEntryType.Information, 100); } 
    public static void Info(string entry, int eventID) { Write(entry, EventLogEntryType.Information, eventID); } 
} 

Đây là cách mà tôi đã thực hiện lớp EventLogger của tôi mà được sử dụng trong một ứng dụng sản xuất.

Nếu bạn có thể đăng mã, chúng tôi có thể so sánh.

Một điều xảy ra với tôi là khi tôi tạo nguồn của mình, tôi sử dụng tên ứng dụng, nhưng gắn bó với tệp nhật ký Ứng dụng. Bạn cũng đang cố tạo một logfile mới. Nếu vậy hãy kiểm tra xem nó có được tạo trong trình xem sự kiện hay không.

EDIT 2: Mạo danh người dùng với một người sử dụng giá trị thẻ của zero

Đây là một chút của một câu hỏi khó.

Hãy thử mã này, được bao quanh mã ghi sự kiện.

System.Security.Principal.WindowsImpersonationContext wic = System.Security.Principal.WindowsIdentity.Impersonate(IntPtr.Zero); 
// your code to write to event log or any to do something which needs elevated permission-- 
wic.Undo(); 

tôi đã không cố gắng này, đơn giản chỉ vì mã của tôi đang làm việc, nó xuất phát từ đây: http://sharenotes.wordpress.com/2008/03/18/cannot-open-log-for-source-you-may-not-have-write-access/

+0

Tôi nghĩ ý tưởng thứ 3 của bạn về việc tải ứng dụng và chạy nó một lần sẽ phải là giải pháp của tôi vì toàn bộ mục đích của ClickOnce là nó xử lý triển khai và cài đặt. Tuy nhiên ngay cả khi tôi tạo nguồn sự kiện trong một ứng dụng như vậy, tôi nhận được một lỗi khi tôi đi để viết cho nó. Nó nói "Không thể mở nhật ký cho nguồn 'MySource'. Bạn có thể không có quyền ghi." Điều này có vẻ như tôi đang tiến gần hơn, nhưng nó không hoàn toàn ở đó. – Fr33dan

+0

Bạn đã thoát khỏi ứng dụng trước khi cố viết? Trong đoạn mã đó từ MS, chúng tuyên bố rõ ràng rằng nguồn nhật ký không được tạo và được sử dụng ngay lập tức vì có khoảng thời gian trễ cần thiết để kích hoạt nguồn. –

+0

Có, tại thời điểm này, tôi chạy ứng dụng thiết lập theo cách thủ công để xem nó có hoạt động hay không vì vậy đã có hơn 20 giây giữa việc tạo nguồn và cố gắng ghi vào nó. – Fr33dan

0

Trong ClickOnce documentation, người ta nói rằng nếu người dùng chạy một ứng dụng ClickOnce không phải là một quản trị viên , ứng dụng sẽ không ghi vào nhật ký sự kiện.

Full quote:

Sau khi triển khai ClickOnce, ứng dụng sẽ tạo ra một nguồn sự kiện nếu nó chưa tồn tại khi những nỗ lực ứng dụng để viết một sự kiện vào nhật ký sự kiện. Nếu người dùng không phải là quản trị viên, nỗ lực không thành công và ứng dụng sẽ không ghi lại bất kỳ sự kiện nào. Trong trường hợp này, bạn có thể tạo nguồn sự kiện theo cách thủ công.

Để tạo nguồn sự kiện bằng tay, bạn sẽ có thêm một mục trong registry như thế này trong suốt quá trình triển khai của bạn:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\YourApp] 
"EventMessageFile"="%SystemRoot%\\Microsoft.NET\\Framework\\v2.0.50727\\EventLogMessages.dll" 

Cách tiếp cận này sẽ hạn chế nhu cầu cao ở giai đoạn triển khai.

+0

Vì ClickOnce xử lý triển khai và cài đặt, tôi sẽ phải tìm cách khác để chạy nó với tư cách quản trị viên. Tôi đã tạo một tệp thực thi được đóng gói để chạy mã với tư cách quản trị viên. Chỉnh sửa đăng ký của bạn tạo nguồn sự kiện, nhưng tôi vẫn nhận được lỗi "Không thể mở nhật ký cho nguồn 'MySource'. Bạn có thể không có quyền ghi." khi tôi cố gắng và viết cho nó. – Fr33dan

2

Một cách tiếp cận khác là tải xuống tệp ClickOnce setup.exe, nhấp chuột phải và chạy với tư cách quản trị viên. Không phải là rất thỏa đáng nhưng dường như làm việc.