[c#] 프로그래밍 방식으로 IIS Express 시작 및 중지


Answers

너무 늦기는하지만이 질문에 대한 답을 알려 드리겠습니다.

IISVersionManagerLibrary.IISVersionManager mgr = new IISVersionManagerLibrary.IISVersionManagerClass();
IISVersionManagerLibrary.IIISVersion ver = mgr.GetVersionObject("7.5", IISVersionManagerLibrary.IIS_PRODUCT_TYPE.IIS_PRODUCT_EXPRESS);

object obj1 = ver.GetPropertyValue("expressProcessHelper");

IISVersionManagerLibrary.IIISExpressProcessUtility util = obj1 as IISVersionManagerLibrary.IIISExpressProcessUtility;

그게 전부 야. 그런 다음 util 객체에서 StopProcess 메서드를 호출 할 수 있습니다.

그러나 Microsoft로부터 통지를 받아야합니다.

"버전 관리자 API (IIS Express), http://msdn.microsoft.com/en-us/library/gg418429(v=VS.90).aspx

참고 : IIS 버전 관리자 API는 IIS Express 인프라를 지원하며 사용자 코드에서 직접 사용할 수 없습니다. "

Question

C #에서 IIS Express 작업자 프로세스를 시작 / 중지해야하는 작은 응용 프로그램을 빌드하려고합니다. 이 목적을 위해 MSDN에 공식화 된 "IIS Express API"를 사용하고자합니다. http://msdn.microsoft.com/en-us/library/gg418415.aspx

내가 이해하는 한, API는 COM 인터페이스에만 기반합니다. 이 COM 인터페이스를 사용하려면 참조 추가 -> COM -> "IIS Installed Versions Manager Interface"를 통해 VS2010의 COM 라이브러리에 대한 참조를 추가했습니다.

지금까지는 그렇게 좋았지 만 다음은 무엇입니까? IIISExprProcessUtility 인터페이스에는 IIS 프로세스를 시작 / 중지하는 두 가지 "메소드"가 포함되어 있습니다. 이 인터페이스를 구현하는 클래스를 작성해야합니까?

public class test : IISVersionManagerLibrary.IIISExprProcessUtility
{
    public string ConstructCommandLine(string bstrSite, string bstrApplication, string bstrApplicationPool, string bstrConfigPath)
    {
        throw new NotImplementedException();
    }

    public uint GetRunningProcessForSite(string bstrSite, string bstrApplication, string bstrApplicationPool, string bstrConfigPath)
    {
        throw new NotImplementedException();
    }

    public void StopProcess(uint dwPid)
    {
        throw new NotImplementedException();
    }
} 

보시다시피 저는 전문 개발자가 아닙니다. 누군가가 올바른 방향으로 나를 가리킬 수 있습니까? 어떤 도움이라도 대단히 감사합니다.

업데이트 1 : 제안에 따르면 불행히도 작동하지 않는 다음 코드를 시도했습니다 :

좋아, 인스턴스화 될 수 있지만이 개체를 사용하는 방법을 볼 수 없습니다 ...

IISVersionManagerLibrary.IIISExpressProcessUtility test3 = (IISVersionManagerLibrary.IIISExpressProcessUtility) Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("5A081F08-E4FA-45CC-A8EA-5C8A7B51727C")));

Exception: Retrieving the COM class factory for component with CLSID {5A081F08-E4FA-45CC-A8EA-5C8A7B51727C} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).



아니, 인터페이스를 상속받지 않습니다. new 키워드를 사용하여 IISVersionManager의 인스턴스를 만들 수 있습니다. IIISExpressProcessUtility 인스턴스에 대한 참조를 얻는 방법은 완전히 불분명합니다. MSDN 문서는 끔찍합니다. 어쩌면 당신은 새로운 것을 만들 수 있지만 그것을 지원하는 것처럼 보이지는 않습니다.




여기 내 해결책도있다. 숨겨진 창으로 IIS Express를 실행합니다. 관리자 클래스는 여러 IIS Express 인스턴스를 제어합니다.

class IISExpress
{               
    private const string IIS_EXPRESS = @"C:\Program Files\IIS Express\iisexpress.exe";        

    private Process process;

    IISExpress(Dictionary<string, string> args)
    {
        this.Arguments = new ReadOnlyDictionary<string, string>(args);

        string argumentsInString = args.Keys
            .Where(key => !string.IsNullOrEmpty(key))
            .Select(key => $"/{key}:{args[key]}")
            .Aggregate((agregate, element) => $"{agregate} {element}");

        this.process = Process.Start(new ProcessStartInfo()
        {
            FileName = IIS_EXPRESS,
            Arguments = argumentsInString,
            WindowStyle = ProcessWindowStyle.Hidden                
        });
    }

    public IReadOnlyDictionary<string, string> Arguments { get; protected set; }        

    public static IISExpress Start(Dictionary<string, string> args)
    {
        return new IISExpress(args);
    }

    public void Stop()
    {
        try
        {
            this.process.Kill();
            this.process.WaitForExit();
        }
        finally
        {
            this.process.Close();
        }            
    }        
}

몇 가지 사례가 필요합니다. 그들을 제어하는 ​​관리자 클래스를 설계했습니다.

static class IISExpressManager
{
    /// <summary>
    /// All started IIS Express hosts
    /// </summary>
    private static List<IISExpress> hosts = new List<IISExpress>();

    /// <summary>
    /// Start IIS Express hosts according to the config file
    /// </summary>
    public static void StartIfEnabled()
    {
        string enableIISExpress = ConfigurationManager.AppSettings["EnableIISExpress"]; // bool value from config file
        string pathToConfigFile = ConfigurationManager.AppSettings["IISExpressConfigFile"]; // path string to iis configuration file
        string quotedPathToConfigFile = '"' + pathToConfigFile + '"';

        if (bool.TryParse(enableIISExpress, out bool isIISExpressEnabled) 
            && isIISExpressEnabled && File.Exists(pathToConfigFile))
        {                
            hosts.Add(IISExpress.Start(
                new Dictionary<string, string> {
                    {"systray", "false"},
                    {"config", quotedPathToConfigFile},
                    {"site", "Site1" }                        
                }));

            hosts.Add(IISExpress.Start(
                new Dictionary<string, string> {
                    {"systray", "false"},
                    { "config", quotedPathToConfigFile},
                    {"site", "Site2" }
                }));

        }
    }

    /// <summary>
    /// Stop all started hosts
    /// </summary>
    public static void Stop()
    {
        foreach(var h in hosts)
        {
            h.Stop();
        }
    }
}



나는 당신이 어렵게 그렇게하고 있다고 느낍니다. 이 질문에 대한 힌트를 얻으십시오 Build에서 ASP.NET Development Server를 자동으로 중지 / 다시 시작 하고 동일한 프로세스를 채택 할 수 있는지 확인하십시오.

귀하의 질문에 대답, 나는 pinvoke.net 도움이 될 것 같아요. 그들은 솔루션을 구축하는 데 도움이 될 수있는 많은 예제를 가지고 있습니다.




나는 다른 해결책을 채택했다. "taskkill"과 프로세스 이름을 사용하여 프로세스 트리를 간단히 종료 할 수 있습니다. 이것은 로컬 및 TFS 2013에서 완벽하게 작동합니다.

public static void FinalizeIis()
{
    var startInfo = new ProcessStartInfo
    {
        UseShellExecute = false,
        Arguments = string.Format("/F /IM iisexpress.exe"),
        FileName = "taskkill"
    };

    Process.Start(startInfo);
}



Related