0

我嘗試從Web應用程序調用.exe文件。 但我想要的是由用戶通過網站的windoes認證進行非個人化調用的文件。使用非個人化從.NET Web應用程序啓動進程

Process process = new Process(); 
try 
{ 
    process.StartInfo.UseShellExecute = false; 
    process.StartInfo.FileName = ConfigData.PVDToBudgetDBexePath; 
    process.StartInfo.CreateNoWindow = false; 
    process.Start(); 
    log.Info("Process started by " + WindowsIdentity.GetCurrent().Name + " with ID: " + process.Id); 
    process.WaitForExit(); 
    log.Info("After WaitForExit Process ID: " + process.Id); 
} 
catch (Exception ex) 
{ 
    log.Error("Error executing file with message " + ex.Message); 
} 

這兩個信息日誌文本都被正確記錄。沒有錯誤發生。 但被調用的程序沒有做任何事情。不記錄,不在數據庫中寫入。 用戶擁有該文件的可執行權限。

當我從開發服務器調用相同的代碼時,它工作正常。

我使用.Net 4.5和IIS 7 我發現有關這個主題的帖子只適用於.Net和IIS的非常舊的版本,並不能幫助我。

我在做什麼錯了? 或者我怎樣才能找出發生了什麼問題?

千恩萬謝,

編輯: 爲了更好地解釋清楚我的打算: 我有這個(自制)exe文件,從Excel工作表數據導入數據庫。這需要一些時間。在執行此操作時,它將其進程whith log4net也記錄到數據庫中。 我想用戶可以觸發導入的用戶界面(Web應用程序)。 這個UI上還有一個ajax進度條,它顯示從數據庫中的日誌表導入takten的進度。

我希望此導入過程的最大一個實例在同一時間運行。所以我有一個函數來檢查進程是否仍在運行。 如果是這樣,它不允許啓動另一個進程。如果沒有,你可以重新開始。

private bool IsRunning(string name) 
    { 
     Process[] processlist = Process.GetProcesses(); 

     if (Process.GetProcessesByName(name).Length > 0 ) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 

回答

0

如果你的意思是開發服務器是由Visual Studio推出的web服務器,從1995年起該服務器是由Visual Studio推出的這款給你一個假的測試用例,並使用您的Windows帳戶來運行,而標準已配置的IIS不會在「用戶」帳戶下運行,而是一個非常有限的系統帳戶(幸運的是!!)。即使用戶使用您的網站中的域帳戶登錄,IIS進程也不會在此帳戶下運行(無論如何,這是毫無意義的)。這就是爲什麼這個代碼不能在IIS中運行並且會在你的開發服務器上運行的原因。即使你啓動exe,它也會使用IIS的系統帳戶運行,因爲你沒有提供任何帳戶,這是一個有限的帳戶,它將再次運行與你預期不同的exe。

如果你真的想要這樣做,你將不得不使用模擬,但是你將不得不啓動這個過程來「模擬」登錄到該網站的用戶,假設用戶帳戶用於登錄甚至使用在那個點上感覺。例如。如果它是一個域帳戶,這可能會起作用,但是如果您使用其他類型的身份驗證(如表單身份驗證),則這在操作系統級別上沒有任何意義,因此您不能在IIS中使用這些憑據進行模擬。

根據我的經驗,我已經做了幾次這樣的事情,在IIS中模仿總是一件壞事,並且總是會產生問題,這同樣也是通過啓動命令行進程的方式。糟糕的是總會有更好的/當你考慮這個問題時可以選擇其他解另外,等待代碼中的進程結束並不是一個好習慣。如果過程阻塞會怎麼樣?它會阻止網站。

幸運的是,當您考慮時總會有更好的/替代的解決方案。例如,一個更好的/可能的解決方案是使用消息隊列,例如,您只需推送消息來執行任務,另一端使用處理消息的應用程序,然後可以使用此命令行工具。該應用程序可以在您想要的任何用戶帳戶下運行,而不必讓IIS在不同的帳戶下運行。稍後,您必須回來查找操作結果,但可以在您的網站後臺使用回調來完成。儘管這個解決方案比你想要做的要大一些,但它幾乎在每個領域都會有更好的結果(網站的響應能力,可維護性,可伸縮性等等),唯一不好的是代碼行您將需要,但這很少是一個有效的因素要考慮

+0

謝謝您的回答開始的exe文件。我將閱讀關於消息隊列並試圖理解這是什麼。我在我的問題中添加了一些進一步的解釋,以明確我想要做什麼。如果我知道通過IIS的帳戶試圖啓動exe文件,我可以給它的權利和測試,如果它與帽子帳戶的作品。那會讓我更進一步。或者有什麼方法可以將用戶的憑證提供給流程啓動器? – Ephedra

+0

您是否可以修改執行excell處理的應用程序? –

+0

是的。我自己寫了 – Ephedra

0

如果您自己編寫excel處理的應用程序,則可以將數據庫中的表用作某種類型的隊列,而不是使用消息總線。然後,您的Web應用程序只需添加包含該表中進程的所有necesarry信息的行,狀態和進度就是其中之一。擴展您的處理應用程序以連續監控此表,一旦它檢測到新記錄,它就可以開始執行必要的任務並根據進度和狀態以及最終結果更新數據庫。這樣可以避免消息傳遞子系統,同樣的效果,並且可以避免你必須啓動一個模仿的過程,這是一件非常糟糕的事情。

您可以將excel進程修改爲windows服務,以便它可以連續運行並從系統啓動,但是,如果您不想,也可以將任何命令行應用程序作爲Windows服務運行) 。

這種技術會比模仿更容易,讓您的網站在它運行的受保護的環境

+0

謝謝你的回答。我猜Windows服務也是可能的。我現在通過TimeScheduler解決了它。 – Ephedra

0

我現在解決了這個問題通過啓動通過TimeScheduler exe文件。

路徑=文件路徑的exe文件

參數=參數與

using Microsoft.Win32.TaskScheduler; 


      using (TaskService taskService = new TaskService()) 
      { 
       var taskDefinition = taskService.NewTask(); 
       taskDefinition.RegistrationInfo.Author = WindowsIdentity.GetCurrent().Name; 
       taskDefinition.RegistrationInfo.Description = "Runs exe file"; 


       var action = new ExecAction(path, arguments); 
       taskDefinition.Actions.Add(action); 

       taskService.RootFolder.RegisterTaskDefinition("NameOfTask", taskDefinition); 

       //get task: 
       var task = taskService.RootFolder.GetTasks().Where(a => a.Name == "NameOfTask").FirstOrDefault(); 

       try 
       { 
        task.Run(); 
       } 
       catch (Exception ex) 
       { 
        log.Error("Error starting task in TaskScheduler with message: " + ex.Message); 
       } 


      } 
+0

P.S.我的IsRunning方法(參見問題)仍然適用於這種方法。 – Ephedra

相關問題