代码之家  ›  专栏  ›  技术社区  ›  Brandon Boone

跑步cscript.exe文件从C#。ashx不执行vbscript文件中的代码

  •  3
  • Brandon Boone  · 技术社区  · 14 年前

    我在.vbs文件中添加了一些错误处理,这确实是一个权限问题(我现在得到一个“权限拒绝错误”)。但是,在web.config文件 <impersonate> 标签似乎没有任何效果。

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

    我得到一个新错误:

    应用程序初始化失败 正确(0xc0000142)。单击“确定”以 终止应用程序。

    如果你知道是什么原因,就大声说出来。( 或者直接打出来。。。

    谢谢你的帮助!


    背景

    我正在尝试从自定义处理程序(.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文件中添加一些echo语句,以便确保它正在运行。在命令行上,所有语句都正确输出。当检查字符串sOutput时,我得到了头消息,但没有后续消息。

    从C#-酸液含量

    Microsoft(R)Windows脚本主机 5.7版版权所有(C)Microsoft 公司。版权所有

    Microsoft(R)Windows脚本主机 5.7版版权所有(C)Microsoft

    你好

    有什么想法吗?谢谢!

    3 回复  |  直到 14 年前
        1
  •  1
  •   Matt    14 年前

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

        2
  •  1
  •   Mike    14 年前

    你需要是一个管理员来创建网站。您需要将web应用更改为以管理员用户身份运行,或者,您也可以以管理员用户身份启动cscript进程。

        3
  •  1
  •   Brandon Boone    13 年前

    System.Diagnostics.Process 并使用kernel32.dll和advapi32.dll方法。

    “这是因为ASP.NET, 模拟是在 source

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

    这是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);