Application changes not taking effect - c#

I have made a change to a method used in a Functiod in a mapping file but it seems the new code is not taking effect, ever.
I have deployed properly, started the application, restarted related host instance (actually all host instances I could find) and still, the old code seems to execute.
Here's the, simple, method:
public string RemoveNonNumericChars(string stIn, int maxLength)
{
string strOut;
try
{
strOut = Regex.Replace(stIn, "[^0-9]", "");
System.Diagnostics.EventLog.WriteEntry("BizTalk Server 2009", strOut);
return strOut.Substring(0, maxLength);
}
catch
{
return string.Empty;
}
}
I added the writing to EventLog line to see that this code is indeed being executed, but I don't get anything in "Application" event logs.
I do NOT get an empty string being returned, so it really does seem like the old code that's being executed prior to me fixing the method.
What am I missing exactly ?
Thank you.

For some reason, the script is not able to correctly retrieve the Build Config selected in Visual Studio, it's taken from Debug when I'm actually trying to build it for a Test environment. I should have known, thanks anyways.

Related

Accessing Registry Keys from .dll in C#

The environment I'm using might sound a bit messed up, so I will try to explain it at best.
I'm doing some experimental things with Electron. Right now, I have a simple .dll written in C# with using .NET Standard 2.0 as the base. On Electron's side, I'm using electron-edge-js, which, I think, works fine because I'm able to communicate with both of them.
So basic process goes like this,
I'm building my C# code to get my .dll's (I'm also adding reference dlls as well). Putting them into the same folder with Electron project. Starting the project to see how they did.
The problem lies at .dll's code. I'm using the following simple code,
public string RegisterUser(string username, string userkey) {
try {
RegistryKey key;
if (Microsoft.Win32.Registry.CurrentUser == null) return "Current user is null";
key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(#"SOFTWARE\Test\TestFunctions");
if (key == null) return "Key is null";
key.SetValue("uid", username);
key.SetValue("upsw", userkey);
key.Close();
return "Done";
} catch (Exception e) {
return e.ToString();
}
}
However, whenever I call this method, it always returns "Current user is null" no matter what. I tried building my .exe and running it as administrator as well. I checked the privileges in Regedit as well. They all seem fine. I'm having a kinda hard time for such an easy code. A little help would be amazing, thanks!

Where does WebConfigurationManager.AppSettings write its data? Not to web.config

I am trying to use WebConfigurationManager.AppSettings[string] to read/write values to be stored in a configuration file on the server. I thought that it read/wrote it to the Web.config file, or maybe app.config. However, I ran the following test code - which the first time through (as desired) it throws an exception and but writes 'NOTSet' to that configuration entry - this allows me go easily go edit the file and change it to the correct value.
After running it a 2nd time, I can see the value returned is "NOTSet" - exactly as I would like. The code is working exactly as planned.
Except - Where is it written? I did a 'baregrep NOTSet .' - which recursively searched the ENTIRE project source directory and ONLY found the line in code that set the var - which means it was not written to anything in the entire project tree - not web.config, app.config or any other file.
I sighed, and said it must be in the registry - I searched the whole registry for anything with that value, then tried the key value - nothing.
Yet, running the program IS pulling the value that was set on the last run! Where did my data go? I want to be able to edit the value- and more importantly, have a FILE that I can copy to the production web server with all the GUIDs set correctly.
public enum Guids
{
IncidentSourceEnumPortal,
WorkItemClass,
WorkItemManagementPack
}
public class GuidConsts
{
static readonly Dictionary<Guids, Guid> GuidList = new Dictionary<Guids, Guid>();
public static Guid Guids(Guids guidId)
{
if (!GuidList.ContainsKey(guidId))
{
string id = WebConfigurationManager.AppSettings[guidId.ToString()];
Guid newGuid;
if ( (id == null) || Guid.TryParse(id, out newGuid))
{
WebConfigurationManager.AppSettings[guidId.ToString()] = "NOTSet";
throw new Exception(String.Format("Invalid guid - not found in Config: {0}", guidId));
}
GuidList.Add(guidId, newGuid);
return newGuid;
}
return GuidList[guidId];
}
}
To save the web.config file you need to call Configuration.Save() to persist changes. They are not automatically saved when you change a value:
https://msdn.microsoft.com/en-us/library/ms134088%28v=vs.110%29.aspx
Writing to web.config on the fly is not really advisable anyway, for one thing it will cause the app pool to be restarted potentially resulting in loss of session state across your application and probably other application-wide things you don't want to happen.

C# - Load existing system environment variables when the current process don't have them loaded

On Windows, I have a C# assembly that is COM visible. It references other assemblies to control an application in the machine. It works fine.
However, under Apache Web Server and using CGI, it doesn't work. After doing some debuging, I found out that the problem is that, while running under Apache's CGI, the environment variables SYSTEMROOT and SYSTEMDRIVE, which aparently are needed by the referenced assemblies, are not loaded.
I can configure Apache to pass those environemtn variables too, but before doing so, I'd really like to know if there's some command I can put on my C# COM visible assembly to make it load environment variables as if it was, let's say, the SYSTEM user or something like that, so it doesn't have to relay on the environment passed by the starting application.
How do you force loading an existent system environment variable in C#, when IT IS NOT SET in the current process (or it was process-deleted by the launching process)?
Thanks in advance for any suggestions!
EDIT 1 - ADDED INFO: Just to make it more clear (as I see in the current answers it's not so clear): Apache intendedly deletes a lot of environment variables for CGI processes. It's not that Apache cannot see them, it can, but it won't pass them to CGI processes.
This should do the trick:
Environment.GetEnvironmentVariable("variable", EnvironmentVariableTarget.Machine);
I did a small test and it is working:
//has the value
string a = Environment.GetEnvironmentVariable("TMP");
Environment.SetEnvironmentVariable("TMP", null);
//does not have has the value
a = Environment.GetEnvironmentVariable("TMP");
//has the value
a = Environment.GetEnvironmentVariable("TMP", EnvironmentVariableTarget.Machine);
SOLUTION: Marco's answer was great and technically answered my question - except that I found out that the environment variables SYSTEMROOT and SYSTEMDRIVE are not really set in the registry where all environment variables are set, so, the chosen answer works for all variables except those two, which I specified in the OP.
SYSTEMROOT is defined on the registry in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRoot, and apparently (after more research), SYSTEMDRIVE is generated as a substring of SYSTEMDRIVE.
So, to get SYSTEMDRIVE and SYSTEMROOT from registry and load them into the environment:
using Microsoft.Win32;
namespace MySpace
{
public class Setup
{
public Setup()
{
SetUpEnvironment();
}
private void SetUpEnvironment()
{
string test_a = Environment.GetEnvironmentVariable("SYSTEMDRIVE", EnvironmentVariableTarget.Process);
string test_b = Environment.GetEnvironmentVariable("SYSTEMROOT", EnvironmentVariableTarget.Process);
if (test_a == null || test_a.Length == 0 || test_b == null || test_b.Length == 0)
{
string RegistryPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
string SYSTEMROOT = (string) Registry.GetValue(RegistryPath, "SystemRoot", null);
if (SYSTEMROOT == null)
{
throw new System.ApplicationException("Cannot access registry key " + RegistryPath);
}
string SYSTEMDRIVE = SYSTEMROOT.Substring(0, SYSTEMROOT.IndexOf(':') + 1);
Environment.SetEnvironmentVariable("SYSTEMROOT", SYSTEMROOT, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("SYSTEMDRIVE", SYSTEMDRIVE, EnvironmentVariableTarget.Process);
}
}
}
}
Then you can just call Setup setup = new Setup(); from other classes. And that's it. :-)
Environment.GetEnvironmentVariable
see reference here.
e.g.
Environment.CurrentDirectory = Environment.GetEnvironmentVariable("windir");
DirectoryInfo info = new DirectoryInfo(".");
lock(info)
{
Console.WriteLine("Directory Info: "+info.FullName);
}
Are the variables set as system wide?
If they are not, that is what you need to do, otherwise create user variables for the user the COM is running under.
Thank you. I cannot state with any certainty that this has once and for all driven a stake through the heart of the vampire, but amazingly enough, the error has disappeared (for now). The odd thing is that access to the statement
Environment.GetEnvironmentVariable("variable", EnvironmentVariableTarget.Machine);
is a real oddity in the debugger. It does not show up in Intellisense and does not even appear to fire, which leads me to suspect, which you all knew already, that this is some sort of magic runtime object Environment that has no instantiation in the debugger but also can be benignly jumped over. Oh well.
Oh and I should mention that after you see that error, you will note oddities in your Windows OS, which is worrisome. In particular, you will see, if you try to use the Control Panel /System/Advanced Properties (whatever) that it cannot load the dialog for the environment variables any more, indicating that %windir% has been seriously hosed (compromised) across all applications. Bad bad bad....

Visual Studio Custom Language Service

I am attempting to implement a Language Service in a VSPackage using the MPF, and it's not working quite as I understand it should.
I have several implementations already, such as ParseSource parsing the input file with a ParseRequest. However, when it finds an error, it adds it with AuthoringSink.AddError. The documentation for this implies it adds it to the Error List for me; it doesn't.
I also have a simple MySource class, a subclass of Source. I return this new class with an overridden LanguageService.CreateSource method. The documentation for OnCommand says it's fired 'when a command is entered'. However, it's not.
There's obviously some intermediate step which I haven't done correctly. I've already rambled enough, so I'll be glad to give any additional details by request.
Any clarification is much appreciated.
For the AuthoringSink error list question, I use this behavior in my Language Service. In ParseSource, the ParseRequest class has an AuthoringSink. You can also create a new ErrorListProvider if you want to work outside of the parser's behavior. Here is some example code:
error_list = new ErrorListProvider(this.Site);
error_list.ProviderName = "MyLanguageService Errors";
error_list.ProviderGuid = new Guid(this.errorlistGUIDstring.);
}
ErrorTask task = new ErrorTask();
task.Document = filename;
task.CanDelete = true;
task.Category = TaskCategory.CodeSense;
task.Column = column;
task.Line = line;
task.Text = message;
task.ErrorCategory = TaskErrorCategory.Error;
task.Navigate += NavigateToParseError;
error_list.Tasks.Add(task);
I hope this was helpful.
OnCommand should be firing every time there is a command, in your MySource class you can do something like this (pulled from working code):
public override void OnCommand(IVsTextView textView, VsCommands2K command, char ch)
{
if (textView == null || this.LanguageService == null
|| !this.LanguageService.Preferences.EnableCodeSense)
return;
if (command == Microsoft.VisualStudio.VSConstants.VSStd2KCmdID.TYPECHAR)
{
if (char.IsLetterOrDigit(ch))
{
//do something cool
}
}
base.OnCommand(textView, command, ch);
}
If that doesn't work double check that CodeSense = true in your ProvideLanguageService attribute when you setup your LanguageService package. A whole lot of what is cool to do in the LanguageService requires these attributes to be correctly turned on. Some even give cool behaviors for free!
Another thing to be careful of is that some behaviors like colorizer don't function correctly in the hive in my experience. I don't think these were ones that gave me trouble, but I implemented these a couple of years ago so I'm mostly just looking back at old code.
AuthoringSink.AddError only adds errors to the error list if ParseRequest.Reason is ParseReason.Check. When your ParseSource function attempts to add errors while parsing for any other ParseReason, nothing will happen.
It's possible that your language service is never calling ParseSource with this ParseReason. As far as I know, the only way to get a ParseReason of Check (outside of manually calling BeginParse or ParseSource yourself) is to proffer your service with an idle timer.

NUnit is not failing test with dynamic keyword of .Net 4.0

I am using NUnit with Visual Studio Express Edition 2010 for C#, Now, normally test works fine. But whenever I try to use Massive.cs, which is open source api to access database. Test fails from that file only. Now, if I run the application, api is working fine. I have created a different library file to access data base.
I seriously don't understand the error. It is just giving error that object reference is not set to an object. But if I run the code, it works fine. I am using dynamic keyword as shown in link of api above. Does that making problem with NUnit ?
Is there any other way to test in this type of Scenarios?
Here are the further details of the code,
Test class is like this
dynamic item = new Item();
item.Insert(new { Name = "Maggi", Description = "Its 2 Min Nuddles", IsDelete = false });
var items = item.All();
Assert.AreEqual("Maggi", items.FirstOrDefault().Name);
Now, I have put test here. Which gives error like shown in image,
Now if I run code in console application, then code is working fine, code snippet is given below
dynamic item = new Item();
item.Insert(new { Name = "Maggi", Description = "Its 2 Min Nuddles", IsDelete = false });
var result = item.All();
foreach (var i in result)
{
Console.WriteLine(i.Name + i.Description);
}
Console.Read();
Here, code is working and same thing is not working with NUnit Test. Please have a look and help me out. Please let me know if any further information is needed from my side.
Most probable explanation is that you haven't set up your connection string in the test project.
If you are using NUnit, just put it in app.config of your test project.
Solved... There is a issue with NUnit Testing. It was not taking config file pefectly. So, I made two changes. Changes I have done in Project setting.
First change is to change Application Base to bin\debug just give application base as this and then config file to .config to .exe.config and things are up and running. :)

Categories

Resources