Problems with settings file depending on configuration (debug, release) - c#

I'm now localizing my WPF application and there is this little piece of code in the constructor of the MainWindow:
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(Settings.Default.Language);
It crashes right after I start it, saying:
XmlParseException:{"'The invocation of the constructor on type 'Program.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'."}
its inner: CultureNotFoundException: Culture is not supported. Parameter name: nameen-UK is an invalid culture identifier.
Now I know that there is no such a culture name as en-UK. I just typed it once by accident... I thought there was.
Now everything contains: en-GB. (settings, appconfig, etc.)
Steps I have done:
restart devenv
delete all the bin and obj folders.
search in the entire solution for the expression: "en-UK" (with and without case sensitivity)
search with total commander for "asterisk dot asterisk" containing the text: "en-UK" (with and without case sensitivity)
no results...
Then I put a breakpoint into the constructor and the
Settings.Default.Language
has the value "en-UK".
The point: everything works fine in release mode. It occurs only in Debug mode. How is this possible?
in release mode, the Settings.Default.Language has the en-GB value (which is fine).
Have you met this problem before? Is it a Visual Studio bug or did I go mad? Thank you.

in Visual Studio the debug mode or the release mode each one have a separated config file;
so when you debug with Debug config the old config info still registered;
try to make like this in the constructor:
Setting.Default.Reset();
if this not help you please post some code for more detail.

Related

C# console application not running stand-alone after being published

I'm rather new to C# and Visual Studio.
The problem I have is after I publish my C# console app in Visual Studio. The console app is not handling the augments correctly and is throwing an error.
I have setup a few Launch Profiles to test out how the console app will behave with different arguments. They all pass and give me the expected results when I run the Debug and Release Profiles.
However, when I go to publish and I select self-contained and select Produce single file. (Published Profile Settings.) The app no longer works as expected.
I get the following error:
Generic Exception Handler: System.ArgumentNullException: Value cannot be null. (Parameter 'paths')
at System.IO.Path.Combine(String[] )
at AMP_New_Project.AMP_New_Project_Folder.Main(String[] args) in C:\Users\eriskedahl\Documents\GitHub\JMS\NewAMP_Proj_Console\AMP_New_Proj.cs:line 135
PS C:\Users\erisk\Documents\GitHub\JMS\NewAMP_Proj_Console\Releases>
Now the error itself is fine and looks like my the exception handling is working, but I have a debug profile to check this and the path is allowed to be null. There is an if statement to handle what happens when a path argument is not supplied.
if (strWorkPath == null || strWorkPath.Length == 0)
{
strWorkPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)!;
}
It seems the console app is not self-contained and is missing some references but not sure where else to check. Why would the app behave differently after being published?
When I run debug, and no path is given, the the variable strWorkPath is null and then gets set to the console app's current working directory.
As mentioned this works completely fine and as expected when I run the app through the debug in Visual Studio, I only get this error when I run the published version. If I open a Powershell or cmd window and go to the Bin/Release folder and run the application from there I also get the expected results. The App fails once I copy the exe file to a different folder.
When publishing as a single file, the build system bundles all of the assemblies which make up your application together.
The Assembly.Location docs say:
In .NET 5 and later versions, for bundled assemblies, the value returned is an empty string.
So we're passing an empty string to Path.GetDirectoryName, which says:
Directory information for path, or null if path denotes a root directory or is null.
So that's probably what's happening: Assembly.Location returns an empty string, because the assembly has been bundled together with a load of other assemblies as part of the publish, and Path.GetDirectoryName turns that into null.
To get the application's location in a way which supports bundling, use AppDomain.CurrentDomain.BaseDirectory.
Note that this is not the current working directory. The CWD is the directory that the user is in when they run your application. It's normally assumed that if the user passes a relative path to your application (e.g. as a command-line argument), the application should interpret that as relative to the user's CWD.
Problem is not that you are using self-contained deployment but that you also using single-file deployment (one of the checkboxes).
Docs for single-file deployment and executable mention that some Assembly APIs will not work in single-file deployment mode, including the Location, which will return an empty string:
API
Note
Assembly.CodeBase
Throws System.PlatformNotSupportedException.
Assembly.EscapedCodeBase
Throws System.PlatformNotSupportedException.
Assembly.GetFile
Throws System.IO.IOException.
Assembly.GetFiles
Throws System.IO.IOException.
Assembly.Location
Returns an empty string.
AssemblyName.CodeBase
Returns null.
AssemblyName.EscapedCodeBase
Returns null.
Module.FullyQualifiedName
Returns a string with the value of <Unknown> or throws an exception.
Marshal.GetHINSTANCE
Returns -1.
Module.Name
Returns a string with the value of <Unknown>.
Which leads to Path.GetDirectoryName returning null.
There are some workarounds mentioned:
To access files next to the executable, use System.AppContext.BaseDirectory
To find the file name of the executable, use the first element of System.Environment.GetCommandLineArgs, or starting with .NET 6, use the file name from System.Environment.ProcessPath.
To avoid shipping loose files entirely, consider using embedded resources.
So you can use System.AppContext.BaseDirectory to determine the directory.

DirectoryInfo throwing a System.OverflowException

When I construct a new DirectoryInfo using a network path like this:
using Delimon.Win32.IO;
DirectoryInfo di = new DirectoryInfo(#"\\a\path\to\a\place\you\are\not\allowed\to\know")
I know the path is correct since it opens in my browser when I copy paste. But I am getting an error:
"System.OverflowException: Arithmetic operation resulted in an overflow."
This is all the call stack info I can give.
System.OverflowException: Arithmetic operation resulted in an overflow.
at Delimon.Win32.IO.Helpers.GetFileInformation(String path)
at Delimon.Win32.IO.FileSystemInfo.Refresh()
at Delimon.Win32.IO.DirectoryInfo..ctor(String dir)
The path is 67 characters long. So its not a long path.
I can't find any documentation on System.OverflowException resulting from the construction of DirectoryInfo objects.
Any help?
I was getting this exact error just now
System.OverflowException: 'Arithmetic operation resulted in an overflow.'
and managed to isolate the cause.
The following line was giving the error:
string[] files = Delimon.Win32.IO.Directory.GetFiles(#"d:\temp");
This line is from an old app that I'm rewriting. Knowing that it works in the old version, but not in the new version, I've removed everything and everything in the new version and was left with an empty form. I still got the error.
Then I created a new empty project and tried the code in it, and it worked. So even though I removed everything in my new app, I still get the error. This suggests there's something wrong with the settings. So I started comparing project files.
In the *.csproj file, there was this line:
<Prefer32Bit>false</Prefer32Bit>
and it was not in the old app nor in the new project.
It seems that when a new project is created, "Prefer 32-bit" (Project -> Properties -> Build -> General) is checked by default, but in my new app, this was not checked. I don't remember unchecking it myself, so I don't know how it got unchecked. Once I checked it, I no longer get the error.
I was using Delimon.Win32.IO.DirectoryInfo which is apparently an old, un-maintained code base. I should have been using System.IO.DirectoryInfo

Obtaining full nUnit output in visual studio online

I have set up my VS 2013 environment to integrate with TFS in Visual Studio Online. I have configured a CI build to run and then run all my tests (nUnit framework) upon completion. However when the tests complete and I see the output it only says whether each test passed or failed, not the details of the assert statements I call in code, ie what error actually happened.
So it will say
GetPosMenus failed
But if I run the test locally in VS2013 I see the full error
GetPosMenus failed
Initialization method Data.Test.PosMenuDataRepositoryTests.LoadData threw exception. System.ArgumentOutOfRangeException: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index.
at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at System.Collections.Generic.List`1.get_Item(Int32 index)
at Testing.Shared.DataPopulation.Pos.PosMenuDataPopulator.LoadPosMenusIntoDatabase(IUnitOfWork work, IList`1 data, IList`1 venues) in PosMenuDataPopulator.cs: line 48
at5 Data.Test.PosMenuDataRepositoryTests.LoadData() in PosMenuDataRepositoryTests.cs: line 50
How can I configure the online build engine to give me the full output?
You can view this in your account in VSO online and within Visual Studio.
In VS:
Team Explorer Home -> Builds
Under All Build Definitions double-click the build definition you are interested in.
This should open a tab containing a history of completed builds. The default history is set to Today, you will need to change the Date Filter to see older builds. Note also that the visible build history will depend on the retention policy you have set in the build definition.
Double-click your build and you should see the following screen. Expand the test results and the exception should be visible

MonoGame - Error 9009 & IgnoreMe.dll not found

i've just installed MonoGame and XNA and i'm having some issues from the jump, from googling it seems as though i need to add 'C:\Windows\System32' to my path environment variables, i've tried adding it here
but i'm still getting these errors
Error 1
The command "SETX MONOGAME_PLATFORM "PSM" > NUL" exited with code 9009. MyMonoGameContent
Error 2
Metadata file 'C:\Users\Benji\documents\visual studio 2013\Projects\myMonoGame\MyMonoGameContent\MyMonoGameContent\bin\PSM\IgnoreMe.dll' could not be found C:\Users\Benji\documents\visual studio 2013\Projects\myMonoGame\myMonoGame\CSC myMonoGame
This happens when i try to compile after referencing my content project
i'm following these http://rbwhitaker.wikidot.com/monogame-tutorials
no idea what's up, was that the wrong place to set the enviroment variable? i've tried looking for a user property sheet but can't find one in my project
I wouldn't expect that you would want to create content for the PSM (PlayStation Mobile). Check the targeted platform of the ContentBuilder project to ensure you are building for Windows.

Powershell, Service Bus For Windows Server Programmatically: Command found, module could not be loaded

From C# code I'm trying to retrieve all the namespaces from powershell... (Later more complex things, like creating namespaces)
PowerShell ps = PowerShell.Create();
ps.AddCommand("Import-Module").AddArgument("ServiceBus").Invoke();
var result = ps.AddCommand("Get-SBNamespace").Invoke();
Above code gives the following exception:
The 'Get-SBNamespace' command was found in the module 'ServiceBus',
but the module could not be loaded. For more information, run
'Import-Module ServiceBus'.
Does anyone know how to solve this error?
CURRENT STATUS: after some debugging I've found that no modules are loaded by default in the PowerShell object. Using the code:
InitialSessionState iss = InitialSessionState.CreateDefault();
iss.ImportPSModule(new string[]{#"serviceBus"});
PowerShell ps = PowerShell.Create(iss);
doesn't work to load the service bus module. Also the code:
ps.AddCommand("Import-Module").AddParameter("-Name", "serviceBus").Invoke();
doesn't work to import the service bus module. Running Visual Studio in administrator mode also doesn't make a difference
Thanks in advance
You didn't say which version of Visual Studio you're using. If it's VS 2012, when you tried the x64 platform target did you make sure that "Prefer 32-bit" was not checked? Even if it was not checked try checking it, saving the project configuration, clearing it and saving again - this worked for me on another project.
UPDATE
It's been suggested elsewhere that there's a bug in VS2012 that shows "Prefer 32-bit" as greyed-out and unchecked when it's actually active. I'm running Update 2 and I don't see that. But it sounds like you might be. I suggest you edit the .csproj file directly.
Whilst "Platform Target" is set at "Any CPU", in Solution Explorer, right-click on the Project name (or, with go to the PROJECT menu) and select "Unload Project". Project files will close and Solution Explorer will display project name (unavailable) > The project file was unloaded:
Right-click on the Project name again and select "Edit project name.csproj". The file is XML and mostly comprises PropertyGroup and ItemGroup elements. In a console project, the first PropertyGroup usually contains a Platform element which should read AnyCPU if you followed my instructions above. The next two PropertyGroups are normally for Debug and Release configurations. If you've added another configuration, it will have its own PropertyGroup. In each of these, look for an element which reads:
<Prefer32Bit>true</Prefer32Bit>
What you should have is an element which reads:
<Prefer32Bit>false</Prefer32Bit>
Either change it or insert it (in each configuration ProjectGroup), save the file and close it. Back in Solution Explorer, right-click the project and select "Reload Project". Let me know if that solves it. You can confirm your PowerShell is now running 64-bit by get the result of
[System.IntPtr]::Size
e.g.
ps.AddScript("[System.IntPtr]::Size");
which will be 4 in an x86 process and 8 in an x64 process.
Which my project set up like this, I was able to load ServiceBus using:
ps.AddCommand("Import-Module").AddArgument("ServiceBus");
Hopefully, you will, too.
I don't have ServiceBus installed so I can't verify exactly what you've tried but
ps.AddCommand("Import-Module").AddArgument("ActiveDirectory").Invoke();
worked for me, so your original syntax looks good.
Just to test for failure, I tried:
ps.AddCommand("Import-Module").AddArgument("CheeseDirectory");
ps.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
var importResult = ps.Invoke();
foreach (PSObject result in importResult)
{
Console.WriteLine(result);
}
and got
The specified module 'CheeseDirectory' was not loaded because no valid
module file was found in any module directory.
Have you tried similar?
Do you take care of your Assembly target in your C# program (x86 versus X64). The module may exist in one target, not in the other. PowerShell exists in both.
Seems you're trying to import some modules and execute the cmdlet or function inside the module, right?
So I think you could try the following code:
PowerShell ps = PowerShell.Create();
Assembly ass = Assembly.LoadFile(#"yourServiceBus.dll");
ps.AddCommand("Import-Module").AddParameter("Assembly", ass).Invoke();
var result = ps.AddCommand("Get-SBNamespace").Invoke();
Hope this could help.

Categories