none
Windows service 使用 account : Local system, NetworkService 時無法Access web service RRS feed

  • 問題

  • 小弟欲開發一隻Windows service,

    主要功能是在背景監控另外一隻通訊程式,是否有異常狀況發生(如失去回應等)

    若有異常狀況,則需要關閉並重啟該程式。

    被開啟的通訊程式不需出現GUI,也不用與User互動。

    且此程式單獨開啟時功能皆正常


    該通訊程式的主要功能是開啟Socket接收資料,

    並將資料傳上web service

    Windows service 使用 Process.start() 執行該程式。


    將Windows service 的 Account 設定為User時一切正常。

    但當 Account 設定為 Local system || NetworkService 時

    該通訊程式在Access web service 時就會出現Exception如下:

    System.Net.WebException: 無法連接至遠端伺服器 --->
    System.Net.Sockets.SocketException: 無法連線,因為目標電腦拒絕連線。


    已經嘗試過將該通訊程式整合進入Windows service中,

    但是依然會出現同樣問題。

    想請問各位前輩,

    小弟的問題出在哪裡呢?

    是給予該Windows service的權限不足嗎?

    還是其他的問題?

    感激不盡!!!


    最後附上Windows service 執行該通訊程式 的 Code :

            private bool bThread;
    
            private EventLog Logger;
            private Thread processThread;
            protected Process procsTDH, procsMS;
    
            private TaiDocHost taiDocHost;
    
            public TelecareMonitor()
            {
                InitializeComponent();
                if (!EventLog.SourceExists("Monitor"))
                {
                    EventLog.CreateEventSource("Monitor", "Monitor Log");
                }
    
                Logger = new EventLog();
                Logger.Source = "Monitor";
                Logger.Log = "Monitor Log";
            }
    
            protected override void OnStart(string[] args)
            {
                // TODO: Add code here to start your service.
                StartProgram(0);
                StartWatchDog();
            }
    
            protected override void OnStop()
            {
                // TODO: Add code here to perform any tear-down necessary to stop your service.
                if (procsTDH != null)
                {
                    try
                    {
                        procsTDH.Kill();
                    }
                    catch (Exception ex)
                    {
                        Logger.WriteEntry(ex.ToString(), EventLogEntryType.Error);
                    }
                }
    
                if (procsMS != null)
                {
                    try
                    {
                        procsMS.Kill();
                    }
                    catch (Exception ex)
                    {
                        Logger.WriteEntry(ex.ToString(), EventLogEntryType.Error);
                    }
                }
                Logger.WriteEntry("Monitor 服務停止");
            }
    
            void StartProgram(int i)
            {
                switch (i)
                {
                    case 0:
                        procsTDH = this.StartProcess(@"C:\xxx\", @"C:\xxx\xxx.exe");
                        procsMS = this.StartProcess(@"C:\xxx\", @"C:\xxx\yyy.exe");
                        break;
                    case 1:
                        procsTDH = this.StartProcess(@"C:\xxx\", @"C:\xxx\xxx.exe");
                        break;
                    case 2:
                        procsMS = this.StartProcess(@"C:\xxx\", @"C:\xxx\yyy.exe");
                        break;
                    default:
                        break;
                }
            }
    
            Process StartProcess(string strPath, string strFile)
            {
                Process p = new Process();
                p.StartInfo.FileName = strFile;
                p.StartInfo.WorkingDirectory = strPath;
                p.StartInfo.UseShellExecute = false;
                p.Start();
    
                Logger.WriteEntry(String.Format("Process: {0} Run!", p.ProcessName));
    
                //p.EnableRaisingEvents = true;
                //p.Exited += delegate
                //{
                //    Console.WriteLine("Process exited... Restart it!");
                //    p = StartProcess(str);
                //};
    
                return p;
            }
    


    2013年11月11日 上午 09:38

解答

所有回覆

  • 你可以設定使用者的帳戶來執行 Windows Service。


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    • 已標示為解答 Tony Hom 2013年11月12日 上午 06:57
    2013年11月11日 上午 10:58
    版主
  • Windows Service指定的執行身份必須有啟動您的程式的權限才能夠成夠, 否則就會失敗

    2013年11月11日 上午 11:20
  • 不好意思,再多請問您們一個問題:

    有可能在 Code 中指派權限給子程式嗎?

    個人有嘗試過使用 Process.StartInfo 的 UserName & Password 來指定執行身分,

    但是該通訊程式依然無法正常運作,

    甚至從 Taskman 的記憶體使用情形也讓我覺得他沒有正常的初始化程式。

    個人嘗試如下:

            Process StartProcess(string strPath, string strFile, string user, string password)
            {
                SecureString passWord = new SecureString();
                foreach (char c in password)
                {
                    passWord.AppendChar(c);
                }
    
                Process p = new Process();
                p.StartInfo.FileName = strFile;
                p.StartInfo.WorkingDirectory = strPath;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.UserName = user;
                p.StartInfo.Password = passWord;
                p.Start();
    
                Logger.WriteEntry(String.Format("Process: {0} Run!", p.ProcessName));
    
                return p;
            }

    2013年11月12日 上午 01:01
  • 您可以參考這篇討論的做法:Elevating process privilege programatically?

    • 已標示為解答 Tony Hom 2013年11月12日 上午 06:57
    2013年11月12日 上午 04:02
  • 您好,

    我嘗試使用討論中的做法來更改我的 Code 如下:

            Process StartProcess(string strPath, string strFile, string domain, string user, string password)
            {
                SecureString passWord = new SecureString();
                foreach (char c in password)
                {
                    passWord.AppendChar(c);
                }
    
                Process p = new Process();
                p.StartInfo.FileName = strFile;
                p.StartInfo.WorkingDirectory = strPath;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.Domain = domain;
                p.StartInfo.UserName = user;
                p.StartInfo.Password = passWord;
                p.StartInfo.Verb = "runas";
                try
                {
                    p.Start();
                    Logger.WriteEntry(String.Format("Process: {0} Run!", p.ProcessName));
                }
                catch (Exception ex)
                {
                    Logger.WriteEntry(ex.ToString());
                }
    
                return p;
            }
    

    但是會 catch 到 Win32 Exception 如下:

    攔截到 System.ComponentModel.Win32Exception
      Message="存取被拒。"
      Source="System"
      ErrorCode=-2147467259
      NativeErrorCode=5
      StackTrace:
           於 System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
           於 System.Diagnostics.Process.Start()
           於 KMUHHost.TelecareMonitor.StartProcess(String strPath, String strFile, String user, String password)

    依照User Account 的 Domain & UserName & Password設定後依然出現此問題,

    請問我是否有哪個地方有錯誤呢?

    2013年11月12日 上午 09:45