C# Unreachable code detected - c#

I'm getting a "Unreachable code detected" message in Visual Studio at the point i++ in my code below. Can you spot what I've done wrong?
try
{
RegistryKey OurKey = Registry.CurrentUser;
OurKey.CreateSubKey("Software\\Resources\\Shared");
OurKey = OurKey.OpenSubKey("Software\\Resources\\Shared", true);
for (int i = 0; i < cmbPaths.Items.Count; i++) //<---- problem with i
{
OurKey.SetValue("paths" + i, cmbPaths.Items[i]);
break;
}
}

The problem is that this actually isn't a loop. You don't have any condition on the break so you could equivalently write something like
if(cmbPath.Items.Count > 0)
{
OurKey.SetValue("paths" + 0, cmbPaths.Items[0]);
}
Alternatively you have to correct with something like
for (int i = 0; i < cmbPaths.Items.Count; i++)
{
OurKey.SetValue("paths" + i, cmbPaths.Items[i]);
if(someConditionHolds)
break;
}

You're breaking out of the loop before the end of the first iteration.

The problem is that because you break; in the loop with no chance of it doing anything else, the increment of i (i++) will never be reached.

Although your problem is solved i need to tell you this,
you can just using the CreateSubKey() method for your purpose. I think It's a better choice.
:)
//Creates a new subkey or opens an existing subkey for write access.
var ourKey = Registry.CurrentUser.CreateSubKey("Software\\Resources\\Shared");

You can also end up getting unreachable code if you use say for example Entity Framework, and you didn't add that reference to that project.
Say you have several projects like A Data Layer Project, a Domain Classes, then you create a console app for testing or whatever and you reference where your dbcontext is at, but if you don't use say nuget and add in EF, you will get code unreachable when trying to write a loop etc...

Related

"The process cannot access the file because it is being used by another process." with SystemReader

I have no coding experience but have been trying to fix a broken program many years ago. I've been fumbling through fixing things but have stumbled upon a piece that I can't fix. From what I've gathered you get Alexa to append a Dropbox file and the program reads that file looking for the change and, depending on what it is, executes a certain command based on a customizable list in an XML document.
I've gotten this to work about five times in the hundred of attempts I've done, every other time it will crash and Visual Studio gives me: "System.IO.IOException: 'The process cannot access the file 'C:\Users\\"User"\Dropbox\controlcomputer\controlfile.txt' because it is being used by another process.'"
This is the file that Dropbox appends and this only happens when I append the file, otherwise, the program works fine and I can navigate it.
I believe this is the code that handles this as this is the only mention of StreamReader in all of the code:
public static void launchTaskControlFile(string path)
{
int num = 0;
StreamReader streamReader = new StreamReader(path);
string str = "";
while (true)
{
string str1 = streamReader.ReadLine();
string str2 = str1;
if (str1 == null)
{
break;
}
str = str2.TrimStart(new char[] { '#' });
num++;
}
streamReader.Close();
if (str.Contains("Google"))
{
MainWindow.googleSearch(str);
}
else if (str.Contains("LockDown") && Settings.Default.lockdownEnabled)
{
MainWindow.executeLock();
}
else if (str.Contains("Shutdown") && Settings.Default.shutdownEnabled)
{
MainWindow.executeShutdown();
}
else if (str.Contains("Restart") && Settings.Default.restartEnabled)
{
MainWindow.executeRestart();
}
else if (!str.Contains("Password"))
{
MainWindow.launchApplication(str);
}
else
{
SendKeys.SendWait(" ");
Thread.Sleep(500);
string str3 = "potato";
for (int i = 0; i < str3.Length; i++)
{
SendKeys.SendWait(str3[i].ToString());
}
}
Console.ReadLine();
}
I've searched online but have no idea how I could apply anything I've found to this. Once again before working on this I have no coding experience so act like you're talking to a toddler.
Sorry if anything I added here is unnecessary I'm just trying to be thorough. Any help would be appreciated.
I set up a try delay pattern like Adriano Repetti said and it seems to be working, however doing that flat out would only cause it to not crash so I had to add a loop around it and set the loop to stop when a variable hit 1, which happened whenever any command types are triggered. This takes it out of the loop and sets the integer back to 0, triggering the loop again. That seems to be working now.

How to access sys.stderr after calling PyErr_Print with python c-api

I am trying to use the python c-api from a c# project via dll import.
I am getting an ModuleNotFoundError when importing some modules, which I thought are builtin.
(Note: I compiled python myself)
I am a bit stuck right now, but my hope is to get some extra information when calling PyErr_Print() in the code below.
Code:
IntPtr modulePtr = NativeInterface.PyImport_ExecCodeModuleEx(moduleName,compiledModule, path);
if (modulePtr == IntPtr.Zero)
{
NativeInterface.PyErr_Print();
PythonException exception = PythonException.Query();
throw exception;
}
The docs for PyErr_Print state that it will populate sys.stderr with some error information.
What would be the easiest way to read this variable from my c# application?
This answer gives C code because I understand C and not C#, but I think it should be pretty transferable.
By default sys.stderr writes to some console somewhere and so you can't meaningfully try to read from it. However, it's perfectly possible to replace it to redirect the output. Two sensible options include writing to a file, and writing to a StringIO object that can later be queried.
The C code to run is basically equivalent to:
import sys
from io import StringIO # Python 3
sys.stderr = StringIO()
or in C:
int setup_stderr() {
PyObject *io = NULL, *stringio = NULL, *stringioinstance = NULL;
int success = 0;
io = PyImport_ImportModule("io");
if (!io) goto done;
stringio = PyObject_GetAttrString(io,"StringIO");
if (!stringio) goto done;
stringioinstance = PyObject_CallFunctionObjArgs(stringio,NULL);
if (!stringioinstance) goto done;
if (PySys_SetObject("stderr",stringioinstance)==-1) goto done;
success = 1;
done:
Py_XDECREF(stringioinstance);
Py_XDECREF(stringio);
Py_XDECREF(io);
return success;
}
You run this once at the start of your program.
To query the contents of sys.stderr you'd then do the equivalent of:
value = sys.stderr.getvalue()
encoded_value = value.encode() # or you could just handle the unicode output
In C:
char* get_stderr_text() {
PyObject* stderr = PySys_GetObject("stderr"); // borrowed reference
PyObject *value = NULL, *encoded = NULL;
char* result = NULL;
char* temp_result = NULL;
Py_ssize_t size = 0;
value = PyObject_CallMethod(stderr,"getvalue",NULL);
if (!value) goto done;
// ideally should get the preferred encoding
encoded = PyUnicode_AsEncodedString(value,"utf-8","strict");
if (!encoded) goto done;
if (PyBytes_AsStringAndSize(encoded,&temp_result,&size) == -1) goto done;
size += 1;
// copy so we own the memory
result = malloc(sizeof(char)*size);
for (int i = 0; i<size; ++i) {
result[i] = temp_result[i];
}
done:
Py_XDECREF(encoded);
Py_XDECREF(value);
return result;
}
There's a bit of effort spent copying the string. You might consider working directly with unicode and using PyUnicode_AsUCS4Copy.
You probably then want to look at clearing the string after you've written it, just done by replacing sys.stderr with a fresh StringIO object.
I could not find a way to acces sys.stderr via C-Api. But I realized that I can run python scripts via the c-api (See PyRun_String in the docs).
So I am debugging now by writing sys.path to a textfile.
import sys
file = open('log.txt','w')
for path in sys.path:
file.write(i+'\n')

Cosmos custom OS, addmapping?

I am new to C# and is currently using COSMOS to make a simple FileSystem for my OS class. Currently I'm trying to implement a "reformat" function that, when the word "reformat" is typed into the console, the OS (emulated via QEMU), partitions the disk. Currently this is my code:
public static void console()
{
while (true)
{
Console.WriteLine("Console: ");
String input = Console.ReadLine();
if (input == "exit")
{
Cosmos.Sys.Deboot.ShutDown();
}
else if (input == "cpumem")
{
Console.WriteLine(Cosmos.Kernel.CPU.AmountOfMemory.ToString());
}
else if (input == "restart")
{
Cosmos.Sys.Deboot.Reboot();
}
else if (input == "devices")
{
var devices = Cosmos.Sys.FileSystem.Disk.Devices.ToArray();
}
else if (input == "reformat")
{
try
{
Partition part = null;
for (int j = 0; j < Cosmos.Hardware.BlockDevice.Devices.Count; j++)
{
if (Cosmos.Hardware.BlockDevice.Devices[j] is Partition)
{
part = (Partition)Cosmos.Hardware.BlockDevice.Devices[j];
}
}
var fs = new Cosmos.Sys.FileSystem.FAT32.FAT32(part);
uint cluster = 100;
fs.Format("newCluster", cluster);
}
catch
{
//Do Something warn user.
}
}
}
}
Most important is this bit:
else if (input == "reformat")
{
try
{
Partition part = null;
for (int j = 0; j < Cosmos.Hardware.BlockDevice.Devices.Count; j++)
{
if (Cosmos.Hardware.BlockDevice.Devices[j] is Partition)
{
part = (Partition)Cosmos.Hardware.BlockDevice.Devices[j];
}
}
var fs = new Cosmos.Sys.FileSystem.FAT32.FAT32(part);
uint cluster = 100;
fs.Format("newCluster", cluster);
}
catch
{
//Do Something warn user.
}
}
Which is analogous to what is located here: http://cosmos-tutorials.webs.com/atafat.html
However, when I run it, I get this error:
I believe this is because I lack this line:
Cosmos.System.Filesystem.FileSystem.AddMapping("C", FATFS);
FATFileList = FATFS.GetRoot();
Located in the link above. Is there any other way to map? Or am I missing something completely? The COSMOS documentation doesn't really tell much, the source code is honestly confusing for a beginner like me as it has no comments whatsoever on how the functions work or what they do. I am using an older version of COSMOS (Milestone 4) as it's the only one that works for Visual Studio C# 2008. Newer versions run only in Visual Studio C# 2010.
Ah, I recognize this... had to debug a similar situation on a Cosmos project I'm working on myself (I'm using the VS2010-compatible Cosmos but the same situation might apply to older versions as well...)
This can happen if you try to call a method on a null object. Type 0x........, Method 0x........ is specifically mentioning the location in the compiled code where the call failed. "Not FOUND!" means that the method it is looking for cannot be found, presumably because you called it on a null reference.
I'm testing with VirtualBox myself, and found that if you're using a brand-new blank hard disk image, there will be no Partitions on it. Thus, the condition will never get satisfied, your Partition will never get set and then Cosmos will try to execute a method on the null Partition!
Look closely at how you set the Partition (it's initialized to null). For starters I would print a simple message each time the "if (block device is partition)" condition is satisfied... I would be willing to bet it will never print.
Hope this helps... I am still learning about Cosmos and custom kernels myself but fixing the null reference in my case solved my occurrence of the problem. If that's the problem, then the next step, of course, is figuring out why you're not getting any Partitions in the first place...
The rest of your code looks fine but I am not sure how you implemented the rest of your classes. Kernel debugging can be a nightmare, good luck to you!

Throw exception if more than one file in a folder

Below is the snippet of code I'm using to count the files in a folder (just files, not additional folders). If there is more than one file in this folder I need to throw an exception.
private bool CheckCondition2(String FolderName)
{
bool ConditionPassed = false;
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(FolderName);
int count = dir.GetFiles().Length;
ConditionPassed = (count > 1);
return ConditionPassed;
}
I then call it in main with:
if (!CheckCondition2(SourceFolder))
{
CanCopy = false;
throw new Exception("More than one mark-off file.");
}
Currently when I test it, it tells me there is more than one file in the directory despite there only being one. What have I done wrong in my code?
In your method, you return true if there are more than one files.
In your if-statement, you check for false, however. You seem to have mixed these up a little.
It's always a good idea to debug your code and follow the value as it changes to see if you've got any logic-errors. A more automatic and reliable way to do this is, of course, writing a unit test.
You could switch the condition in your method, to be
ConditionPassed = (count <= 1);
That way, it means that the method would return true when you're in a 'correct' state. You could instead change the if-statement to read
if (CheckCondition2(SourceFolder))
Either would probably work for you. In the latter example, I would also suggest changing the name of the method to something like HasMoreThanOneFile to make it abundantly obvious what it does.
Try this:
ConditionPassed = (count <= 1); //check should pass if there is at most one file
Either change the condition
ConditionPassed = (count <= 1);
or the if statement
if (CheckCondition2(SourceFolder)))
I presume your success scenario is to be at most 1 files in the source folder
Instead of using a bool, why not try...
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(FolderName);
int count = dir.GetFiles().Length;
if (count > 1)
{
throw new Exception("More than one mark-off file.");
}
else
{
// Something else
}
Its a bit neater code (Sorry the OCD is kicking in!)
I think there's a flaw in your logic. ConditionPassed = (count > 1) should be ConditionPassed = (count <=1). Hope this help!
Please try debugging your code.
It just worked after making a small change in the if statement, it should have been if (CheckCondition2(SourceFolder))
Try updating name of the function to avoid confusion.

How to set a PreSharedKey in a RasEntry on Windows CE / Compact Framework?

Since I really don't get any progress in the last hours I need to consult you for a problem which I don't get solved.
We have a Win CE 5.0 application, written C#/Compact Frmaework 2.0 that uses RASDial to Dial into a VPN. Currently it uses PPTP but I have to change it to L2TP with a Pre Shard Key. But to be honest I have no experience in C++ and I really understand only half of the code or to be more clear I don't understand the RAS Api and Documentation in the MSDN.
I understand how to create this L2PT RAS Entry and how to Dial it but in no way I understand where and how to set the Pre Shared Key!
I found a peace of code that seems to do the same things our code does in priciple but on the Website/Board I found it the Author says this is with pre shared key but to be honest, I don't get where the key is.
(...)
// Device configuration for L2TP VPN
if (bIsL2TP) {
DWORD cbKey = 0;
if (g_sharedKey) {
cbKey = (wcslen(g_sharedKey))*sizeof(WCHAR);
}
pL2TPConfigData = (PL2TP_CONFIG_DATA)new BYTE
[sizeof(L2TP_CONFIG_DATA)+ cbKey];
ZeroMemory(pL2TPConfigData, sizeof(L2TP_CONFIG_DATA)+ cbKey);
pL2TPConfigData->dwVersion = 1;
pL2TPConfigData->dwAuthType = L2TP_IPSEC_AUTH_PRESHAREDKEY;
pL2TPConfigData->dwFlags = 0;
pL2TPConfigData->cbKey = cbKey;
pL2TPConfigData->dwOffsetKey = sizeof(L2TP_CONFIG_DATA);
pL2TPConfigData->cMyCerts = 0;
pL2TPConfigData->cRootCerts = 0;
pL2TPConfigData->dwOffsetCertHashes = sizeof(L2TP_CONFIG_DATA);
if (g_sharedKey) {
memcpy((PBYTE)pL2TPConfigData+pL2TPConfigData->dwOffsetKey,
g_sharedKey, cbKey);
}
pConfigData = (PBYTE)pL2TPConfigData;
cbConfigData = sizeof(L2TP_CONFIG_DATA) + cbKey;
}
(...)
// Create a new phone-book entry.
res = ::RasSetEntryProperties(NULL, g_entryName, &rasEntry, sizeof
(rasEntry), pConfigData, cbConfigData);
if (res != 0) {
wprintf(L"Cannot create or update the phone book entry (error# %u).
Aborting.", res);
goto exit;
}
In the code the Length (cbKey) of the key is determined but can someone explain to me where the actual key is in the code? Or can someone provide me an explaination on how to set a Pre Shared Key in RASEntry for L2TP?
Thank you so much
twickl
The pre-shared key is copied into the L2TP_CONFIG_DATA structure with this line:
memcpy((PBYTE)pL2TPConfigData+pL2TPConfigData->dwOffsetKey, g_sharedKey, cbKey);
Basically this line says "copy the data from g_sharedKey into the pL2TPConfigData instance, starting at an offset of pL2TPConfigData->dwOffsetKey for a length of cbKey"
The code wraps this in an if block, so if g_sharedKey is NULL, it doesn't do this copy.

Categories

Resources