窗口服务抛出类型初始化程序错误

时间:2011-10-05 21:29:15

标签: c# windows-services

我不确定这个应用程序发生了什么。它运行良好,然后有一天它停止工作。我试图消除代码中的单个元素,但是一旦我添加了一些枚举(见下面的代码)它就破坏了 - 所以我删除了它们但是这并没有扭转这个问题。然后我从一个全新的win服务(使用VS2010和VS2008)开始,添加了类级变量,并在添加枚举后再次启动服务。

这是代码,我想知道是否有人可以帮助我。我真的很感激。

using _Mail;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Net.Mail;
using Microsoft.Office.Core;
using Microsoft.Office.Interop.PowerPoint;
using Microsoft.SharePoint;

namespace Uploader
{

public partial class _UploaderService : ServiceBase
{
    private static string smtpServer = ConfigurationManager.AppSettings["smtpServer"];
    private static string sendTo = ConfigurationManager.AppSettings["sendTo"];
    private static string sendFrom = ConfigurationManager.AppSettings["sendFrom"];
    private static string portalURL = ConfigurationManager.AppSettings["portalURL"];
    private static string imageListFolder = ConfigurationManager.AppSettings["imageListFolder"];
    private static string remFolder = ConfigurationManager.AppSettings["remoteFolder"];
    private static string sourceFileName = ConfigurationManager.AppSettings["sourceFileName"];
    private static string remoteDriveLetter = ConfigurationManager.AppSettings["remoteDriveLetter"];
    private static string remoteShareName = ConfigurationManager.AppSettings["remoteShareName"];
    private static string userName = ConfigurationManager.AppSettings["userName"];
    private static string userPwd = ConfigurationManager.AppSettings["userPwd"];
    private static string statusMessage;
    private static string[] files;

    private static SPWeb _Web = new SPSite(portalURL).OpenWeb();
    private static NETRESOURCE res = new NETRESOURCE();

    public enum ResourceScope
    {
        RESOURCE_CONNECTED = 1,
        RESOURCE_GLOBALNET,
        RESOURCE_REMEMBERED,
        RESOURCE_RECENT,
        RESOURCE_CONTEXT
    };
    public enum ResourceType
    {
        RESOURCETYPE_ANY,
        RESOURCETYPE_DISK,
        RESOURCETYPE_PRINT,
        RESOURCETYPE_RESERVED
    };
    public enum ResourceUsage
    {
        RESOURCEUSAGE_CONNECTABLE = 0x00000001,
        RESOURCEUSAGE_CONTAINER = 0x00000002,
        RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004,
        RESOURCEUSAGE_SIBLING = 0x00000008,
        RESOURCEUSAGE_ATTACHED = 0x00000010
    };
    public enum ResourceDisplayType
    {
        RESOURCEDISPLAYTYPE_GENERIC,
        RESOURCEDISPLAYTYPE_DOMAIN,
        RESOURCEDISPLAYTYPE_SERVER,
        RESOURCEDISPLAYTYPE_SHARE,
        RESOURCEDISPLAYTYPE_FILE,
        RESOURCEDISPLAYTYPE_GROUP,
        RESOURCEDISPLAYTYPE_NETWORK,
        RESOURCEDISPLAYTYPE_ROOT,
        RESOURCEDISPLAYTYPE_SHAREADMIN,
        RESOURCEDISPLAYTYPE_DIRECTORY,
        RESOURCEDISPLAYTYPE_TREE,
        RESOURCEDISPLAYTYPE_NDSCONTAINER
    };
    [StructLayout(LayoutKind.Sequential)]
    public struct NETRESOURCE
    {
        public ResourceScope dwScope;
        public ResourceType dwType;
        public ResourceDisplayType dwDisplayType;
        public ResourceUsage dwUsage;
        public string lpLocalName;
        public string lpRemoteName;
        public string lpComment;
        public string lpProvider;
    };

    [DllImport("mpr.dll")]
    public static extern int WNetAddConnection2(ref NETRESOURCE
    netResource, string password, string username, int flags);

    public cisf_UploaderService()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {            
        try
        {
            FileSystemWatcher fsWatcher = new FileSystemWatcher();
            fsWatcher.Created += new FileSystemEventHandler(fsw_Created);

            DisconnectDrive(remoteDriveLetter);
            res.dwType = ResourceType.RESOURCETYPE_DISK;
            res.lpLocalName = remoteDriveLetter;
            res.lpRemoteName = remoteShareName;
            int stat = WNetAddConnection2(ref res, null, null, 0);
            statusMessage += "Map Network Drive status - " + stat + ".";

            //MapDrive();

            CleanUp();
            fsWatcher.Path = remFolder;
            fsWatcher.Filter = sourceFileName;
            fsWatcher.EnableRaisingEvents = true;
        }
        catch (Exception ex1)
        {
            WriteException(ex1,"Ex1");
        }
    }

    protected override void OnStop()
    {
    }

    static void fsw_Created(object sender, FileSystemEventArgs e)
    {
        statusMessage += "\nNew PowerPoint file detected in directory.";

        ConvetToJpegs();
        AcquireFiles();
        CleanUp();
        DisconnectDrive(remoteDriveLetter);

        statusMessage += "\nOperation sucessfuly completed.";

        EventLog.WriteEntry("Conversion Service Status", statusMessage, EventLogEntryType.Information);

    }

    protected static void ConvetToJpegs()
    {
        Microsoft.Office.Interop.PowerPoint.Application app = new Microsoft.Office.Interop.PowerPoint.Application();
        Presentation pptPresentation = null;

        try
        {
            pptPresentation = app.Presentations.Open(remFolder + sourceFileName, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
            pptPresentation.SaveAs(remFolder + ".", PpSaveAsFileType.ppSaveAsJPG, MsoTriState.msoFalse);

        }
        catch (Exception ex2)
        {
            WriteException(ex2, "Ex2");
        }
        finally
        {
            pptPresentation.Close();
            statusMessage += "\nFile conversion completed.";
        }
    }

    protected static void AcquireFiles()
    {
        files = null;

        try
        {
            files = Directory.GetFiles(remFolder, "*.jpg");
        }
        catch (Exception ex3)
        {
            WriteException(ex3, "Ex3");
        }
        finally
        {
            statusMessage += "\nFiles acquired.";
            if (files.Length > 0)
            {
                DeleteOldSlides();
            }
        }
    }

    protected static void DeleteOldSlides()
    {
        SPList imagesLibrary = _Web.Lists[imageListFolder];
        _Web.AllowUnsafeUpdates = true;
        try
        {
            while (imagesLibrary.Items.Count > 1)
            {
                imagesLibrary.Items[imagesLibrary.Items.Count - 1].File.Delete();
            }
        }
        catch (Exception ex4)
        {
            WriteException(ex4, "Ex4");
        }
        finally
        {
            statusMessage += "\nOld slides deleted.";
            UploadToSharePoint();
        }
    }

    protected static void UploadToSharePoint()
    {
        _Web.AllowUnsafeUpdates = true;

        FileStream fs = null;
        string fileName = string.Empty;

        try
        {
            foreach (string file in files)
            {

                fileName = file.Split(@"\".ToCharArray())[1].ToLower();
                fs = File.Open(file, FileMode.Open);
                _Web.Files.Add(imageListFolder + "/" + fileName, fs, true);
                fileName = string.Empty;
                fs.Close();
            }
        }
        catch (Exception ex5)
        {
            WriteException(ex5, fileName);
        }
        finally
        {
            statusMessage += "\nFiles uploaded to SharePoint.";
            _Web.AllowUnsafeUpdates = false;
        }
    }

    protected static void CleanUp()
    {
        string[] path = Directory.GetFiles(remFolder, "*.jpg");
        string[] path1 = Directory.GetFiles(remFolder, "*.pptx");

        try
        {
            foreach (string tempfiles in path1)
            {
                if (path != null)
                {
                    File.Delete(tempfiles);
                }
            }
            foreach (string tempfiles in path)
            {
                if (path != null)
                {
                    File.Delete(tempfiles);
                }
            }
        }
        catch (Exception ex6)
        {
            WriteException(ex6, "Ex6");
        }
        finally
        {
            statusMessage += "\nFiles deleted from temporary directory " + remoteShareName ;
        }
    }

    //public static bool MapDrive() 
    //{ 
    //    bool ReturnValue = false;
    //    if (System.IO.Directory.Exists(remoteDriveLetter + ":\\")) 
    //    {
    //        DisconnectDrive(remoteDriveLetter); 
    //    } 
    //    System.Diagnostics.Process p = new System.Diagnostics.Process(); 
    //    p.StartInfo.UseShellExecute = false; 
    //    p.StartInfo.CreateNoWindow = true; 
    //    p.StartInfo.RedirectStandardError = true; 
    //    p.StartInfo.RedirectStandardOutput = true; 
    //    p.StartInfo.FileName = "net.exe";
    //    p.StartInfo.Arguments = " use " + remoteDriveLetter + ": " + remoteShareName + " " + userPwd + " /user:" + userName; 
    //    p.Start(); 
    //    p.WaitForExit(); 
    //    string ErrorMessage = p.StandardError.ReadToEnd(); 
    //    string OuputMessage = p.StandardOutput.ReadToEnd(); 
    //    if (ErrorMessage.Length > 0) 
    //    { 
    //        throw new Exception("Error:" + ErrorMessage); 
    //    } else { ReturnValue = true; } return ReturnValue; }

    protected static void DisconnectDrive(string DriveLetter)
    {
        Process p = new Process();

        p.StartInfo.UseShellExecute = false;
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.RedirectStandardError = true;
        p.StartInfo.RedirectStandardOutput = true;

        try
        {
            p.StartInfo.FileName = "net.exe";
            p.StartInfo.Arguments = " use " + "Z" + ": /DELETE";
            p.Start();
        }
        catch (Exception ex7)
        {
            WriteException(ex7, "Ex7");
        }
        finally
        {
            p.WaitForExit();
        }
    }

    public static void WriteException(Exception ex, string source)
    {
        string err = "Uploader Error" +
                     "\n\nError Message from method " + source + ": " + ex.Message.ToString() +
                     "\n\nStack Trace: " + ex.StackTrace.ToString() + "\n";
        EventLog.WriteEntry("Conversion Service", err, EventLogEntryType.Warning);

        _Mail sendEmail = new _Mail();
        sendEmail.SMTPServer = smtpServer;
        sendEmail.MailTo = sendTo;
        sendEmail.MailFrom = sendFrom;
        sendEmail.MailSubject = "Uploader Error";
        sendEmail.MailBody = err;
        sendEmail.Send();
    }        
}
}

2 个答案:

答案 0 :(得分:0)

类型初始化程序错误表示无法创建类型。当CLR初始化所有静态字段时,在调用构造函数之前发生这种情况。由于您的初始化不仅仅是调用私有构造函数或设置文字值,而是让您自己难以调试问题

在这种情况下,它可能会导致您的某个AppSettings键出现问题

e.g。

private static string smtpServer = ConfigurationManager.AppSettings["smtpServer"];
private static string sendTo = ConfigurationManager.AppSettings["sendTo"];
...

这看起来也很可疑。

private static SPWeb _Web = new SPSite(portalURL).OpenWeb();
private static NETRESOURCE res = new NETRESOURCE();

而是在构造函数中执行您需要执行的操作。您可能还想添加一个辅助方法,这样您就可以提出一个更好的异常(或者您可以将Marc Gravel评论看作内部异常)

例如

 private string safeGetAppSetting(string key)
 {

   try 
   { 
         return ConfigurationManager.AppSettings["smtpServer"];
   }
   catch(ConfigurationErrorsException)
   {
        throw new InvalidOperationException(string.Format("key {0} is missing or misconfigured", key);
   }
 }




public cisf_UploaderService()
{
    InitializeComponent();
    smtpServer = safeGetAppSetting("smtpServer");
}

更新在后见之明中将Debugger.Launch()添加到Program.Main(),因为kzen提到可能是值得的。如果它不是本地开发机器,那么在根处添加一些额外的日志记录的问题也可能有所帮助。

        try
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new SampleWindowsService() 
            };
            ServiceBase.Run(ServicesToRun);
        }
        catch (Exception ex)
        {
            string SourceName = "YourService.ExceptionLog";
            if (!EventLog.SourceExists(SourceName))
            {
                EventLog.CreateEventSource(SourceName, "Application");
            }

            EventLog eventLog = new EventLog();
            eventLog.Source = SourceName;
            string message = "";
            if (ex.InnerException  != null)
                string message = string.Format("Exception: {0} \n\nStack: {1} \n\nInnerException: {2}", ex.Message, ex.StackTrace, ex.InnerException.Message);
            else
                string message = string.Format("Exception: {0} \n\nStack: {1}", ex.Message, ex.StackTrace);
            eventLog.WriteEntry(message, EventLogEntryType.Error);
        }

答案 1 :(得分:0)

Debugger.Launch();作为代码的第一行,启动服务并逐行调试,直到找到确切的代码行引发异常......