2010-10-01 62 views
2

编辑从C#.ashx的运行的Cscript.exe不VBScript文件执行代码

我在一些错误处理添加到我的.vbs文件,并且它确实是一个权限问题(我现在碰到一个“Permission拒绝错误“)。但是,在web.config <impersonate>标记中提供我的凭据似乎没有任何效果。

还试图通过时,通过

p.StartInfo.Password = Misc.CreateSecurityString("password"); 
p.StartInfo.UserName = "admin"; 

我得到一个新的错误提供我的凭据的过程:

cscript.exe - Application error

The application failed to initialize properly (0xc0000142). Click on OK to terminate the application.

喊出来,如果你知道是什么导致了这一点。 (或只是键入它...

感谢您的帮助到目前为止!


背景

我试图从一个自定义的处理器(ashx的)执行.vbs文件。 VBScript正在iis 5.1中设置一个Web应用程序。

到目前为止,下面的代码执行没有错误

string sToRun = "C:\CreateIISApplication.vbs" 
System.Diagnostics.Process p = new System.Diagnostics.Process(); 
p.StartInfo.UseShellExecute = false; 
p.StartInfo.RedirectStandardOutput = true; 
p.StartInfo.FileName = "cscript"; 
p.StartInfo.Arguments = sToRun; 
p.Start(); 
// Do not wait for the child process to exit before 
// reading to the end of its redirected stream. 
// p.WaitForExit(); 
// Read the output stream first and then wait. 
string sOutput = p.StandardOutput.ReadToEnd(); 
p.WaitForExit(); 

问题

我的问题是,VBScript中似乎根本就不会运行。当我检查IIS时,我的应用程序未被创建。

当我直接从命令提示符运行脚本文件时,一切正常,我的应用程序显示在IIS中。

故障排除

我决定添加一些回声报表到.vbs文件,所以我可以确保它正在运行。在命令行中,所有语句都可以正确输出。当检查字符串sOutput时,我得到标题消息,但没有我的后续消息。

从C# - sOutput

Microsoft (R) Windows Script Host Version 5.7 Copyright (C) Microsoft Corporation. All rights reserved

的内容通过命令行

Microsoft (R) Windows Script Host Version 5.7 Copyright (C) Microsoft Corporation. All rights reserved

Hello

所以我可以证明(我认为).vbs文件不被评估,并且正在调用cscript。如果我在不引用.vbs文件的情况下调用cscript,那么我将获得帮助文档。所以有些事情出错了。

任何想法?谢谢!

+0

@Mike&@马特 - 感谢您的帮助,请参阅我的编辑,您可以提供的任何进一步的帮助将会很棒! – 2010-10-01 19:38:11

回答

1

原来我需要跳过使用System.Diagnostics.Process并使用kernel32.dll和advapi32.dll方法。

还需要让我的匿名访问帐户成为“替换进程级令牌”控制面板 - >管理工具 - >本地安全设置的成员。 (您将需要重新启动,这才会生效

下面是从MSDN改编代码(http://support.microsoft.com/kb/889251

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Runtime.InteropServices; 
using Microsoft.Win32; 
using System.IO; 
using System.Security.Principal; 

namespace UtilityLib 
{ 
    public class Win32Process 
    { 
     [StructLayout(LayoutKind.Sequential)] 
     public struct STARTUPINFO 
     { 
      public int cb; 
      public String lpReserved; 
      public String lpDesktop; 
      public String lpTitle; 
      public uint dwX; 
      public uint dwY; 
      public uint dwXSize; 
      public uint dwYSize; 
      public uint dwXCountChars; 
      public uint dwYCountChars; 
      public uint dwFillAttribute; 
      public uint dwFlags; 
      public short wShowWindow; 
      public short cbReserved2; 
      public IntPtr lpReserved2; 
      public IntPtr hStdInput; 
      public IntPtr hStdOutput; 
      public IntPtr hStdError; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct PROCESS_INFORMATION 
     { 
      public IntPtr hProcess; 
      public IntPtr hThread; 
      public uint dwProcessId; 
      public uint dwThreadId; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct SECURITY_ATTRIBUTES 
     { 
      public int Length; 
      public IntPtr lpSecurityDescriptor; 
      public bool bInheritHandle; 
     } 

     [DllImport("kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 
     public extern static bool CloseHandle(IntPtr handle); 

     [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] 
     public extern static bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, 
      ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment, 
      String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); 

     [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")] 
     public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, 
      ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType, 
      int ImpersonationLevel, ref IntPtr DuplicateTokenHandle); 


     public static void CreateProcess(string cmdline) 
     { 
      IntPtr Token = new IntPtr(0); 
      IntPtr DupedToken = new IntPtr(0); 
      bool  ret; 
      //Label2.Text+=WindowsIdentity.GetCurrent().Name.ToString(); 


      SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); 
      sa.bInheritHandle  = false; 
      sa.Length    = Marshal.SizeOf(sa); 
      sa.lpSecurityDescriptor = (IntPtr)0; 

      Token = WindowsIdentity.GetCurrent().Token; 

      const uint GENERIC_ALL = 0x10000000; 

      const int SecurityImpersonation = 2; 
      const int TokenType = 1; 

      ret = DuplicateTokenEx(Token, GENERIC_ALL, ref sa, SecurityImpersonation, TokenType, ref DupedToken); 

      if (ret == false) 
      { 
       throw new Exception("DuplicateTokenEx failed with " + Marshal.GetLastWin32Error()); 
      } 


      STARTUPINFO si   = new STARTUPINFO(); 
      si.cb     = Marshal.SizeOf(si); 
      si.lpDesktop   = ""; 

      string commandLinePath = cmdline; 

      PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); 
      ret = CreateProcessAsUser(DupedToken,null,commandLinePath, ref sa, ref sa, false, 0, (IntPtr)0, "c:\\", ref si, out pi); 

      if (ret == false) 
      { 
       throw new Exception("CreateProcessAsUser failed with " + Marshal.GetLastWin32Error() + ": if 1314, make sure user is a member 'Replace a process level token' Control Panel -> Administrative Tools -> Local Security Settings."); 
      } 
      else 
      { 
       CloseHandle(pi.hProcess); 
       CloseHandle(pi.hThread); 
      } 

      ret = CloseHandle(DupedToken); 
      if (ret == false) 
      { 
       throw new Exception(Marshal.GetLastWin32Error().ToString()); 
      } 

     } 

    } 
} 

使用它很简单:。

string sToRun = @"cscript C:\CreateIISApplication.vbs"; //OR C:\myfile.bat arguments, or whatever else you want to run. 

Win32Process.CreateProcess(sToRun); 
1

我想象一个问题(可能不是全部问题)是IIS运行的用户没有权限在目标机器上运行脚本。

1

您需要成为管理员才能创建网站。您需要将您的Web应用程序更改为以管理员用户身份运行,或者,您可以以管理员用户身份启动cscript进程。