Запуск cscript.exe из C # .ashx не выполняет код в файле vbscript - PullRequest
3 голосов
/ 01 октября 2010

EDIT

Я добавил некоторую обработку ошибок в мой файл .vbs, и это действительно проблема с разрешениями (теперь я получаю «Ошибка отказа в доступе»). Однако указание моих учетных данных в теге web.config <impersonate>, похоже, не имеет никакого эффекта.

Также при попытке передать мои учетные данные процессу через

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

Я получаю новую ошибку:

cscript.exe - Ошибка приложения

Приложение не удалось инициализировать правильно (0xc0000142). Нажмите на ОК, чтобы прекратить заявку.

Кричи, если знаешь, что это вызвало. ( Или просто наберите ... )

Спасибо за вашу помощь!


Фон

Я пытаюсь выполнить файл .vbs из пользовательского обработчика (.ashx). VBScript настраивает веб-приложение в iis 5.1.

Пока следующий код выполняется без ошибок

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.

Устранение неисправностей

Я решил добавить некоторые операторы echo в файл .vbs, чтобы убедиться, что он работает. В командной строке все операторы выводятся правильно. При проверке строки sOutput я получаю сообщение заголовка, но ни одно из моих последующих сообщений.

Из C # - содержимое sOutput

Microsoft (R) Windows Script Host Версия 5.7 Copyright (C) Microsoft Корпорация. Все права защищены

Из командной строки

Microsoft (R) Windows Script Host Версия 5.7 Copyright (C) Microsoft Корпорация. Все права защищены

Hello

Так что я могу доказать (я думаю), что файл .vbs не проверяется и вызывается cscript. И если я вызываю cscript без ссылки на файл .vbs, я получаю справочную документацию. Так что что-то идет не так.

Есть идеи? Спасибо!

Ответы [ 3 ]

1 голос
/ 01 октября 2010

Вы должны быть администратором, чтобы создать сайт.Вам нужно будет изменить свое веб-приложение, чтобы оно работало от имени администратора, или же вы можете запустить процесс cscript от имени администратора.

1 голос
/ 04 октября 2010

Оказывается, мне нужно было пропустить использование 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);
1 голос
/ 01 октября 2010

Я полагаю, что проблема (возможно, не вся проблема) заключается в том, что пользователь, под которым работает IIS, не имеет прав для запуска сценариев на целевом компьютере.

...