2016-10-17 2 views
0

서비스를 구축 중입니다. 기본적으로 디렉토리에 파일이 도착할 때까지 기다렸다가 파일을 다른 디렉토리로 암호화 한 다음 삭제합니다. 그것은 서비스가 아니지만 잘 작동하지만 서비스로 작동하지는 않습니다. 나는 그것을 디버깅하는 서비스를 중단 할 때, 그것은프로그램 실행 서비스가 실행될 때까지 실행

ServiceBase.Run(ServicesToRun); 

에 붙어 결코 실제로 파일이 지정된 디렉토리를 입력 할 때 코드를 실행하는 것 같다되지 않습니다. 이것은 나의 첫 번째 서비스이고 많은 코드가 AES encryption on large fileshttps://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx에서 나왔습니다. 어떤 입력이라도 크게 환영 할 것입니다.

/// Program.CS 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.ServiceProcess; 
    using System.Text; 
    using System.Threading.Tasks; 

    namespace XYZDataEncryptor 
    { 
     static class Program 
     { 
      /// <summary> 
      /// The main entry point for the application. 
      /// </summary> 
      static void Main() 
      { 
       ServiceBase[] ServicesToRun; 
       ServicesToRun = new ServiceBase[] 
       { 
        new XYZDataEncryptor() 
       }; 
       // stuck here in service debugger 
       ServiceBase.Run(ServicesToRun); 
      } 
     } 
    } 


    /// XYZDataEncryptor.CS 
    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Diagnostics; 
    using System.Linq; 
    using System.ServiceProcess; 
    using System.Text; 
    using System.Threading.Tasks; 
    using System.Runtime.InteropServices; 
    using System.IO; 
    using System.Threading; 
    using System.Security.Cryptography; 

    namespace XYZDataEncryptor 
    { 
     public partial class XYZDataEncryptor : ServiceBase 
     { 
      public XYZDataEncryptor() 
      { 
       InitializeComponent(); 
      } 

      protected override void OnStart(string[] args) 
      { 
       // Update the service state to Start Pending. 
       ServiceStatus serviceStatus = new ServiceStatus(); 
       serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING; 
       serviceStatus.dwWaitHint = 100000; 
       SetServiceStatus(this.ServiceHandle, ref serviceStatus); 
       System.Timers.Timer timer = new System.Timers.Timer(); 
       timer.Interval = 60000; // 60 seconds 
       // Run the OnTimer Process 
       timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer); 
       timer.Start(); 

       // Update the service state to Running. 
       serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING; 
       SetServiceStatus(this.ServiceHandle, ref serviceStatus); 
      } 
      public void OnTimer(object sender, System.Timers.ElapsedEventArgs args) 
      { 
       // process the files 
       ProcessFiles(); 
      } 
      protected override void OnStop() 
      { 
      } 

      public enum ServiceState 
      { 
       SERVICE_STOPPED = 0x00000001, 
       SERVICE_START_PENDING = 0x00000002, 
       SERVICE_STOP_PENDING = 0x00000003, 
       SERVICE_RUNNING = 0x00000004, 
       SERVICE_CONTINUE_PENDING = 0x00000005, 
       SERVICE_PAUSE_PENDING = 0x00000006, 
       SERVICE_PAUSED = 0x00000007, 
      } 

      [StructLayout(LayoutKind.Sequential)] 
      public struct ServiceStatus 
      { 
       public long dwServiceType; 
       public ServiceState dwCurrentState; 
       public long dwControlsAccepted; 
       public long dwWin32ExitCode; 
       public long dwServiceSpecificExitCode; 
       public long dwCheckPoint; 
       public long dwWaitHint; 
      }; 



      [DllImport("advapi32.dll", SetLastError = true)] 
      private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus); 


      private static void ProcessFiles() 
      { 

       string path = @"q:\XYZraw"; 
       string outPath = @"q:\XYZEncryptedRaw"; 
       string[] rawFiles = Directory.GetFiles(@"q:\XYZraw\", "*.txt"); 

       foreach (string fileName in rawFiles) 
       { 
        // check if the file has fully arrived then encrypt it 
        CheckFile(path, outPath, fileName); 

       } 
      } 

      private static void CheckFile(string path, string outPath, string fileName) 
      { 
       if (File.Exists(fileName)) 
       { 
        bool finished = false; 
        while (!finished) 
        { 
         // Wait if file is still open 
         FileInfo fileInfo = new FileInfo(fileName); 
         while (IsFileLocked(fileInfo)) 
         { 
          // check to see if the file is still open (locked) 
          Thread.Sleep(5000); 
         } 
         finished = true; 
        } 


        string outFile = outPath + fileName.Substring(fileName.LastIndexOf("\\")); 
        // This path is a file 
        byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 
        // encrypt file 
        AES_Encrypt(fileName, outFile, saltBytes); 
        File.Delete(fileName); 
       } 

      } 

      private static void AES_Encrypt(string inputFile, string outputFile, byte[] passwordBytes) 
      { 
       byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 
       string cryptFile = outputFile; 
       FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create); 

       RijndaelManaged AES = new RijndaelManaged(); 

       AES.KeySize = 256; 
       AES.BlockSize = 128; 


       var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); 
       AES.Key = key.GetBytes(AES.KeySize/8); 
       AES.IV = key.GetBytes(AES.BlockSize/8); 
       AES.Padding = PaddingMode.Zeros; 

       AES.Mode = CipherMode.CBC; 

       CryptoStream cs = new CryptoStream(fsCrypt, 
        AES.CreateEncryptor(), 
        CryptoStreamMode.Write); 

       FileStream fsIn = new FileStream(inputFile, FileMode.Open); 

       int data; 
       while ((data = fsIn.ReadByte()) != -1) 
        cs.WriteByte((byte)data); 


       fsIn.Close(); 
       cs.Close(); 
       fsCrypt.Close(); 

      } 


      static bool IsFileLocked(FileInfo file) 
      { 
       FileStream stream = null; 

       try 
       { 
        stream = file.Open(FileMode.Open, 
          FileAccess.ReadWrite, FileShare.None); 
       } 
       catch (IOException) 
       { 
        //the file is unavailable because it is: 
        //still being written to 
        //or being processed by another thread 
        //or does not exist (has already been processed) 
        return true; 
       } 
       finally 
       { 
        if (stream != null) 
         stream.Close(); 
       } 

       //file is not locked 
       return false; 
      } 



     } 
    } 
+1

대신 서비스, 당신이 프로그램을 실행하려면 작업 스케줄러를 사용할 수 있습니다

는 서비스로 오래 살고 필드로 타이머를 선언합니다. – urlreader

+0

좋은 생각인데 프로그램이 매분마다 실행되어야 서비스가 더 나은 전략 인 것 같습니다. – Missy

+0

@urlreader - 작업 스케줄러를 실행할 수없는 것 같습니다. 서비스 아이디어가 작동하지 않으며 디버깅 방법을 알 수 없습니다. 나는 모든 최고 권한을 주었고 서비스로 표시했지만 실제로 실행하지는 못했습니다. 그래서 나는 작업 스케줄러 아이디어로 전환했고 그것이 실행 중이라는 것을 나타내지 만 그것이 예정된 작업에서만 작업 관리자에 없다는 표시가 없습니다. 어떤 아이디어? – Missy

답변

1

당신은 새로운 타이머가 범위를 벗어나하면

protected override void OnStart(string[] args) 

내부의 지역 범위가

System.Timers.Timer timer = new System.Timers.Timer(); 

를 만드는, 그것은 쓰레기 수집 할 수 있습니다. 이것은 조만간 발생할 수 있으므로 쓰레기 수거시기에 따라 서비스가 더 짧거나 길게 작동합니다.

System.Timers.Timer _timer; 

protected override void OnStart(string[] args) 
{ 
    [...] 
    _timer = new System.Timers.Timer(); 
    _timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer); 
    _timer.Start(); 
    [...] 
+0

Hi Thomas - 답변 해 주셔서 감사합니다. 그 일을 어떻게 처리 할 수 ​​있겠습니까? – Missy

+0

서비스는 영원히 살 것입니다. – Missy

+1

@Missy : 답변을 –

관련 문제