2010-10-01 124 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進程。