从C#Web服务调用或调用C#控制台应用程序?

由于我的问题,我无法通过我的Web服务运行DOS命令。

C#web服务运行批处理文件还是dos命令?

由于我不能让我的web服务直接运行dos命令,我现在正在考虑创建将运行我的dos命令的C#控制台应用程序,然后控制台应用程序将由Web服务调用。

有可能这样做吗?

从另一个.Net应用程序调用.Net控制台应用程序的最简单方法是在程序集中进行链接,并直接调用静态Main方法。 但是如果有任何理由你无法执行命令(权限),那么你将遇到与此方法相同的问题。

如果权限是问题,那么您可以:

  • 更改ASP.Net用于托管您的Web服务的帐户
  • 创建承载WCF或.Net Remoting侦听器的Windows服务。 设计监听器以生成运行所需的进程。 使用您需要的权限运行该服务

此外,正如John Kalberer所提到的,这可能与这些服务无法与桌面交互有关。 如果这是问题, 那么请看这个问题 。

如果可以从Web服务中进行,则需要执行以下两项操作之一:

  • 使用模拟来执行控制台应用程序
  • 在IIS中使用可以执行应用程序的帐户。

假设上述其中一个工作并且您能够执行控制台应用程序,还需要考虑其他一些事项:

  • 您可能需要更改IIS中“主目录”选项卡下的执行权限
  • 您可能需要禁止控制台对话框,因为这可能会引发一些标记

我之前不得不这样做,标准模仿对我来说不起作用。 我不得不以不同的方式处理模仿。 我不知道你是否会遇到与我相同的障碍,但这是我创建的用于通过Windows API以编程方式模拟的类:

编辑

更改为实现IDisposable的实例类 – 感谢@John Saunders

添加了一个重载的构造函数,以便使用using语句更容易实现,并添加了布尔属性Impersonating来检查实例当前是否正在模拟。 还有BeginImpersonationContext和EndImpersonationContext方法供替代使用。

 ///  /// Leverages the Windows API (advapi32.dll) to programmatically impersonate a user. ///  public class ImpersonationContext : IDisposable { #region constants private const int LOGON32_LOGON_INTERACTIVE = 2; private const int LOGON32_PROVIDER_DEFAULT = 0; #endregion #region global variables private WindowsImpersonationContext impersonationContext; private bool impersonating; #endregion #region unmanaged code [DllImport("advapi32.dll")] private static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool RevertToSelf(); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern bool CloseHandle(IntPtr handle); #endregion #region constructors public ImpersonationContext() { impersonating = false; } ///  /// Overloaded constructor and begins impersonating. ///  public ImpersonationContext(string userName, string password, string domain) { this.BeginImpersonationContext(userName, password, domain); } #endregion #region impersonation methods ///  /// Begins the impersonation context for the specified user. ///  /// Don't call this method if you used the overloaded constructor. public void BeginImpersonationContext(string userName, string password, string domain) { //initialize token and duplicate variables IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; if (RevertToSelf()) { if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0) { if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) { using (WindowsIdentity tempWindowsIdentity = new WindowsIdentity(tokenDuplicate)) { //begin the impersonation context and mark impersonating true impersonationContext = tempWindowsIdentity.Impersonate(); impersonating = true; } } } } //close the handle to the account token if (token != IntPtr.Zero) CloseHandle(token); //close the handle to the duplicated account token if (tokenDuplicate != IntPtr.Zero) CloseHandle(tokenDuplicate); } ///  /// Ends the current impersonation context. ///  public void EndImpersonationContext() { //if the context exists undo it and dispose of the object if (impersonationContext != null) { //end the impersonation context and dispose of the object impersonationContext.Undo(); impersonationContext.Dispose(); } //mark the impersonation flag false impersonating = false; } #endregion #region properties ///  /// Gets a value indicating whether the impersonation is currently active. ///  public bool Impersonating { get { return impersonating; } } #endregion #region IDisposable implementation ~ImpersonationContext() { Dispose(false); } public void Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { if (disposing) { if (impersonationContext != null) { impersonationContext.Undo(); impersonationContext.Dispose(); } } } #endregion } 

编辑

最后,这是一个如何实现类的示例:

 using (ImpersonationContext context = new ImpersonationContext("user", "password", "domain")) { if (context.Impersonating) { Process.Start(@"/Support/SendFax/SendFax.exe"); } }