65.9K
CodeProject 正在变化。 阅读更多。
Home

应用程序管理

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.71/5 (5投票s)

2010年2月18日

Ms-PL

3分钟阅读

viewsIcon

29842

downloadIcon

713

Application Management 让您的应用程序生活更轻松。它将自动进行内存管理,处理和记录未处理的异常,分析您的函数,使您的应用程序成为单实例,并提供用于获取系统信息的实用函数。

目录

引言

Application Management 让您的应用程序生活更轻松。它将自动进行内存管理,处理和记录未处理的异常,分析您的函数,使您的应用程序成为单实例,并提供用于获取系统信息的实用函数。

支持的平台

该库可在多个平台上运行,并在 Windows XP、Windows 7 和 Linux Ubuntu 9.10 上进行了测试。对于 Linux,我提供了 Mono 编译版本,您可以重新编译或执行。bin 下的 DebugRelease 文件夹是使用 Visual Studio 2008 (Windows) 编译的。bin 下的 Mono 文件夹是使用 MonoDevelop (Mono 系统兼容) 编译的。

类和函数受操作系统不兼容异常的保护。所有 WinAPI 函数在 Windows 系统外都将无法正常工作。

如果您想进行自己的系统验证,请使用以下代码

if(Environment.OSVersion.Platform == PlatformID.Win32NT)
{
    // Windows NT Platform
}
else
{
    // Non Windows System
}

ApplicationManagement_app_v1

背景

此库不能替代您的内联优化,只要可能,您始终必须 Dispose 您的对象。

使用代码

大多数类都应该在作用域之外使用,并声明为 static。我将使用 public static 来允许我从任何地方访问类。具有 Start(); 方法的类也具有 Stop(); 方法。

库中的类

有关类的更多信息,请参阅文档文件。

  • WinAPI (包含所有 Win API 调用) 命名空间
    • Dbghelp (Dbghelp.dll 的所有 API 调用) 静态类
    • Kernel32 (Kernel32.dll 的所有 API 调用) 静态类
  • About (存储有关库、作者、网页等的常量...) 静态类
  • AssemblyEx (来自程序集的 Util 函数) 静态类
  • ExceptionHandler (自动处理和记录未处理的异常) 类
  • Instance (使您的应用程序成为单实例) 类
  • MemoryManagement (自动内存管理) 类
  • MiniDump (用于创建迷你转储) 静态类
  • Profiling (用于分析函数,ProfilingDataDictionary) 类
    • ProfilingData (存储分析数据的类,StartDate、EndDate、TimeTaken,...) 类
  • SystemInformationEx (提供一些与系统信息相关的 GET 函数) 静态类
  • VistaSecurity (与 Windows Vista 及更高版本相关的函数) 静态类

Instance 类

public static Instance instance;
[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    #region Instance Class (Make single instance app)
    // Check if that is a single instance, and name mutex as: "{ProductName}Mutex"
    instance = new Instance(Application.ProductName);
    // instance is created but make sure you call next line:
    // First parameter is used to define mutex level (Global or this session only)
    // Second parameter is used to check processes equality after check mutex
    if (!instance.MakeSingleInstance(true, false))
    {
        Instance.ShowDuplicateInstanceDialogError();
        // Stop and quit App.
        return;
    }
    #endregion

    Application.Run(new MainFrm());
    // Note: by calling 'Instance.Dispose' method will release mutex,
    // and app will be multi instance,
    // But still checks for process equality!
    // instance.Dispose();
}

MemoryManagement 类

appmanagement_memorymanagement.png

注意: MemoryManagement 仅在 WinNT 系统中生效;否则,您仍然可以在任何系统下使用 **静态方法**。

public static MemoryManagement memory;
[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    #region Memory Management class
    // MemoryManagement only make effect in WinNT Systems, 
    // if your app is multi system use that.
    if (MemoryManagement.CanUseClass())
    {
        memory = new MemoryManagement();
        memory.Start();
    }
    else
    {
        memory = null;
    }
    #endregion

    Application.Run(new MainFrm());
}

ExceptionHandler 类

注意: 请确保在运行应用程序之前启动。如果未启动,请在运行应用程序之前使用以下代码

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

appmanagement_exceptiondialog.png

此类可以生成包含详细错误信息的 .txt 文件。它还可以创建可使用 Visual Studio 等程序进行调试的转储 (.dmp) 文件。Minidump 文件 (Windows) [^]

日志存储的默认目录是:APPEXEdir\Logs\AppErrors\。文件名格式为:yyyy_MM_dd_HH_mm_ss

public static ExceptionHandler exceptionHandler;
[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    #region Exception Handler Class 
           (Automatic cath and log unhandled exceptions)
    // Automatic cath and log unhandled exceptions
    exceptionHandler = new ExceptionHandler();
    // Next two lines are optional
    exceptionHandler.PrefixText = 
      "This file represets an error cath on our program";
    exceptionHandler.SuffixText = 
         "Please fell free to send us that errors " + 
         "files via email: myapp@company.com";
    exceptionHandler.StartHandlingExceptions();
    #endregion

    Application.Run(new MainFrm());
}

以下是未处理异常日志的示例 (MyTestApp__2010_02_15_18_35_29.txt)。

[MyTestApp]
Date=15-02-2010 18:35:29
Application=MyTestApp 1.0.0.0
ExecutablePath=D:\caza\c++\ApplicationManagement\MyTestApp\
                        bin\Release\MyTestApp.exe
Company=MyTestApp

This file represets an error cath on our program

########################
##        Error       ##
########################
[Exception1]
Message=O valor não pode ser nulo.
StackTrace=   em MyTestApp.MainFrm.ButtonClick(Object sender, EventArgs e) 
   em D:\caza\c++\ApplicationManagement\MyTestApp\MainFrm.cs:line 115
   em System.Windows.Forms.Control.OnClick(EventArgs e)
   em System.Windows.Forms.Button.OnClick(EventArgs e)
   em System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   em System.Windows.Forms.Control.WmMouseUp(
                   Message& m, MouseButtons button, Int32 clicks)
   em System.Windows.Forms.Control.WndProc(Message& m)
   em System.Windows.Forms.ButtonBase.WndProc(Message& m)
   em System.Windows.Forms.Button.WndProc(Message& m)
   em System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   em System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   em System.Windows.Forms.NativeWindow.Callback(
                   IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
TargetSite=Void ButtonClick(System.Object, System.EventArgs)
Source=MyTestApp
HelpLink=


########################
## System Information ##
########################
[System]
OperativeSystem=Windows 7 x86
ProcessorCount=2


########################
##     Open Forms     ##
########################
[Forms]
Form1=MyTestApp.MainFrm, Text: ApplicationManagement Library Test


########################
## Loaded Assemblies  ##
########################
[mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]
   Location=C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll

[MyTestApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]
   Location=D:\caza\c++\ApplicationManagement\
                 MyTestApp\bin\Release\MyTestApp.exe

[ApplicationManagement, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]
   Location=D:\caza\c++\ApplicationManagement\MyTestApp\
                 bin\Release\ApplicationManagement.dll

[System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
                                    PublicKeyToken=b77a5c561934e089]
   Location=C:\Windows\assembly\GAC_MSIL\System.Windows.Forms\
                  2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll

[System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]
   Location=C:\Windows\assembly\GAC_MSIL\System\
                 2.0.0.0__b77a5c561934e089\System.dll

[System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]
   Location=C:\Windows\assembly\GAC_MSIL\System.Drawing\
                  2.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll

[System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]
   Location=C:\Windows\assembly\GAC_32\System.Data\
                  2.0.0.0__b77a5c561934e089\System.Data.dll

[mscorlib.resources, Version=2.0.0.0, Culture=pt, PublicKeyToken=b77a5c561934e089]
   Location=C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll

Please fell free to send us that errors files via email: myapp@company.com

Profiling 类

注意:最好直接使用 Profiling.ProfilingDataProfiling 类是 Profiling.ProfilingData 的一个 Dictionary

public static Profiling profiling;
[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    #region Profiling Class
    // Our profiling will determinate the time taken by the app to initialize.
    profiling = new Profiling();
    Profiling.ProfilingData profilingData = profiling.Create("InitApp", true);
    #endregion

    // Wait 1.5s and see the output
    Thread.Sleep(1500);

    #region End started profile and show results
    profilingData.Stop();
    MessageBox.Show(
        string.Format(
            "Start Date: {0}\nEnd Date: {1}\nTime Taken: {2}ms", 
                 profilingData.StartDate,
                 profilingData.EndDate,
                 profilingData.TimeTaken.TotalMilliseconds
            ),
        "Our application initializes time");
    #endregion

    Application.Run(new MainFrm());
}

另一个例子

/// <summary>
/// Do some job and returns the time it takes
/// </summary>
Profiling.ProfilingData MyFunction()
{
    // Note is better use a single class to all your profiling, but...
    // Initialize class, create a profiling and start it
    Profiling profiling = new Profiling("MyFunction", true);
    // Also can use:
    // Profiling.ProfilingData pData = profiling.Create("MyFunction");
    // if (pData == null)
    //     Console.WriteLine("Won't execute profiling, name already exists.");
    
    // Lets make some garbage
    for(int i = 1; i <= 10000; i++)
    {
        Random rand = new Random();
        Console.WriteLine(rand.Next(0, i));
    }
    
    // Function ends now let stop profiling and return the results.
    Profiling.ProfilingData pData = profiling.Get("MyFunction");
    // Note: you can check if pData is null if you not sure that exists
    pData.Stop(); // profiling.Stop("MyFunction"); also works
    return pData;
}

Profiling.ProfilingData pData = MyFunction();
if(pData.IsConcluded)
{
    Console.WriteLine("Total time to execute 'MyFunction': {0} ({1}ms)", 
                pData.TimeTaken, 
                pData.TimeTaken.TotalMilliseconds);
}
else
{
    Console.WriteLine("Developer doesn't write the function correct");
    Console.WriteLine("A ProfilingData must be Stopped, " + 
                      "before use EndDate and TimeTaken");
}

注意:为了避免重复键并方便编码,您可以使用 Profiling.ProfilingData。**再次强调**,Profiling 类是可选的,只是一个包装器,用于存储 Profiling.ProfilingData 类,其中包含一个 Dictionary<string, Profiling.ProfilingData>。**但是**,如果您想保留和存储一个分析函数以供以后使用或获取结果,最好使用 Profiling 类。

Profiling.ProfilingData pData = new Profiling.ProfilingData();
pData.Start();

// Do your job here, time is counting!!!
// This way is more simple than use Profiling Class

pData.Stop();
/*
*
* pData.StartDate;
* pDate.EndDate;
* pDate.TimeTaken;
*
*/
// Discard variable
pData = null;

VistaSecurity 类

/// <summary>
/// Under Windows Vista, if current user is not an administrator, 
/// try elevate the permissions and exit from current application.
/// </summary>
if(!VistaSecurity.IsAdmin())
{
    if(VistaSecurity.RestartElevated(Application.ExecutablePath))
        Application.Exit();
}

整合所有内容

#region Variables
public static Instance instance;
public static MemoryManagement memory;
public static Profiling profiling;
public static ExceptionHandler exceptionHandler;
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    #region Profiling Class
    // Our profiling will determinate
    // the time taken by the app to initialize.
    profiling = new Profiling();
    Profiling.ProfilingData profilingData = 
       profiling.Create("InitApp", true);
    #endregion

    #region Instance Class (Make single instance app)
    // Check if that is a single instance, and name
    // mutex as: "{ProductName}Mutex"
    instance = new Instance(Application.ProductName);
    // instance is created but make sure you call next line:
    // First parameter is used to define mutex level
    // (Global or this session only)
    // Second parameter is used to check
    // processes equality after check mutex
    if (!instance.MakeSingleInstance(true, false))
    {
        Instance.ShowDuplicateInstanceDialogError();
        // Stop and quit App.
        return;
    }
    #endregion

    #region Memory Management class
    // MemoryManagement only make effect in WinNT Systems, 
    // if your app is multi system use that.
    if (MemoryManagement.CanUseClass())
    {
        memory = new MemoryManagement();
        memory.Start();
    }
    else
    {
        memory = null;
    }
    #endregion

    #region Exception Handler Class 
       (Automatic cath and log unhandled exceptions)
    // Automatic cath and log unhandled exceptions
    exceptionHandler = new ExceptionHandler();
    // Next two lines are optional
    exceptionHandler.PrefixText = 
      "This file represets an error cath on our program";
    exceptionHandler.SuffixText = 
      "Please fell free to send us that errors " + 
      "files via email: myapp@company.com";
    exceptionHandler.StartHandlingExceptions();
    #endregion

    #region End started profile and show results
    profilingData.Stop();
    MessageBox.Show(
        string.Format(
            "Start Date: {0}\nEnd Date: {1}\nTime Taken: {2}ms", 
                 profilingData.StartDate,
                 profilingData.EndDate,
                 profilingData.TimeTaken.TotalMilliseconds
            ),
        "Our application initializes time");
    #endregion
            
    Application.Run(new MainFrm());
    // Note: by calling 'Instance.Dispose' method will release mutex,
    // and app will be multi instance,
    // But still checks for process equality!
    // instance.Dispose();
}

您的项目是否使用了这个库?

如果您在任何项目中使用我的库,请告诉我。您可以在讨论区发布您的应用程序名称和链接。这对我来说也是一种激励,知道人们正在使用我的库。

捐赠

编写库需要时间,而我的所有工作都是免费的。捐赠对我来说是一种激励,鼓励我制作更好的库。请考虑捐赠:PayPal 捐赠[^]。

Donate

您也可以使用 SourceForge 的捐赠系统进行捐赠

Donate

其他主页

历史

版本 1.0

  • 首次发布。
© . All rights reserved.