After some updates on our windows servers(2008R2 ,2012) Asp.net application throwing error:
var obj_1 = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static);
CacheInternal is coming null, dont know why ?
following solution is not working :(
Solution
I have find the solution. Now HTTPRuntime class doesnt have CacheInternal Property.So to achive the above task I have created a global list adding sessions in that list in Session_Start and removing the sessions in Sessions_end functions of Global.asax.
I have find a solution that maybe is the best for now. If anyone has another, let me know!
object aspNetCacheInternal = null;
var cacheInternalPropInfo = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static);
if (cacheInternalPropInfo == null)
{
// At some point, after some .NET Framework's security update, that internal member disappeared.
// https://stackoverflow.com/a/45045160
//
// We need to look for internal cache otherwise.
//
var cacheInternalFieldInfo = HttpRuntime.Cache.GetType().GetField("_internalCache", BindingFlags.NonPublic | BindingFlags.Static);
if (cacheInternalFieldInfo != null)
{
var httpRuntimeInternalCache = cacheInternalFieldInfo.GetValue(HttpRuntime.Cache);
var httpRuntimeInternalCacheField = httpRuntimeInternalCache.GetType().GetField("_cacheInternal", BindingFlags.NonPublic | BindingFlags.Instance);
if (httpRuntimeInternalCacheField != null)
aspNetCacheInternal = httpRuntimeInternalCacheField.GetValue(httpRuntimeInternalCache);
}
}
else
{
aspNetCacheInternal = cacheInternalPropInfo.GetValue(null, null);
}
return aspNetCacheInternal;
Regards!
That internal member was present in .NET 2.0 and disappeared somewhere between .NET 3.5 and .NET 4.6.1. That's why you shouldn't use reflection to rely on nonpublic members. They can disappear or be renamed any time.
Because .NET is backwards compatible, forcing a certain runtime version will not use older assemblies at runtime, if newer ones are available: .NET 4.6.1 is still an in-place upgrade of all earlier versions down to 4.0.
So I think this update either patched the member away from the System.Web assembly, or it was never in 4.0 to begin with and your application pool somehow changed from .NET 2.0 to .NET 4.0.
Of course it isn't advisable to uninstall updates, but you could try to find the one removing this member. You'd then have to verify it wasn't a security update.
Alternatively force the application to run under .NET 2.0, if that's viable.
You could also try to find a different way to solve the original problem.
Related
The app I'm working on needs to handle files with very long file/path names. It's a .Net 4.6 application so I've implemented the pre-4.6.2 workaround to allow the \\?\ syntax as outlined here and here.
This is the code I'm using to enable the feature (I can't modify the app.config so this has to be set in code):
var type = Type.GetType("System.AppContext");
if (type != null)
{
AppContext.SetSwitch("Switch.System.IO.UseLegacyPathHandling", false);
AppContext.SetSwitch("Switch.System.IO.BlockLongPaths", false);
var switchType = Type.GetType("System.AppContextSwitches");
if (switchType != null)
{
// We also have to reach into System.AppContextSwitches and manually update the cached private versions of these properties (don't ask me why):
var legacyField = switchType.GetField("_useLegacyPathHandling", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
legacyField?.SetValue(null, (Int32)(-1)); // <- caching uses 0 to indicate no value, -1 for false, 1 for true.
var blockingField = switchType.GetField("_blockLongPaths", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
blockingField?.SetValue(null, (Int32)(-1)); // <- caching uses 0 to indicate no value, -1 for false, 1 for true.
}
}
This works (yay!) on all the machines we've tested on, except one (boo!). The machine in question is a Windows 10 Pro installation, like the others, and has the same registry settings in the [Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem] namespace.
The error message on this particular machine is:
The given path format is not supported
The one difference we can see on that machine is that when looking at a very long file in Windows File Explorer, the 'Location' field uses the \\?\ syntax in the r-click > Properties menu.
I'm guessing that there's some registry key that is causing both that difference in File Explorer, and the failure of my fix, but somewhere other than the FileSystem namespace mentioned above.
Has anyone encountered a similar issue, or have an idea of other registry areas that might be relevant?
You can set those AppContext switches on a machine-wide basis via the registry if you don't want to set them in each App.config file individually:
These settings will affect all .NET apps that don't specify a different value in their App.config file. That is, the registry setting only changes the default value, which can still be overridden with app-specific values by specifying <AppContextSwitchOverrides value="..." />
EnableLongPath.reg :
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AppContext]
"Switch.System.IO.BlockLongPaths"="false"
"Switch.System.IO.UseLegacyPathHandling"="false"
C:\>regedit.exe EnableLongPath.reg
First of, I am completely new to octopus client, used it for the first time just before posting this.
So, I've been landed with this project to update the version number on a webpage monitoring some of our octopus deployed projects. I have been looking around the octopus client and not really gotten anywhere. The best I have so far is:
OctopusServerEndpoint endPoint = new OctopusServerEndpoint(server, apiKey);
OctopusRepository repo = new OctopusRepository(endPoint);
var releases = repo.Releases.FindAll();
From these releases I can get the ProjectId and even the Version, the issue is that releases is 600 strong and I am only looking for 15 of them.
The existing code I have to work from used to parse the version from local files so that is all out the window. Also, the existing code only deals with the actual names of the projects, like "AWOBridge", not their ProjectId, which is "Projects-27".
Right now my only option is to manually write up a keyList or map to correlate the names I have with the IDs in the octopus client, which I of course rather not since it is not very extendable or good code practice in my opinion.
So if anyone has any idea on how to use the names directly with octopus client and get the version number from that I would very much appriciate it.
I'll be getting down into octopus client while waiting. Let's see if I beat you to it!
Guess I beat you to it!
I'll just leave an answer here if anyone ever has the same problem.
I ended up using the dashboardto get what I needed:
OctopusServerEndpoint endPoint = new OctopusServerEndpoint(server, apiKey);
OctopusRepository repo = new OctopusRepository(endPoint);
DashboardResource dash = repo.Dashboards.GetDashboard();
List<DashboardItemResource> items = dash.Items;
DashboardItemResource item = new DashboardItemResource();
List<DashboardProjectResource> projs = dash.Projects;
var projID = projs.Find(x => x.Name == projectName).Id;
item = items.Find(x => x.ProjectId == projID && x.IsCurrent == true);
The dashboard is great since it contains all the info that the web dashboard shows. So you can use Project, Release, Deployment and Environment with all the information they contain.
Hope this helps someone in the future!
I'm using LINQPad to run C# snippets for Octopus automation using the Octopus Client library and I have come up with following to get any version of a project making use of Regular expression pattern. It works quite well if you use Pre-release semantic versioning.
For example to get latest release for a project:
var project = Repo.Projects.FindByName("MyProjectName");
var release = GetReleaseForProject(project);
To get specific release use that has 'rc1' in the version for example (also useful if you use source code branch name in the version published to Octopus:
var release = GetReleaseForProject(project, "rc1");
public ReleaseResource GetReleaseForProject(ProjectResource project, string versionPattern = "")
{
// create compiled regex expression to use for search
var regex = new Regex(versionPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
var releases = Repo.Projects.GetReleases(project);
if (!string.IsNullOrWhiteSpace(versionPattern) && !releases.Items.Any(r => regex.IsMatch(r.Version)))
{
return null;
}
return (!string.IsNullOrWhiteSpace(versionPattern)) ? releases.Items.Where(r => regex.IsMatch(r.Version))?.First() : releases.Items?.First();;
}
I have this code for looping through folders in a location, but I am getting some error I can't understand, here's the code
var directoryNames = Directory.EnumerateDirectories(filePath).Where(dir => dir.EndsWith(".user"));
foreach (var directoryName in directoryNames)
{
// some stuff
}
I get this error
'System.IO.Directory' does not contain a definition for 'EnumerateDirectories'
If this is something to do with the Framework version (my project has Framework 2.0, lowest possible so it can install easier on all machines), can you please:
Tell me an alternative code that would work like this, and will work on Framework 2.0
or
Tell me if I can use higher version of Framework, and guarantee that it will be supported on most machines (meaning the user will not be required to download Framework)
EnumerateDirectories was introduced in .NET 4.0. For .NET 2.0, you could use GetDirectories instead. You can specify your filter as a search pattern; this would cause the filtering to be performed by the filesystem itself.
var directoryNames = Directory.GetDirectories(filePath, "*.user");
foreach (var directoryName in directoryNames)
{
// ...
}
On a system multiple mono runtime versions may exist.
For example
/usr/bin/mono
/usr/local/bin/mono
When creating a new managed process from a C# application it can be useful to be explicit about which mono version you want to run it with. (The mono in the path may not be the mono being used to run the current process)
Using the Process class to get the current process name returns the assembly that mono is running not mono itself.
What is the best way to determine which mono runtime is currently being used?
On Linux, the process Id and /proc can be used to find the mono executable.
string monopath = String.Format("/proc/{0}/exe", Process.GetCurrentProcess().Id);
monopath will be a symlink to the current executing mono runtime, and can be used to launch a new process:
Process.Start(monopath);
You can use
Type monoRuntimeType;
MethodInfo getDisplayNameMethod;
if ((monoRuntimeType = typeof(object).Assembly.GetType("Mono.Runtime")) != null &&
(getDisplayNameMethod = monoRuntimeType.GetMethod("GetDisplayName",
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.ExactBinding, null,
Type.EmptyTypes, null)) != null)
Console.WriteLine("Mono " + (string)getDisplayNameMethod.Invoke(null, null));
I'm targetting IOS 4.3 and 5.0 with an app built against the 5.0 SDK and would like to add support for the Twitter functionality introduced in iOS5 only when the app runs on a iOS5 device. What is the recommended way to reliably test for the availability of these OS features at runtime without having your app crash?
I know you do this using respondsToSelector in Objective-C but how is it done in C#?
With recent MonoTouch versions you can use the following code:
if (UIDevice.CurrentDevice.CheckSystemVersion (5, 0)) {
window.RootViewController = navigation;
} else {
window.AddSubview (navigation.View);
}
Otherwise you can get a string from UIDevice.CurrentDevice.SystemVersion and do some checks with your own code.
Follow up to comments, including mine...
If you want to check by feature you can do something like:
MonoTouch.Twitter.TWRequest req = new MonoTouch.Twitter.TWRequest ();
if (req.Handle == IntPtr.Zero) {
Console.WriteLine ("No Twitter support before iOS5");
}
What happens is that the selector to create the TWRequest instance will return null and the .NET object will be created in an invalid (unusable) state that you can query with the Handle property. Again YMMV, testing is key :-)