Использование EventLog в приложении ClickOnce
у меня есть библиотека, которую я использую в нескольких приложениях ClickOnce. В случае ошибки в этой библиотеке я хотел бы написать ошибку в windows EventLog
.
нашел KB статья о том, как, но кажется,что для этого требуются разрешения администратора для поиска источника. В частности, он задыхается при попытке поиска Security
журнал событий.
есть ли в любом случае, чтобы обойти это и записать в журнал событий в ClickOnce заявление? Я видел одного человека попытка написать известному источнику, но они, похоже, не смогли найти источник, который был бы постоянно доступен.
EDIT:
на основе ответов здесь я создаю программу, которая входит в мое приложение, которое я могу запустить при первом запуске, чтобы настроить источник событий, который может получить права администратора. Однако, как только источник создан, кажется, я все еще не могу написать ему.
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
if (!EventLog.SourceExists("ATE"))
{
EventLog.CreateEventSource("ATE", "Application");
}
}
Is правильно создает источник (что эквивалентно редактированию реестра, предоставленному Yannick Blondeau). Когда я пишу источнику в своем приложении без повышенных прав, я получаю новую ошибку, но она все равно не работает. Новая ошибка:
Cannot open log for source 'ATE'. You may not have write access.
EDIT 2:
теперь я пытаюсь заставить его работать через изменения реестра на ключ CustomSD. Я попытался добавить (A;; 0x7;;; AU), чтобы предоставить аутентифицированным пользователям полный доступ, но это не кажется, есть какой-то эффект.
3 ответов
к сожалению, источник событий требует создания административных priveledges. Однако, вам не нужны права администратора для записи в журнал событий, или читать из него.
есть два способа обойти это.
вы добавляете новый источник событий при установке приложения в качестве администратора.
вы создаете простое приложение, которое вы запускаете в качестве администратора для настройки приложения. Это может быть даже включено в программу установки.
Если вы не или установщика, то загрузите приложение на компьютер как администратор и запустить программу. Ваш запуск приложения должен настроить источник событий, если он еще не существует, верно? (Хорошо, это три способа.)
этот фрагмент кода от microsoft:http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx и предназначен для запуска от имени администратора.
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.");
}
}
Я знаю, что это может быть не совсем то, что вы хотели, но я считаю это единственный способ сделать это.
EDIT 1: добавлен дополнительный код
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); }
}
таким образом я реализовал класс EventLogger, который используется в производственном приложении.
Если вы могли бы опубликовать свой код, мы можем сделать сравнение.
мне приходит в голову, что при создании источника я использую имя приложения, но придерживаюсь файла журнала приложения. Вы также пытаетесь создать новый файл журнала. Если так убедитесь, что он создан в средстве просмотра событий.
EDIT 2: олицетворение Пользователя со значением токена пользователя ноль
Это немного сложно.
попробуйте этот код, обернутый вокруг события написания кода.
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();
Я не пробовал это, просто потому, что мой код работает, он исходит отсюда: http://sharenotes.wordpress.com/2008/03/18/cannot-open-log-for-source-you-may-not-have-write-access/
альтернативным подходом к этому является загрузка установки ClickOnce.exe-файл, щелкните правой кнопкой мыши и запустите от имени администратора. Не очень удовлетворительно, но, кажется, работает.
на документация ClickOnce, говорится, что если пользователь, запускающий приложение ClickOnce, не является администратором, приложение не сможет записать в журнал событий.
полная цитата:
после развертывания ClickOnce приложение создаст событие источник, если он еще не существует, когда приложение пытается запись события в журнал событий. Если пользователь не является администратором, попытка не удалась, и приложение не будет регистрировать события. В этом случае, вы можете создать источник событий вручную.
чтобы создать источник событий вручную, вам нужно будет добавить такую запись в реестр во время процесса развертывания:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\YourApp]
"EventMessageFile"="%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\EventLogMessages.dll"
этот подход ограничит потребность в высоте на этапе развертывания.