I am developing a multi store web application in ASP.NET where multiple stores with different domain can be created. I have a wizard to create a store to fill the information. what i want when i clik on finish button of wizard, i want to add the particular store site on IIS. how can i do that pragmatically using C#.
private void ConfigureSiteInIis()
{
string strWebsitename = txtStoreName.Text; // abc
const string strApplicationPool = "DefaultAppPool"; // set your deafultpool :4.0 in IIS
string strhostname = txtDomainName.Text; //abc.com
const string stripaddress = "localhost:40411"; // ip address
string bindinginfo = stripaddress + ":80:" + strhostname;
var serverMgr=new ServerManager();
//Site mySite = serverMgr.Sites.Add(txtStoreName.Text, "http", bindinginfo, "C:\\inetpub\\wwwroot\\yourWebsite");
Site mySite = serverMgr.Sites.Add(txtStoreName.Text, "http", "*:80:" + strhostname , Server.InetPath+txtDomainName.Text);
mySite.ApplicationDefaults.ApplicationPoolName = strApplicationPool;
mySite.TraceFailedRequestsLogging.Enabled = true;
mySite.TraceFailedRequestsLogging.Directory = "C:\\inetpub\\customfolder\\site";
serverMgr.CommitChanges();
lblMessage.Text = "New website " + strWebsitename + " added sucessfully";
lblMessage.ForeColor = System.Drawing.Color.Green;
}
I have got this code from stackoverflow but it is throwing exception "The specified HTTPS binding is invalid".
I've wrote this one time ago, works perfectly(IIS7 and later):
public static Application CreateApplicaiton(string siteName, string path, string physicalPath, string appPoolName)
{
ServerManager iisManager = ServerManager.OpenRemote(Environment.MachineName.ToLower());
// should start with "/" also not to end with this symbol
string correctApplicationPath = string.Format("{0}{1}", Path.AltDirectorySeparatorChar, path.Trim(Path.AltDirectorySeparatorChar));
int indexOfApplication = correctApplicationPath.LastIndexOf(Path.AltDirectorySeparatorChar);
if (indexOfApplication > 0)
{
// create sequence of virtual directories if the path is not a root level (i.e. test/beta1/Customer1/myApplication)
string virtualDirectoryPath = correctApplicationPath.Substring(0, indexOfApplication);
iisManager.CreateVirtualDirectory(siteName, virtualDirectoryPath, string.Empty);
}
Application application = iisManager.Sites[siteName].Applications.Add(correctApplicationPath, physicalPath);
application.ApplicationPoolName = appPoolName;
return application;
}
to host an application at localhost/test/beta1/Customer1/myApplication, use following parameters:
siteName - name of your site in IIS |Default Web Site
path - virtual directory |test/beta1/Customer1/myApplication
public static void CreateVirtualDirectory(this ServerManager iisManager, string siteName, string path, string physicalPath)
{
Site site = iisManager.Sites[siteName];
//remove '/' at the beginning and at the end
List<string> pathElements = path.Trim(Path.AltDirectorySeparatorChar).Split(Path.AltDirectorySeparatorChar).ToList();
string currentPath = string.Empty;
List<string> directoryPath = pathElements;
//go through applications hierarchy and find the deepest one
Application application = site.Applications.First(a => a.Path == Path.AltDirectorySeparatorChar.ToString());
for (int i = 0; i < pathElements.Count; i++)
{
string pathElement = pathElements[i];
currentPath = string.Join(Path.AltDirectorySeparatorChar.ToString(), currentPath, pathElement);
if (site.Applications[currentPath] != null)
{
application = site.Applications[currentPath];
if (i != pathElements.Count - 1)
{
directoryPath = pathElements.GetRange(i + 1, pathElements.Count - i - 1);
}
}
}
currentPath = string.Empty;
foreach (string pathElement in directoryPath)
{
currentPath = string.Join(Path.AltDirectorySeparatorChar.ToString(), currentPath, pathElement);
//add virtual directories
if (application.VirtualDirectories[currentPath] == null)
{
//assign physical path of application root folder by default
string currentPhysicalPath = Path.Combine(application.VirtualDirectories[0].PhysicalPath, pathElement);
//if this is last element of path, use physicalPath specified on method call
if (pathElement == pathElements.Last() && !string.IsNullOrWhiteSpace(physicalPath))
{
currentPhysicalPath = physicalPath;
}
currentPhysicalPath = Environment.ExpandEnvironmentVariables(currentPhysicalPath);
if (!Directory.Exists(currentPhysicalPath))
{
Directory.CreateDirectory(currentPhysicalPath);
}
application.VirtualDirectories.Add(currentPath, currentPhysicalPath);
}
}
}
Related
I have the following code which works fine for Move, but doesn't work for copy
// relativeSourceFolderUrl = "/SubSeries/DEV010/files/dev010-007-2018/parent/copyThisFolder"
// relativeDestinationFolderUrl= "/SubSeries/DEV010/files/dev010-007-2018/parent/child"
// fileName = "copyThisFoler"
// moveItem = false
public Folder MoveOrCopyFolder(String relativeSourceFolderUrl, String relativeDestinationFolderUrl, String fileName, bool moveItem)
{
Folder folder = ClientContext.Web.GetFolderByServerRelativeUrl(relativeDestinationFolderUrl);
// Check if file or folder exists and alter name
fileName = CheckFileOrFolderExistsInFolder(fileName, folder, false);
// In this case the function returns a fileName of "copyThisFolder"
var file = ClientContext.Web.GetFileByServerRelativeUrl(relativeSourceFolderUrl);
ClientContext.Load(file.ListItemAllFields);
ClientContext.ExecuteQuery();
if (moveItem)
file.MoveTo(relativeDestinationFolderUrl + "/" + fileName, MoveOperations.None);
else
file.CopyTo(relativeDestinationFolderUrl + "/" + fileName, false);
ClientContext.ExecuteQuery();
return null;
}
It breaks on this line
file.CopyTo(relativeDestinationFolderUrl + "/" + fileName, false);
The error is
Additional information: The URL '/SubSeries/DEV010/files/dev010-007-2018/parent/copythisfolder' is invalid. It may refer to a nonexistent file or folder, or refer to a valid file or folder that is not in the current Web.
The Move works, but its odd that similar code doesn't work for copy.
In the end I used this post:
https://sharepoint.stackexchange.com/questions/97471/copy-all-items-in-a-folder-to-another-location/250233?noredirect=1#comment266907_250233
Which lead me to this solution:
public void CopyFiles(string listTitle, string srcRelativeSource, string destRelativeSource)
{
var srcList = ClientContext.Web.Lists.GetByTitle(listTitle);
var qry = CamlQuery.CreateAllItemsQuery();
qry.FolderServerRelativeUrl = string.Format("/{0}", srcRelativeSource);
var srcItems = srcList.GetItems(qry);
ClientContext.Load(srcItems, icol => icol.Include(i => i.FileSystemObjectType, i => i["FileRef"], i => i.File));
ClientContext.ExecuteQuery();
createThisFolder(destRelativeSource);
foreach (var item in srcItems)
{
switch (item.FileSystemObjectType)
{
case FileSystemObjectType.Folder:
var destFolderUrl = ((string)item["FileRef"]).ToLower().Replace(srcRelativeSource, destRelativeSource);
createThisFolder(destFolderUrl);
break;
case FileSystemObjectType.File:
var destFileUrl = item.File.ServerRelativeUrl.ToLower().Replace(srcRelativeSource, destRelativeSource);
item.File.CopyTo(destFileUrl, true);
ClientContext.ExecuteQuery();
break;
}
}
}
private void createThisFolder(string destFolderUrl)
{
//change destFolderUrl into absolute url
Uri u = new Uri(ClientContext.Web.Context.Url);
//remove the string after the last slash
int idx = destFolderUrl.LastIndexOf('/');
string path = destFolderUrl.Substring(0, idx);
string lastFolder = destFolderUrl.Split('/').Last();
string filtered = (path.StartsWith("/")) ? path.Substring(1) : path;
string url = u.GetLeftPart(UriPartial.Authority) + "/" + filtered;
CreateFolder(url, lastFolder);
}
I'm trying to remove a Silverlight Out Of Browser app programatically passing the arguments to sllauncher in following this post: http://timheuer.com/blog/archive/2010/03/25/using-sllauncher-for-silent-install-silverlight-application.aspx However it won't uninstall the app when given the origin.
It turns out that when you have an automatically updating Out-Of-Browser application, Silverlight stamps each application Uri with a time stamp that can be found in the application's folder in the C:\Users\Trevor\AppData\Local\Microsoft\Silverlight\OutOfBrowser(AppFolderName) metadata file. So to facilitate the removal of our app in preparation for our new one, I implemented the following:
UninstallExisting(GetInstalledAppUri()); // This is how it's called
//This is the two method's implementation
// TODO: Change to your app name.
const string appName = "YourAppNameHere";
static string silverlightOutOfBrowserFolder =
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
+ #"\Microsoft\Silverlight\OutOfBrowser";
private static string GetInstalledAppUri()
{
string xapFolderPath = Path.Combine(silverlightOutOfBrowserFolder, GetXapFolder());
string[] lines = File.ReadAllLines(Path.Combine(xapFolderPath, "metadata"), Encoding.Unicode);
string finalAppUriLine = lines.First(i => i.Contains("FinalAppUri="));
return "\"" + finalAppUriLine.Replace("FinalAppUri=", "") + "\"";
}
private static string GetXapFolder()
{
string AppXapFolder = "";
foreach (var dir in Directory.GetDirectories(silverlightOutOfBrowserFolder))
{
if (dir.Contains(appName))
{
AppXapFolder = dir;
}
}
return AppXapFolder ;
}
private static string silverlightExe
{
get
{
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
#"Microsoft Silverlight\sllauncher.exe");
}
}
private static void UninstallExisting(string xapUriToRemove)
{
string installArgs = "/uninstall" + " /origin:" + xapUriToRemove;
ProcessStartInfo pstart = new ProcessStartInfo(silverlightExe, installArgs);
Process p = new Process();
pstart.UseShellExecute = false;
p.StartInfo = pstart;
p.Start();
p.WaitForExit();
}
I hope this serves to save someone else the hours of time it took me to figure out about the metadata file and all the peculiarities of sllauncher.exe
I have get my website path using HttpRuntime.AppDomainAppPath (like this C:/personal/Website/page.aspx)
Web service is always located on page.aspx parent of parent folder (like this C:/personal/Service/service.asmx ). I get the webservice-path using a ABC.dll in servicePath variable like this string servicePath="C:/personal/Service/service.asmx".
How to check service path against website path?
If (GetWebPath()== GetServicePath())
{
// ... do something
}
private string GetWebPath()
{
string path = HttpRuntime.AppDomainAppPath;
string[] array = path.Split('\\');
string removeString = "";
for(int i = array.Length; --i >= 0; )
{
removeString = array[array.Length - 2];
break;
}
path = path.Replace(#"\" + removeString + #"\", "");
return path;
}
private string GetServicePath()
{
string path = #"C:\MNJ\OLK\ABC.asmx"
string[] array = path.Split('\\');
string removeString = "";
for(int i = array.Length; --i >= 0; )
{
removeString = #"\" + array[array.Length - 2] + #"\" + array[array.Length - 1];
path = path.Replace(removeString, "");
break;
}
return path;
}
string webPath = #"C:\blabla\CS_Web\website\";
string servicePath = #"C:\blabla\CS_Web\SPM\Server.asmx";
if(Path.GetDirectory(Path.GetDirectoryName(servicePath))==Path.GetDirectoryName(webPath)
{
//You do something here
}
You have to up page to parent folder using Path.GetDirectoryName()
Try this:
System.Web.Server.MapPath(webPath);
This will return the physical file path of the currently executing web file.
More information can be found here: System.Web.Server
Providing you want to check the following pathes:
string webPath = #"C:\blabla\CS_Web\website\";
string servicePath = #"C:\blabla\CS_Web\SPM\Server.asmx";
you should call
string webPathParentDir = GetParentDirectoryName(webPath);
string servicePathParentDir = GetParentDirectoryName(servicePath);
if (servicePathParentDir.Equals(webPathParentDir, StringComparison.OrdinalIgnoreCase))
{
// ... do something
}
with method:
private string GetParentDirectoryName(string path)
{
string pathDirectory = Path.GetDirectoryName(servicePath);
return new DirectoryInfo(pathDirectory).Parent.FullName;
}
What I'm trying to do is to upload a website using FTP in C# (C Sharp). So I need to upload all files and folders within a folder, keeping its structure. I'm using this FTP class: http://www.codeproject.com/Tips/443588/Simple-Csharp-FTP-Class for the actual uploading.
I have come to the conclusion that I need to write a recursive method that goes through every sub-directory of the main directory and upload all files and folders in it. This should make an exact copy of my folder to the FTP. Problem is... I have no clue how to write a method like that. I have written recursive methods before but I'm new to the FTP part.
This is what I have so far:
private void recursiveDirectory(string directoryPath)
{
string[] filePaths = null;
string[] subDirectories = null;
filePaths = Directory.GetFiles(directoryPath, "*.*");
subDirectories = Directory.GetDirectories(directoryPath);
if (filePaths != null && subDirectories != null)
{
foreach (string directory in subDirectories)
{
ftpClient.createDirectory(directory);
}
foreach (string file in filePaths)
{
ftpClient.upload(Path.GetDirectoryName(directoryPath), file);
}
}
}
But its far from done and I don't know how to continue. I'm sure more than me needs to know this! Thanks in advance :)
Ohh and... It would be nice if it reported its progress too :) (I'm using a progress bar)
EDIT:
It might have been unclear... How do I upload a directory including all sub-directories and files with FTP?
Problem Solved! :)
Alright so I managed to write the method myslef. If anyone need it feel free to copy:
private void recursiveDirectory(string dirPath, string uploadPath)
{
string[] files = Directory.GetFiles(dirPath, "*.*");
string[] subDirs = Directory.GetDirectories(dirPath);
foreach (string file in files)
{
ftpClient.upload(uploadPath + "/" + Path.GetFileName(file), file);
}
foreach (string subDir in subDirs)
{
ftpClient.createDirectory(uploadPath + "/" + Path.GetFileName(subDir));
recursiveDirectory(subDir, uploadPath + "/" + Path.GetFileName(subDir));
}
}
It works very well :)
I wrote an FTP classe and also wrapped it in a WinForms user control. You can see my code in the article An FtpClient Class and WinForm Control.
I wrote a reusable class to upload entire directory to an ftp site on windows server, the program also renames the old version of that folder (i use it to upload my windows service program to the server).
maybe some need this:
class MyFtpClient
{
protected string FtpUser { get; set; }
protected string FtpPass { get; set; }
protected string FtpServerUrl { get; set; }
protected string DirPathToUpload { get; set; }
protected string BaseDirectory { get; set; }
public MyFtpClient(string ftpuser, string ftppass, string ftpserverurl, string dirpathtoupload)
{
this.FtpPass = ftppass;
this.FtpUser = ftpuser;
this.FtpServerUrl = ftpserverurl;
this.DirPathToUpload = dirpathtoupload;
var spllitedpath = dirpathtoupload.Split('\\').ToArray();
// last index must be the "base" directory on the server
this.BaseDirectory = spllitedpath[spllitedpath.Length - 1];
}
public void UploadDirectory()
{
// rename the old folder version (if exist)
RenameDir(BaseDirectory);
// create a parent folder on server
CreateDir(BaseDirectory);
// upload the files in the most external directory of the path
UploadAllFolderFiles(DirPathToUpload, BaseDirectory);
// loop trough all files in subdirectories
foreach (string dirPath in Directory.GetDirectories(DirPathToUpload, "*",
SearchOption.AllDirectories))
{
// create the folder
CreateDir(dirPath.Substring(dirPath.IndexOf(BaseDirectory), dirPath.Length - dirPath.IndexOf(BaseDirectory)));
Console.WriteLine(dirPath.Substring(dirPath.IndexOf(BaseDirectory), dirPath.Length - dirPath.IndexOf(BaseDirectory)));
UploadAllFolderFiles(dirPath, dirPath.Substring(dirPath.IndexOf(BaseDirectory), dirPath.Length - dirPath.IndexOf(BaseDirectory))
}
}
private void UploadAllFolderFiles(string localpath, string remotepath)
{
string[] files = Directory.GetFiles(localpath);
// get only the filenames and concat to remote path
foreach (string file in files)
{
// full remote path
var fullremotepath = remotepath + "\\" + Path.GetFileName(file);
// local path
var fulllocalpath = Path.GetFullPath(file);
// upload to server
Upload(fulllocalpath, fullremotepath);
}
}
public bool CreateDir(string dirname)
{
try
{
WebRequest request = WebRequest.Create("ftp://" + FtpServerUrl + "/" + dirname);
request.Method = WebRequestMethods.Ftp.MakeDirectory;
request.Proxy = new WebProxy();
request.Credentials = new NetworkCredential(FtpUser, FtpPass);
using (var resp = (FtpWebResponse)request.GetResponse())
{
if (resp.StatusCode == FtpStatusCode.PathnameCreated)
{
return true;
}
else
{
return false;
}
}
}
catch
{
return false;
}
}
public void Upload(string filepath, string targetpath)
{
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential(FtpUser, FtpPass);
client.Proxy = null;
var fixedpath = targetpath.Replace(#"\", "/");
client.UploadFile("ftp://" + FtpServerUrl + "/" + fixedpath, WebRequestMethods.Ftp.UploadFile, filepath);
}
}
public bool RenameDir(string dirname)
{
var path = "ftp://" + FtpServerUrl + "/" + dirname;
string serverUri = path;
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
request.Method = WebRequestMethods.Ftp.Rename;
request.Proxy = null;
request.Credentials = new NetworkCredential(FtpUser, FtpPass);
// change the name of the old folder the old folder
request.RenameTo = DateTime.Now.ToString("yyyyMMddHHmmss");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
using (var resp = (FtpWebResponse)request.GetResponse())
{
if (resp.StatusCode == FtpStatusCode.FileActionOK)
{
return true;
}
else
{
return false;
}
}
}
catch
{
return false;
}
}
}
Create an instance of that class:
static void Main(string[] args)
{
MyFtpClientftp = new MyFtpClient(ftpuser, ftppass, ftpServerUrl, #"C:\Users\xxxxxxxxxxx");
ftp.UploadDirectory();
Console.WriteLine("DONE");
Console.ReadLine();
}
Unless you're doing this for fun or self-improvement, use a commercial module. I can recommend one from Chilkat, but I'm sure there are others.
Note: I'm pretty sure this does answer the stated problem, What I'm trying to do is to upload a website using FTP in C# (C Sharp).
I'm trying to user Redemption to update a user's Outlook contacts. The user I'm affecting is passed in the exchangeUser, call him "Target User".
This code works when I run it logged in as myself:
public OutlookFolders(string outlookRootFolder, string exchangeUser, string mailServer)
{
var session = new RDOSessionClass();
session.LogonExchangeMailbox(exchangeUser, mailServer);
session.Stores.FindExchangePublicFoldersStore();
var store = session.GetSharedMailbox(exchangeUser);
//...
}
I tried to log in as a 3rd user "Test User" who is not me and is not "Target User". My program brings up a password prompt at runtime when it gets to FindExchangePublicFoldersStore, and if I don't fill in my credentials it fails with the error:
System.Runtime.InteropServices.COMException (0x8004011D): Error in
IMAPISession.OpenMsgStore(pbExchangeProviderPrimaryUserGuid):
MAPI_E_FAILONEPROVIDER
ulVersion: 0
Error: Microsoft Exchange is not available. Either there are network
problems or the Exchange computer is down for maintenance.
Component: Microsoft Exchange Information Store
ulLowLevelError: 2147746069
ulContext: 1318
I tried giving "Test User" owner permission on "Target User's" Mailbox and Contacts folder. Doesn't seem to make a difference. What other permissions need to be set for this to work?
The rule of thumb is to run your code as a user who can access the mailboxes in question, call LogonExchangeMailbox for the current user, then open other users' mailboxes using GetSharedMailbox.
Here's the code for Dmitry's answer.
It also uses a function from Milan's blog.
public OutlookFolders(string exchangeUser, string mailServer)
{
var session = new RDOSessionClass();
var userFullName = GetFullName("DOMAIN-NT\\" + Environment.UserName);
session.LogonExchangeMailbox(userFullName, mailServer);
session.Stores.FindExchangePublicFoldersStore();
var store = session.GetSharedMailbox(exchangeUser);
rootFolder = store.GetDefaultFolder((rdoDefaultFolders)OlDefaultFolders.olFolderContacts);
}
public static string GetFullName(string strLogin)
{
string str = "";
string strDomain;
string strName;
// Parse the string to check if domain name is present.
int idx = strLogin.IndexOf('\\');
if (idx == -1)
{
idx = strLogin.IndexOf('#');
}
if (idx != -1)
{
strDomain = strLogin.Substring(0, idx);
strName = strLogin.Substring(idx + 1);
}
else
{
strDomain = Environment.MachineName;
strName = strLogin;
}
DirectoryEntry obDirEntry = null;
try
{
obDirEntry = new DirectoryEntry("WinNT://" + strDomain + "/" + strName);
PropertyCollection coll = obDirEntry.Properties;
object obVal = coll["FullName"].Value;
str = obVal.ToString();
}
catch (System.Exception ex)
{
str = ex.Message;
}
return str;
}