IIS reverses web site settings when stopping - iis

I have an issue with configuring IIS. I programmatically create a web site and an application (virtual dir) under the web site. Among other settings, I add a wildcard application map in the applications settings. When IIS is restarted, it removes the wilcard application map (and some other settings, but I just mention the wilcard map for simplicity). I can re-add the map, using IIS manager, but when I restart IIS, the map is removed. BUT - if I add the wildcard map and then, without restarting IIS, use a browser first to hit a page in that application, then any subsequent IIS restarts do not cause the map to disappear. Any idea what's going on?
here's my code:
// root virtual dir object
string strRootVirtDirPath = "IIS://localhost/w3svc/" + strWebSiteID + "/root";
DirectoryEntry deRootVirtDir = new DirectoryEntry(strRootVirtDirPath);
// add new virtual dir
DirectoryEntry deNewVirtDir = deRootVirtDir.Children.Add(strAppName, "IIsWebVirtualDir");
deNewVirtDir.Properties["Path"].Value = strPhysicalDir;
deNewVirtDir.Properties["AppFriendlyName"].Value = strAppName;
deNewVirtDir.Properties["AppRoot"].Value = "/LM/W3SVC/" + strWebSiteID + "/Root/" + strAppName;
deNewVirtDir.Properties["AppPoolId"].Value = strAppPoolName;
// create the application
deNewVirtDir.Invoke("AppCreate", 1);
// commit changes
deNewVirtDir.CommitChanges();
deRootVirtDir.CommitChanges();
deNewVirtDir.Close();
deRootVirtDir.Close();

Figured out the problem. It's described in Microsoft's KB article 286196: http://support.microsoft.com/kb/286196
All my affected machines were Windows Server 2K3 R2 just like described in the article.

Related

Use NetOffice.PowerPointApi on azure app service

I have written a code to save all the slides in a presentation as jpeg. It works well in visual studio locally on my system, but when I deploy it on Azure app service, I get 500 internal server error.
IIS received the request; however, an internal error occurred during the processing of the request. The root cause of this error depends on which module handles the request and what was happening in the worker process when this error occurred. IIS was not able to access the web.config file for the Web site or application. This can occur if the NTFS permissions are set incorrectly. IIS was not able to process configuration for the Web site or application. The authenticated user does not have permission to use this DLL. The request is mapped to a managed handler but the .NET Extensibility Feature is not installed.
The code:
using pptd = NetOffice.PowerPointApi;
using NetOffice.PowerPointApi.Enums;
using NetOffice.OfficeApi.Enums;
public void genThumbnails(string originalfileName,string renamedFilename, string dirPath)
{
pptd.Application pptApplication = new pptd.Application();
pptd.Presentation pptPresentation = pptApplication.Presentations.Open(dirPath + renamedFilename, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
int i = 0;
foreach (pptd.Slide pptSlide in pptPresentation.Slides)
{
pptSlide.Export(dirPath + originalfileName + "_slide" + i + ".jpg", "jpg", 1280, 720);
i++;
}
pptPresentation.Close();
}
What is the mistake that I am doing? Does NetOffice package also need MS Office installed on the server like Office.Interop?
The standard windows and Linux web apps used blessed operating system images. As part of the PaaS design, customers are limited as to what they can run as there is no MS Office inter-op present and also because Azure Web Apps is a sandbox.
My suggestion would be to create a container image that has the necessary dependencies that you need and then deploy your custom container to an Azure Web App Container.

IIS 7.5 application pool uses wrong %APPDATA% for custom user as identity

I want my MVC3 web application to access %APPDATA% (e.g. C:\Users\MyUsername\AppData\Roaming on Windows 7) because I store configuration files there. Therefore I created an application pool in IIS with the identity of the user "MyUsername", created that user's profile by logging in with the account, and turned on the option "Load User Profile" (was true by default anyway). Impersonation is turned off.
Now I have the problem that %APPDATA% (in C#):
appdataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
resolves to c:\windows\system32\inetsrv instead of C:\Users\MyUsername\AppData\Roaming.
UPDATE: More exactly, the above C# code returns an empty string, so that Path.GetFullPath(Path.Combine(appdataDir, "MyAppName")) prepends the current path to my application name, resulting in c:\windows\system32\inetsrv\MyAppName.
I know I made this work before with the same web application on a Windows Server 2008 R2, and now I'm getting this problem with the same major version 7.5 of IIS on my Windows 7.
I used the same procedure as before: Created a new user, logged in as that user to create the profile and APPDATA directories, then added the application pool with this identity and finally added the web application to this pool.
Any ideas?
Open your %WINDIR%\System32\inetsrv\config\applicationHost.config and look for <applicationPoolDefaults>. Under <processModel>, make sure you don't have setProfileEnvironment="false". If you do, set it to true.
Application Pools - Your application Pool - Advanced settings ...
Process Model - Load user Profile set True.
It Helps me.
Taken from
https://blogs.msdn.microsoft.com/vijaysk/2009/03/08/iis-7-tip-3-you-can-now-load-the-user-profile-of-the-application-pool-identity/
I experienced the same problem recently. As mentioned by Amit, the problem is that the user profile isn't loaded. The setting is for all application pools, and is in the applicationHost.config (typically C:\Windows\System32\inetsrv\config\applicationHost.config). If you update the applicationPoolDefaults elements as follows, it will work;
<applicationPoolDefaults managedRuntimeVersion="v4.0">
<processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" />
</applicationPoolDefaults>
We've tried this with IIS 7.5, and taken it through to production without problem.
You can automate this if you want;
appcmd set config -section:system.applicationHost/applicationPools /applicationPoolDefaults.processModel.setProfileEnvironment:"true" /commit:apphost
or if you prefer powershell
Set-WebConfigurationProperty "/system.applicationHost/applicationPools/applicationPoolDefaults/processModel" -PSPath IIS:\ -Name "setProfileEnvironment" -Value "true"
Hope this helps
I am experiencing the same problem. Have you by chance installed the Visual Studio 11 beta? I did recently, and I've noticed a couple of differences in how the 4.0 compatible .dlls for that work with our code. I'm still trying to track down the problem for certain, but I didn't have this problem before that.
Edit:
After comparing the decompiled sources from 4.0 and 4.5 for GetFolderPath (and related), there are differences. Whether they are the source of the problem...I'm not sure yet.
Edit 2: Here are the relevant changes. I'm working on trying both to see if I get different results. [code removed]
Edit 3:
I've now tried calling SHGetFolderPath directly, which is what the .NET Framework ends up doing, anyway. It returns E_ACCESSDENIED (-2147024891 / 0x80070005). I don't know what has changed where I'm getting that in some specific cases, but not in others.
Edit 4:
Since you're getting a empty string, you may want to switch your code to use SHGetFolderPath so you can get the HResult and at least know what exactly is happening.
void Main() {
Console.WriteLine( GetFolderPath( Environment.SpecialFolder.ApplicationData ) );
}
[System.Runtime.InteropServices.DllImport("shell32.dll")]
static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, uint dwFlags, StringBuilder pszPath);
private string GetFolderPath( Environment.SpecialFolder folder ) {
var path = new StringBuilder( 260 );
var hresult = SHGetFolderPath( IntPtr.Zero, (int) folder, IntPtr.Zero, 0, path );
Console.WriteLine( hresult.ToString( "X" ) );
return ( (object) path ).ToString( );
}
The problem is with your IIS settings. The answer is here: Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) returns String.Empty

Sharepoint 2010 unextend web application

I am trying to unextend a web application.
First i tried this code:
getWebApp.IisSettings.Remove(SPUrlZone.Internet);
It is working fine but not deleting the IIS website or physical folder of this extended web app. So i started to delete IIS website manually by using the following code:
int instID = getWebApp.IisSettings[SPUrlZone.Internet].PreferredInstanceId;
SPIisWebSite iisWebSite = new SPIisWebSite(instID);
iisWebSite.Unprovision();
or:
ServerManager iisManager = new ServerManager();
Site s1 = iisManager.Sites["MySiteName - 1234"]; // you can pass the site name or the site ID
iisManager.Sites.Remove(s1);
iisManager.CommitChanges();
IIS website is not getting deleted.
Any help?
You can do this without code. In SharePoint 2010, all you need to do is go to Central Administration, Manage Web Application, select your application, select the drop down below the 'Delete' button and select 'Remove SharePoint from IIS web site'. Select your extended site, then also be sure to select 'Yes' to delete the site from IIS.
SPWebApplication getWebApp = GetWebAppById(GlobalVar._webAppId);
getWebApp.IisSettings.Remove(SPUrlZone.Internet);
getWebApp.Update();
Directory.Delete(GlobalVar._exWebAppPhyPath, true);
ServerManager iisManager = new ServerManager();
Site getSite = iisManager.Sites[GlobalVar._webAppExtendedName];
iisManager.Sites.Remove(getSite);
iisManager.CommitChanges();
getWebApp.Update();
getWebApp.Provision();

IIS 7 - Virtual directory redirection path?

I wrote this little web app that lists the websites running on the local IIS + virtual directories attached to the websites.
Using the following line I was able to get the HTTP Redirection URL of a virtual directory, if it was set to redirect:
_directoryEntry.Properties["HttpRedirect"].Value.toString()
Which works quite nicely in IIS 6 - but the value is empty when I try my app in an IIS 7 - and I tried switching the application pool to Classic pipeline as well - what has changed in IIS 7 here? And why?
In IIS7 <httpRedirect> element replaces the IIS 6.0 HttpRedirect metabase property.
You need to set it up like this in your web.config file:
<system.webServer>
<httpRedirect enabled="true" destination="WebSite/myDir/default.aspx" />"
</system.webServer>
If you do not want to tweak web.config, this article talks about a way to do them the IIS 6 way: Creating Http Redirects in IIS7 on Virtual Directories like IIS6
Hope this helps.
What has changed?: IIS7 has a completely new configuration system similar to .NET's hierarchical configuration system. Checkout this link for more detail here on what's changed.
How to get the HttpRedirect value: In C#, rather than using the System.DirectoryServices namespace to access the IIS configuration settings, use the new Microsoft.Web.Administration.dll.
Your code should look something like this example from IIS.net:
using System;
using System.Text;
using Microsoft.Web.Administration;
internal static class Sample
{
private static void Main()
{
using (ServerManager serverManager = new ServerManager())
{
Configuration config = serverManager.GetWebConfiguration("Default Web Site");
ConfigurationSection httpRedirectSection = config.GetSection("system.webServer/httpRedirect");
Console.WriteLine("Redirect is {0}.", httpRedirectSection["enabled"].Equals("true") ? "enabled" : "disabled");
}
}
}
You can actually do quite a lot with the new Microsoft.Web.Administration.dll. Checkout Carlos Ag's blog here for some ideas.
Two quick notes:
Microsoft.Web.Administration.dll is available if the "IIS Management Scripts and Tools" role service is installed. It should be under the inetsrv directory in systemroot.
Any code you run with the MWA dll needs to run as Administrator to access IIS configuration, so just make sure the account running the script has admin rights.
Hope this helps!

Do I need to replace localhost in the IIS://localhost/MimeMap when reading the Mimemap

I'm reading out the mime types from IIS's MimeMap using the command
_mimeTypes = new Dictionary<string, string>();
//load from iis store.
DirectoryEntry Path = new DirectoryEntry("IIS://localhost/MimeMap");
PropertyValueCollection PropValues = Path.Properties["MimeMap"];
IISOle.MimeMap MimeTypeObj;
foreach (var item in PropValues)
{
// IISOle -> Add reference to Active DS IIS Namespace provider
MimeTypeObj = (IISOle.MimeMap)item;
_mimeTypes.Add(MimeTypeObj.Extension, MimeTypeObj.MimeType);
}
Do I need replace the localhost part when I deploy it to my live server? If not, why not and what are the implications of not doing so.
Cheers
It should not be an issue to leave the host as 'localhost'.
After all, you want to get the MimeMap of the machine your app is running on, correct?
A possible complication that I can forsee is that if you are using a third party as a host. They can do anything they want with host headers and it may be possible that localhost is not available for whatever reason.
But you should simply give it a shot and adjust if necessary.
If you leave it like 'Localhost', you will have to run this script directly on the server.
If you change it to fetch the machine name directly, you can think of running this script remotely as well.

Resources