Dynamically create website on IIS using Asp.net web C# - c#

We referred stackOverflow and a few other sites to create a website on IIS using console application. It worked after we run the console with administration permission. Code does create an Application pool and host site on a given port. Same code when we tried on asp.net web application it completed its execution but we did not found metadata on IIS.
Here is a code that works on console..
try
{
ServerManager server = new ServerManager();
ApplicationPool myApplicationPool = null;
//we will first check to make sure that this pool does not already exist
//since the ApplicationPools property is a collection, we can use the Linq FirstOrDefault method
//to check for its existence by name
if (server.ApplicationPools != null && server.ApplicationPools.Count > 0)
{
if (server.ApplicationPools.FirstOrDefault(p => p.Name == "TestPool") == null)
{
//if the pool is not already there we will create it
myApplicationPool = server.ApplicationPools.Add("TestPool");
}
else
{
//if we find the pool already there, we will get a referecne to it for update
myApplicationPool = server.ApplicationPools.FirstOrDefault(p => p.Name == "TestPool");
}
}
else
{
//if the pool is not already there we will create it
myApplicationPool = server.ApplicationPools.Add("TestPool");
}
if (myApplicationPool != null)
{
//for this sample, we will set the pool to run under the NetworkService identity
myApplicationPool.ProcessModel.IdentityType =
ProcessModelIdentityType.NetworkService;
//for this sample, we will set the pool to run under the identity of a specific user
//myApplicationPool.ProcessModel.IdentityType =
ProcessModelIdentityType.SpecificUser;
//myApplicationPool.ProcessModel.UserName = UserName;
//myApplicationPool.ProcessModel.Password = Password;
//we set the runtime version
myApplicationPool.ManagedRuntimeVersion = "v4.0";
//we save our new ApplicationPool!
server.CommitChanges();
}
//Create website
if (server.Sites != null && server.Sites.Count > 0)
{
//we will first check to make sure that the site isn't already there
if (server.Sites.FirstOrDefault(s => s.Name == "MySite") == null)
{
//we will just pick an arbitrary location for the site
string path = #"C:\inetpub\Custom";
//we must specify the Binding information
string ip = "*";
string port = "98";
string hostName = "*";
string bindingInfo = string.Format(#"{0}:{1}:{2}", ip, port, hostName);
//add the new Site to the Sites collection
Site site = server.Sites.Add("MySite", "http", bindingInfo, path);
//set the ApplicationPool for the new Site
site.ApplicationDefaults.ApplicationPoolName = myApplicationPool.Name;
//save the new Site!
server.CommitChanges();
Console.WriteLine("Web site created successfully...");
Console.ReadLine();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine()
}
Here site gets listed in IIS as well.
Now when tried the same code on the web application, it does not create anything on IIS. when we inspect the server manager object we found that the Application pool list was coming from the project's
applicationhost.config
file which is located on .vs hidden folder.
We installed the latest IIS on the local machine for a test, is there any changes needed to get it to work on the web as well. (: we are new to IIS stuff)

You could try below code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Web.Administration;
namespace IISTest
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Do you want to create an Application Pool:y/n");
string response = Console.ReadLine();
if (response.ToString() == "y")
{
Console.Write("Please enter Application Pool Name:");
string poolname = Console.ReadLine();
bool isEnable32bit = false;
ManagedPipelineMode mode = ManagedPipelineMode.Classic;
Console.Write("Need to enable 32 bit on Windows 64 bit?y/n [Applicable for 64 bit OS]: y/n?");
string enable32bit = Console.ReadLine();
if (enable32bit.ToLower() == "y")
{
isEnable32bit = true;
}
Console.Write("Please select Pipeline Mode: 1 for Classic, 2 for Integrated:");
string pipelinemode = Console.ReadLine();
if (pipelinemode.ToLower() == "2")
{
mode = ManagedPipelineMode.Integrated;
}
Console.Write("Please select Runtime Version for Application Pool: 1 for v2.0, 2 for v4.0:");
string runtimeVersion = Console.ReadLine() == "1" ? "v2.0" : "v4.0";
CreateAppPool(poolname, isEnable32bit, mode, runtimeVersion);
Console.WriteLine("Application Pool created successfully...");
}
Console.WriteLine("Do you want to create a website:y/n");
response = Console.ReadLine();
if (response.ToString() == "y")
{
Console.Write("Please enter website name:");
string websiteName = Console.ReadLine();
Console.Write("Please enter host name:");
string hostname = Console.ReadLine();
Console.Write("Please enter physical path to point for website:");
string phypath = Console.ReadLine();
Console.WriteLine("Application pool Name:");
foreach (var pool in new ServerManager().ApplicationPools)
{
Console.WriteLine(pool.Name);
}
Console.WriteLine("");
Console.Write("Please enter Application pool Name for web site:");
string poolName = Console.ReadLine();
CreateIISWebsite(websiteName, hostname, phypath, poolName);
Console.WriteLine("Web site created successfully...");
Console.ReadLine();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
private static void CreateIISWebsite(string websiteName, string hostname, string phyPath, string appPool)
{
ServerManager iisManager = new ServerManager();
iisManager.Sites.Add(websiteName, "http", "*:80:" + hostname, phyPath);
iisManager.Sites[websiteName].ApplicationDefaults.ApplicationPoolName = appPool;
foreach (var item in iisManager.Sites[websiteName].Applications)
{
item.ApplicationPoolName = appPool;
}
iisManager.CommitChanges();
}
private static void CreateAppPool(string poolname,bool enable32bitOn64, ManagedPipelineMode mode,string runtimeVersion="v4.0")
{
using (ServerManager serverManager = new ServerManager())
{
ApplicationPool newPool = serverManager.ApplicationPools.Add(poolname);
newPool.ManagedRuntimeVersion = runtimeVersion;
newPool.Enable32BitAppOnWin64 = true;
newPool.ManagedPipelineMode = mode;
serverManager.CommitChanges();
}
}
}
}
note: do not forget to add a reference to Microsoft.Web.Administration.

Related

How to get the path of a system file

Is there a way to get the path of the system files like "wininit.exe" from processId? Below code doesn't work. Process.GetProcesses() also doesn't return anything logical. Please help me.
P.S. I'm trying to code my own task manager designed based on my needs.
private static string GetMainModuleFilepath(int processId)
{
string wmiQueryString = "SELECT ProcessId, ExecutablePath FROM Win32_Process WHERE ProcessId = " + processId;
using (var searcher = new ManagementObjectSearcher(wmiQueryString))
{
using (var results = searcher.Get())
{
ManagementObject mo = results.Cast<ManagementObject>().FirstOrDefault();
if (mo != null)
{
return (string)mo["ExecutablePath"];
}
}
}
return null;
}
You can use the Process.GetProcessById method and pass in the ProcessId.
Then you can use the MainModule.FileName property on the ProcessModule.
My full code can be seen below: (I have done this in a Console App for quicker writing)
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Enter Process ID:");
var processIdString = Console.ReadLine();
var parsed = int.TryParse(processIdString, out var procId);
if (parsed)
{
var path = GetMainModuleFilepath(procId);
Console.WriteLine($"Found Path: {path}");
}
else
{
Console.WriteLine("Process Id must be a number!");
}
}
}
private static string GetMainModuleFilepath(int processId)
{
var process = Process.GetProcessById(processId);
if (process == null)
{
return string.Empty;
}
return process.MainModule?.FileName;
}
Which results in the following:
Note:
If you are running this code in 32 bit application, you'll not be able to access 64-bit application paths, so you'd have to compile and run you app as 64-bit application (Project Properties → Build → Platform Target → x64).

ServerManager iis check default site wasnt change c#

I need to overwritte Default Site if isnt use, overwrite it if the user decides so or create a new one.
I am trying check all sites, and take this with port 80 and name "Default Web Site". Next if it exist I want to take physical path and check does it equal the default path and contains all files for default path. In this way:
private static void CheckSite(SiteCollection applicationSites)
{
int i = 0;
foreach (var item in applicationSites)
{
foreach (var binding in item.Bindings)
{
int port;
if (binding.EndPoint != null)
port = binding.EndPoint.Port;
else
continue;
if (port == 80 && item.Name == "Default Web Site")
{
var path = item.Applications[i].VirtualDirectories[0].PhysicalPath;
string[] dire = Directory.GetFiles(path);
}
}
i++;
}
}
Is there better way to do this? I am using Microsoft.Web.Administration.
You can get the Default Web Site as below code:
using (ServerManager serverManager = new ServerManager())
{
var sites = serverManager.Sites;
foreach (Site site in sites)
{
var sitename = site.Name;
if (sitename == "Default Web Site")
{
}
}
}

Bloomberg web service call for single field and single instrument taking more than 1 min

I am making a Bloomberg web service GetData call for the "DEBT_TO_EQUITY_FUNDAMENTALS_TKR" field. I am setting secmaster = true and asking for a single instrument with a CUSIP identifier (with yellowkey = MarketSector.Corp).
This strikes me as a fairly lightweight call having seen people asking for thousands of instruments and dozens of fields at once.
I have played around with setting lots of different settings but I just can't get this request to return in a few seconds. It gives me the correct return value but it takes longer than 60 seconds.
Any idea if it is possible to get such a request to execute and return in a few seconds?
Thanks
EDIT - Here is the code I am running:
public string GetFundamentalTicker(string identifier, InstrumentType identifierType = InstrumentType.CUSIP)
{
PerSecurityWS ps = new PerSecurityWS();
try
{
log.DebugFormat("Cert path is: {0}", CertPath);
X509Certificate2 clientCert = new X509Certificate2(CertPath, "<password_redacted>");
ps.ClientCertificates.Add(clientCert);
}
catch (Exception e)
{
log.ErrorFormat("Error in cert setup - {0} - {1}", e.Message, e.InnerException == null ? "" : e.InnerException.Message);
return null;
}
//Set request header
GetDataHeaders getDataHeaders = new GetDataHeaders();
getDataHeaders.secmaster = true;
getDataHeaders.secmasterSpecified = true;
//getDataHeaders.fundamentals = true;
//getDataHeaders.fundamentalsSpecified = true;
//getDataHeaders.programflag = ProgramFlag.oneshot;//unnecessary - defaults to this anyway
//getDataHeaders.programflagSpecified = true;
//getDataHeaders.pricing = true;
getDataHeaders.secid = identifierType;
getDataHeaders.secidSpecified = true;
SubmitGetDataRequest sbmtGtDtreq = new SubmitGetDataRequest();
sbmtGtDtreq.headers = getDataHeaders;
sbmtGtDtreq.fields = new string[] {
"DEBT_TO_EQUITY_FUNDAMENTALS_TKR"
};
int currentFundYear = DateTime.Now.Year;
//var fundYears = new List<int>();
List<Instrument> fundYearInstruments = new List<Instrument>();
Instrument fundYearInstrument = null;
fundYearInstrument = new Instrument();
fundYearInstrument.id = identifier;
fundYearInstrument.typeSpecified = true;
fundYearInstrument.type = identifierType;
fundYearInstrument.yellowkey = MarketSector.Corp;
fundYearInstrument.yellowkeySpecified = true;
//fundYearInstrument.overrides = new Override[] {};//{ new Override() { field = "EQY_FUND_YEAR", value = currentFundYear.ToString() } };
fundYearInstruments.Add(fundYearInstrument);
//fundYears.Add(-1);
Instrument[] instr = fundYearInstruments.ToArray();
Instruments instrs = new Instruments();
instrs.instrument = instr;
sbmtGtDtreq.instruments = instrs;
try
{
SubmitGetDataResponse sbmtGtDtResp = ps.submitGetDataRequest(sbmtGtDtreq);
RetrieveGetDataRequest rtrvGtDrReq = new RetrieveGetDataRequest();
rtrvGtDrReq.responseId = sbmtGtDtResp.responseId;
RetrieveGetDataResponse rtrvGtDrResp;
do
{
System.Threading.Thread.Sleep(POLL_INTERVAL);
rtrvGtDrResp = ps.retrieveGetDataResponse(rtrvGtDrReq);
}
while (rtrvGtDrResp.statusCode.code == DATA_NOT_AVAILABLE);
if (rtrvGtDrResp.statusCode.code == SUCCESS)
{
for (int i = 0; i < rtrvGtDrResp.instrumentDatas.Length; i++)
{
for (int j = 0; j < rtrvGtDrResp.instrumentDatas[i].data.Length; j++)
{
if (rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.A." || rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.S." || rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.D.")
rtrvGtDrResp.instrumentDatas[i].data[j].value = null;
return rtrvGtDrResp.instrumentDatas[i].data[j].value;
}
}
return null;
}
else if (rtrvGtDrResp.statusCode.code == REQUEST_ERROR)
{
log.ErrorFormat("Error in the submitted request: {0}", rtrvGtDrResp.statusCode.description);
return null;
}
}
catch (Exception e)
{
log.ErrorFormat("Error in GetData - {0} - {1}", e.Message, e.InnerException == null ? "" : e.InnerException.Message);
return null;
}
return null;
}
Poll interval is 5 seconds and the SOAP web service url is:
https://software.bloomberg.com/datalicensewp/dlws.wsdl
I am having the same issue. I found out that there is a difference between making the same call to Bloomberg API from, for example, console app (works very fast) and web service (takes a lot of time to start session). And the difference is that console app runs under the same user as bbcomm process, whereas web service (or actually iis process) runs under System account. You can try to log out all users on the PC where web service is hosted and then try to make the call. In this case, I guess, bbcomm goes under System account as no one else is logged in and works fast. It worked for me and the call was answered instantly.

Modify the code to perform operation on remote servers

I wrote the following code to change the user account and password associated with a Windows Service. How can I modify this code to be able to perform the same operation on a remote system?
static void Main(string[] args)
{
string serviceName = "DummyService";
string username = ".\\Service_Test2";
string password = "Password1";
ServiceController sc = new ServiceController(serviceName);
Console.WriteLine(sc.Status.ToString());
if (sc.Status == ServiceControllerStatus.Running)
{
sc.Stop();
}
Thread.Sleep(2000);
sc.Refresh();
Console.WriteLine(sc.Status.ToString());
string objPath = string.Format("Win32_Service.Name='{0}'", serviceName);
using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
{
object[] wmiParams = new object[11];
wmiParams[6] = username;
wmiParams[7] = password;
service.InvokeMethod("Change", wmiParams);
}
Thread.Sleep(2000);
Console.WriteLine(sc.Status.ToString());
if (sc.Status == ServiceControllerStatus.Stopped)
{
sc.Start();
}
Thread.Sleep(2000);
sc.Refresh();
Console.WriteLine(sc.Status.ToString());
}
Use ServiceController constructor overload that allows target machine-name to be specified
Modify WMI object path to include the target server.
new ManagementPath(
"\\\\ComputerName\\root" +
"\\cimv2:Win32_Service.Name='{0}'");
Make sure your user/password have sufficient rights on target machine, change those if not.

Programmatically create a web site in IIS using C# and set port number

We have been able to create a web site. We did this using the information in this link:
https://msdn.microsoft.com/en-us/library/ms525598.aspx
However, we would like to use a port number other that port 80. How do we do this?
We are using IIS 6
If you're using IIS 7, there is a new managed API called Microsoft.Web.Administration
An example from the above blog post:
ServerManager iisManager = new ServerManager();
iisManager.Sites.Add("NewSite", "http", "*:8080:", "d:\\MySite");
iisManager.CommitChanges();
If you're using IIS 6 and want to do this, it's more complex unfortunately.
You will have to create a web service on every server, a web service that handles the creation of a website because direct user impersonation over the network won't work properly (If I recall this correctly).
You will have to use Interop Services and do something similar to this (This example uses two objects, server and site, which are instances of custom classes that store a server's and site's configuration):
string metabasePath = "IIS://" + server.ComputerName + "/W3SVC";
DirectoryEntry w3svc = new DirectoryEntry(metabasePath, server.Username, server.Password);
string serverBindings = ":80:" + site.HostName;
string homeDirectory = server.WWWRootPath + "\\" + site.FolderName;
object[] newSite = new object[] { site.Name, new object[] { serverBindings }, homeDirectory };
object websiteId = (object)w3svc.Invoke("CreateNewSite", newSite);
// Returns the Website ID from the Metabase
int id = (int)websiteId;
See more here
Heres the solution.
Blog article : How to add new website in IIS 7
On Button click :
try
{
ServerManager serverMgr = new ServerManager();
string strWebsitename = txtwebsitename.Text; // abc
string strApplicationPool = "DefaultAppPool"; // set your deafultpool :4.0 in IIS
string strhostname = txthostname.Text; //abc.com
string stripaddress = txtipaddress.Text;// ip address
string bindinginfo = stripaddress + ":80:" + strhostname;
//check if website name already exists in IIS
Boolean bWebsite = IsWebsiteExists(strWebsitename);
if (!bWebsite)
{
Site mySite = serverMgr.Sites.Add(strWebsitename.ToString(), "http", bindinginfo, "C:\\inetpub\\wwwroot\\yourWebsite");
mySite.ApplicationDefaults.ApplicationPoolName = strApplicationPool;
mySite.TraceFailedRequestsLogging.Enabled = true;
mySite.TraceFailedRequestsLogging.Directory = "C:\\inetpub\\customfolder\\site";
serverMgr.CommitChanges();
lblmsg.Text = "New website " + strWebsitename + " added sucessfully";
}
else
{
lblmsg.Text = "Name should be unique, " + strWebsitename + " is already exists. ";
}
}
catch (Exception ae)
{
Response.Redirect(ae.Message);
}
Looping over sites whether name already exists
public bool IsWebsiteExists(string strWebsitename)
{
Boolean flagset = false;
SiteCollection sitecollection = serverMgr.Sites;
foreach (Site site in sitecollection)
{
if (site.Name == strWebsitename.ToString())
{
flagset = true;
break;
}
else
{
flagset = false;
}
}
return flagset;
}
Try the following Code to Know the unUsed PortNo
DirectoryEntry root = new DirectoryEntry("IIS://localhost/W3SVC");
// Find unused ID PortNo for new web site
bool found_valid_port_no = false;
int random_port_no = 1;
do
{
bool regenerate_port_no = false;
System.Random random_generator = new Random();
random_port_no = random_generator.Next(9000,15000);
foreach (DirectoryEntry e in root.Children)
{
if (e.SchemaClassName == "IIsWebServer")
{
int site_id = Convert.ToInt32(e.Name);
//For each detected ID find the port Number
DirectoryEntry vRoot = new DirectoryEntry("IIS://localhost/W3SVC/" + site_id);
PropertyValueCollection pvcServerBindings = vRoot.Properties["serverbindings"];
String bindings = pvcServerBindings.Value.ToString().Replace(":", "");
int port_no = Convert.ToInt32(bindings);
if (port_no == random_port_no)
{
regenerate_port_no = true;
break;
}
}
}
found_valid_port_no = !regenerate_port_no;
} while (!found_valid_port_no);
int newportId = random_port_no;
I have gone though all answer here and also tested. Here is the most clean smarter version of answer for this question. However this still cant work on IIS 6.0. so IIS 8.0 or above is required.
string domainName = "";
string appPoolName = "";
string webFiles = "C:\\Users\\John\\Desktop\\New Folder";
if (IsWebsiteExists(domainName) == false)
{
ServerManager iisManager = new ServerManager();
iisManager.Sites.Add(domainName, "http", "*:8080:", webFiles);
iisManager.ApplicationDefaults.ApplicationPoolName = appPoolName;
iisManager.CommitChanges();
}
else
{
Console.WriteLine("Name Exists already");
}
public static bool IsWebsiteExists(string strWebsitename)
{
ServerManager serverMgr = new ServerManager();
Boolean flagset = false;
SiteCollection sitecollection = serverMgr.Sites;
flagset = sitecollection.Any(x => x.Name == strWebsitename);
return flagset;
}
This simplified method will create a site with default binding settings, and also create the application pool if needed:
public void addIISApplication(string siteName, string physicalPath, int port, string appPoolName)
{
using (var serverMgr = new ServerManager())
{
var sitecollection = serverMgr.Sites;
if (!sitecollection.Any(x => x.Name.ToLower() == siteName.ToLower()))
{
var appPools = serverMgr.ApplicationPools;
if (!appPools.Any(x => x.Name.ToLower() == appPoolName.ToLower()))
{
serverMgr.ApplicationPools.Add(appPoolName);
}
var mySite = serverMgr.Sites.Add(siteName, physicalPath, port);
mySite.ApplicationDefaults.ApplicationPoolName = appPoolName;
serverMgr.CommitChanges();
}
}
}
In properties of site select "Web Site" tab and specify TCP Port.
In studio to debug purpose specify http://localhost:<port>/<site> at tab Web for "Use Local IIS Web Server"

Categories

Resources