IIS 6.0 DirectoryEntry ScriptMaps property and set .Net version - c#

After creating a web site, i notice that it sets the asp.net version to 1.1. I would like to in code change this to version 2.0.50727. I found that in the ScriptMaps property there are string list of all the file extensions and code mapping. But I have not figured out how to change all of the values that are connected to .net? Or is there a way to tell it to use an other verison with .invoke?

DirectoryEntry sited = new DirectoryEntry(string.Format("IIS://localhost/w3svc/{0}/Root", websiteID.ToString()));
sited.Properties["AccessRead"].Add(true);
PropertyValueCollection testScriptMap = sited.Properties["ScriptMaps"];
object[] allValues = (object[])testScriptMap.Value;
object[] newValues = new object[allValues.Length];
string oldVersion = "v1.1.4322";
string newVersion = "v2.0.50727";
for (int i = 0; i < allValues.Length; i++)
{
if (allValues[i] is string)
{
string temp = allValues[i] as string;
if (temp.Contains(oldVersion))
{
newValues[i] = temp.Replace(oldVersion, newVersion);
}
else
{
newValues[i] = allValues[i];
}
}
else
{
newValues[i] = allValues[i];
}
}
testScriptMap.Value = newValues;
sited.CommitChanges();
After little trial and error I found a solution. I took all the objects in the created site and made a copy where i changed the version part of the path string. Then I set the value property of the scriptMaps object to point to the new updated object array.

One easy way is to execute "aspnet_regiis -i". The aspnet_regiis.exe file will be located at - C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe.
Alternately, you can take the hard way, and take a look at an article on modification of IIS Metabase.
Taking the harder way, to me, is much cooler than the easy one!

The following command installs the ASP.NET version associated with the tool and updates the script maps of all existing ASP.NET applications. Note that only applications that are currently mapped to an earlier version of ASP.NET are affected.
Aspnet_regiis -i
the Aspnet_regiis.exe is under the following path:
C:\WINDOWS\Microsoft.NET\Framework\"dot net version you want to change to"
in your case will be under v2.0.50727:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
source: ASP.NET IIS Registration Tool

Related

Installshield Automation Interface - Always Overwrite

I am trying to automate the creation of install packages for the company i work for and am using the Installshield Automation Interface to create an MSI project. One of the things we have done up to now (manually if you can believe it) is go through all of the files we want to release after importing them into installshield and setting them to "Always overwrite" on a folder by folder basis since it seems you cant do it recursively on a parent folder. When creating a Basic MSI on the installshield GUI it lets you do this, however when creating an MSI via the COM object it appears this option is only available to InstallScript which i cant make an MSI with.
Anywho my code kinda looks like this
static void AddFiles(string[] aFiles, ISWiAuto24.ISWiProject oISProj, string sProjName, string ePackName)
{
oISProj.OpenProject(sProjName, false);
string installdirectory = "[ProgramFilesFolder]" + ePackName;
oISProj.INSTALLDIR = installdirectory;
Console.WriteLine("Adding ePack files");
for (int i = 0; i < aFiles.Length;i++ )
{
Console.WriteLine(aFiles[i]);
ISWiComponent NewComponent = oISProj.AddComponent("Component_"+i);
string string_PathToFile = aFiles[i].Substring(0,aFiles[i].LastIndexOf("\\"));
string string_RelativeToInstallDir = string_PathToFile.Substring(aFiles[i].LastIndexOf(ePackName) + ePackName.Length);
NewComponent.Destination = installdirectory+string_RelativeToInstallDir ;
NewComponent.AddFile(aFiles[i]);
/*----------------------------Fails Here--------------------------------------*/
NewComponent.OverwriteMainOptions=0;
/*----------------------------------------------------------------------------*/
}
oISProj.SaveProject();
oISProj.CloseProject();
Console.WriteLine("Done");
}
static voidMain(string[] args){
ISWiAuto24.ISWiProject oISProj = new ISWiAuto24.ISWiProject();
string ePackName = "ThisMonthsBundle"
string[] aFiles = new[] {#"c:/Foo/Roo/Goo/"+ePackName+"/File0",#"c:/Foo/Roo/Goo/"+ePackName+"/File1",#"c:/Foo/Roo/Goo/"+ePackName+"/File2",#"c:/Foo/Roo/Goo/File3"}
string sProjName = "C:/Foo/Bar.ism"
oISProj.CreateProject(sProjName, ISWiProjectType.eptMsi);
AddFiles(aFiles,oISProj,sProjName);
}
does anyone know a way around this?
the error is: COM Exception was unhandled - This property is not supported for Basic MSI Project. You need to remove the line that calls the property from your automation code.
I found an old forum post back in 2010 on the flexera community forum where a flexera developer responded to a user saying that this can be done like so:
ISWiComponent NewComponent = oISProj.AddComponent("Component_1");
NewComponent.Destination = "[ProgramFilesFolder]" + "ProgramName";
NewComponent.AddFile("c:\File1");
ISWiFiles Files = NewComponent.ISWiFiles;
foreach (ISWiFile File in Files)
{
File.OverrideSystemVersion = true;
File.Version = "65535.0.0.0";
}
the developer in question recognised the need for the automation interface to support the ISWiFile.AlwaysOverwrite property and raised a work order for it. i guess they just havent gotten around to it in the 8 years since
https://community.flexerasoftware.com/showthread.php?194448-installshield-2009-automation-File-property-quot-Always-overwrite-quot
Anyway, The above appears to work

Microsoft Diagnostics Runtime crash.dmp analysis (C#)

I'm trying to read in a crash.dmp using the functionality in Microsoft.Diagnostics.Runtime .NET componenet (also known as ClrMD).
I have a crash.dmp in a known location (in a string called pathToFile) so that's not the issue. The rest of the code looks like this.
DataTarget dataTarget = DataTarget.LoadCrashDump(pathToFile);
ClrInfo clrInfo = dataTarget.ClrVersions[0];
string dacLocation = clrInfo.TryGetDacLocation();
When testing this code, I get the following error in the command window:
Error processing directory: System.ArgumentOutOfRangeException. Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index.
I'm assuming it's something to do with the ClrVersions[0] bit but can't for the life of me pin it down.
Any help would be appreciated.
Current Status
When running the following command (which fails)
ClrRuntime rt = dataTarget.CreateRuntime("path\to\mscordawks.dll");
I receive the following error in cmd
mismatched architecture between this process and the dac
Cheers
Anyone?
If the TryGetDacLocation succeeded then you should be able to do
ClrRuntime rt = dataTarget.CreateRuntime(dacLocation);
so you get the correct dacLocation.
Was the dump you are analysing generated on same machine where you are analysing it?
Also what are the bitnesses of the process the dump was generated from, the process in which the CLRMD code is running and the debugger utility used to generate the dump?
Generally you want to be matching the bitnesses all round (x86/x64).
Doug
I was having the same issue reading a dump file generated on the same computer. There were two problems, first bitness (should have been 64, was running in 32) and the second harder problem that the proper DLL could not be located. To fix the second problem I created a method that tries all of the properly named DLLs it can find:
private static ClrRuntime GetRuntime(DataTarget target)
{
ClrInfo version = target.ClrVersions[0];
string dacLocation = version.TryGetDacLocation();
// If we don't have the dac installed, we will use the long-name dac in the same folder.
if (!string.IsNullOrEmpty(dacLocation))
dacLocation = version.DacInfo.FileName;
try // try the one it should be
{
return target.CreateRuntime(dacLocation);
}
catch (Exception e)
{
}
// can't find the one it should be, try'em all
string fileName = "mscordacwks.dll";
string[] searchLocations = new[]
{
#"C:\Windows\Microsoft.NET\",
#"C:\Windows\winsxs\"
};
foreach (string searchLocation in searchLocations)
{
foreach (string file in Directory.GetFiles(searchLocation, fileName, SearchOption.AllDirectories))
{
try
{
return target.CreateRuntime(file);
}
catch (Exception e)
{
}
}
}
throw new Exception("No found valid runtimes");
}
I followed this artificial to get the mscordacwks.dll when dealing with platform differences between where the dmp file was taken and the machine doing the analysis.
http://chentiangemalc.wordpress.com/2014/04/16/obtaining-correct-mscordacwks-dll-for-net-windbging/#comment-3380
and followed the steps including renaming the file to include the architecture and version information.
After that I just http://chentiangemalc.wordpress.com/2014/04/16/obtaining-correct-mscordacwks-dll-for-net-windbging/#comment-3380ut the full path of the file as dacLocation in the script.
After that it worked!
I suspect that putting it on the path could be made to work.

How to get Virtual Machine name using VMWare API?

I'm using the Vestris.VMWareLib API to remotely control my VMs on an ESX 5.0 server. I use the VMWareVirtualMachine.Open method to power on my virtual images. My code is written in C#. The problem is that you need to know the path to the datastore before you can power on the image - I'd like to be able to power it on knowing the VM name only. Is there a way to do this? I've included my current code below.
Thanks, John
using Vestris.VMWareLib;
//Works if VM name is in the path but what if it isn't?
List<VMWareVirtualMachine> vitualMachines = esxServer.RegisteredVirtualMachines.ToList();
VMWareVirtualMachine virtualMachine = vitualMachines.Where(vm => vm.PathName.Contains(vmName)).First();
VMWareVirtualMachine virtualMachine = esxServer.Open(vmName);
There's a method called VMWareVirtualMachine.GetProperty() which can be used to obtain the VM name but I don't know how to use it. Any suggestions or ideas how I can do this?
Thanks,
John
There's been a commit to VMWareTasks that adds the property "Name" to the VMWareVirtualMachine class, it is taken from the "displayName" property in the vmx file. The property is not in VMWareTasks 1.7 so as of right now, you will need to pull the source and build it yourself.
Use it to iterate the registered guests, checking this variable and then power on the appropriate one.
using Vestris.VMWareLib;
private void powerOnVm(string vmName)
{
using (VMWareVirtualHost esxServer = new VMWareVirtualHost())
{
esxServer.ConnectToVMWareVIServer("yourHost", "yourUser", "yourPassword");
using (VMWareVirtualMachine virtualMachine = esxServer.RegisteredVirtualMachines.FirstOrDefault(vm => vm.Name == vmName))
{
if (virtualMachine != null && !virtualMachine.IsRunning)
virtualMachine.PowerOn();
}
}
}
I just tested the above and it worked fine.

The best way to get a path to machine.config of a different .NET version

Whats the best way to get a path to .net 2.0 machine.config file, if the application is running on .net 4.0?
One way would be to do string manipulation and file system access to replace v4.0* with v2.0* in
new ConfigurationFileMap().MachineConfigFilename; and then pass it to ConfigurationManager.OpenMappedMachineConfiguration(new ConfigurationFileMap(<HERE>)). I will resort to this solution if nothing better is available.
Since I needed the path to machine.config for ASP.NET versions, I didn't care about all .NET framework paths (e.g. 3 and 3.5 frameworks since they are just extensions of 2.0). I ended up querying HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET registry key and Path value of the framework key. Finally appending config\machine.config to the framework path yielded desired results.
The method to map ASP.NET runtime to machine.config path would take strings of any format "v2.0", "2.0.50727.0" or just "v2" and "2", regex it to either one decimal digit like "2.0" or one first digit if decimal digits were not specified like "2" and get the right value from the registry. Something similar to this:
string runtimeVersion = "2.0";
string frameworkPath;
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\ASP.NET");
foreach (string childKeyName in regKey.GetSubKeyNames())
{
if (Regex.IsMatch(childKeyName, runtimeVersion))
{
RegistryKey subKey = regKey.OpenSubKey(childKeyName))
{
frameworkPath = (string)subKey.GetValue("Path");
}
}
}
string machineConfigPath = Path.Combine(frameworkPath, #"config\machine.config");
string webRootConfigPath = Path.Combine(frameworkPath, #"config\web.config");
Lastly, I pass this configs to WebConfigurationMap (I am using Microsoft.Web.Administration, but you can use it with System.Configuration as well, the code is almost the same):
using (ServerManager manager = new ServerManager())
{
Configuration rootWebConfig = manager.GetWebConfiguration(new WebConfigurationMap(machineConfigPath, webRootConfigPath), null);
}
WebConfigurationMap maps configuration to custom machine.config and root web.config (hence null as a second argument in GetWebConfiguration())

Sharepoint web.config changes using SPWebConfigModification

I've written a sharepoint application that needs to change web.config
I have a feature that is supposed to make all these configurations. The code for that feature is like this:
SPSite site = properties.Feature.Parent as SPSite;
List<SPWebConfigModification> modifications = new List<SPWebConfigModification>();
modifications.AddRange(CustomErrorsModeConfig.Modifications);
webConfigModificationHelper.AddWebConfigModifications(site.WebApplication, modifications);
CustomErrorsModeConfig.Modifications property contains this code:
public static SPWebConfigModification[] Modifications = {
new SPWebConfigModification()
{
Owner = WebConfigModificationOwner,
Name = "mode",
Type = SPWebConfigModification.SPWebConfigModificationType.EnsureAttribute,
Path = "system.web/customErrors",
Sequence = 0,
Value = "Off"
}
};
Then finally the webConfigModificationHelper.AddWebConfigModifications method:
foreach (SPWebConfigModification modification in modifications)
{
webApp.WebConfigModifications.Add(modification);
}
webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
webApp.Update();
The problem is that I keep getting this error:
Name cannot begin with the ''' character, hexadecimal value 0x27. Line 1, position 1453
Could this be a problem with the web.config before I try to apply my changes ?
Could the SPWebConfigModification property be incorrectly defined ?
Is there some glitch in my code that leads to this error ?
Might there be some property I am missing (e.g. web.AllowUnsafeUpdates) ?
Some sharepoint site configuration ?
I've been trying to solve this issue for some time now with no luck :( Any ideas ?
I can recommend using stsadmwebconfig for making changes to web.config files. I've implemented this in many features and it has always been a pain, especially while developing. Using this tool makes it a lot easier.
Ive seen this before when the file format is not correctly set between the file and the declaration.
Open the web.config file into a advanced text editor (Notepad++ or Visual Studio) and manually force the file type to match what is specified. Usually its going to be UTF-8.
For more info:
http://www.dumpsterdoggy.com/tutorials/?xmlexception-name-cannot-begin-with
Try taking the List template and for loop out and set the property using straightforward syntax. Here's a post for setting the property in your example, see if you can get this to work and then progress to building up a more generic solution with a List and iteration over the items in the list.
http://www.sharepointkings.com/2008/05/how-to-modify-webconfig-file-in.html

Categories