3

Im making a program that makes a Wi-Fi hotspot for you and enables Internet Connection Sharing automaticly using a powershell script.

The script works and runs perfectly, but i have to wait for it to be finished so i can notify the user its done. Im using below code which works but...

but it crashes and causes an error on my home computer which is allot faster. I get a Cannot read or write or memory is corrupt error which i can't really explain.

public static void ToggleIcs(string connectionInterface, bool state)
    {
        string toggle;
        string par1;
        string par2;
        if (state){
            toggle = "EnableSharing";
            par1 = "0";
            par2 = "1";
        }else{
            toggle = "DisableSharing";
            par1 = "";
            par2 = "";
        }
        using (PowerShell powerShellInstance = PowerShell.Create())
        {
            // this script enables or disables internet sharing with the connectionInterface given.
            powerShellInstance.AddScript("" +
                "regsvr32 hnetcfg.dll /s;" +
                "$m = New-Object -ComObject HNetCfg.HNetShare;" +
                "$m.EnumEveryConnection |% { $m.NetConnectionProps.Invoke($_) };" +
                "$c = $m.EnumEveryConnection |? { $m.NetConnectionProps.Invoke($_).Name -eq '" + connectionInterface + "' };" +
                "$config = $m.INetSharingConfigurationForINetConnection.Invoke($c);" +
                "Write-Output $config.SharingEnabled;" +
                "Write-Output $config.SharingConnectionType;" +
                "$config." + toggle + "(" + par1 + ");" +

                "$m2 = New-Object -ComObject HNetCfg.HNetShare;" +
                "$m2.EnumEveryConnection |% { $m2.NetConnectionProps.Invoke($_) };" +
                "$c2 = $m2.EnumEveryConnection |? { $m2.NetConnectionProps.Invoke($_).DeviceName -Match 'Microsoft Hosted Network Virtual Adapter' };" +
                "$config2 = $m2.INetSharingConfigurationForINetConnection.Invoke($c2);" +
                "Write-Output $config2.SharingEnabled;" +
                "Write-Output $config2.SharingConnectionType;" +
                "$config." + toggle + "(" + par2 + ");");


            PSDataCollection<PSObject> outputCollection = new PSDataCollection<PSObject>();
            IAsyncResult result = powerShellInstance.BeginInvoke<PSObject, PSObject>(null, outputCollection);
            Console.WriteLine(DateTime.Now + ">> Started Powershell script");

            int i = 0;
            while (!result.IsCompleted)
            {
                if (i < 60)
                {
                    Console.WriteLine(DateTime.Now + ">> Running script");
                }
                else
                {
                    ScriptFailed();
                    powerShellInstance.Stop();
                    break;
                }
                i++;
                Thread.Sleep(1000);
            }
            Console.WriteLine(DateTime.Now + ">> Executed Internet Sharing script");
        }
    }

This is the error im getting:

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

I don't get a line that says where it crashes but it crashes after Thread.Sleep(1000);. Which i found out using breakpoints

As I said, the script runs fine on my laptop, and it does work on my faster computer, but it crashes as soon as it hits Thread.Sleep(1000). After it crashed, I checked if ICS was enabled in the network and sharing center, and and it did so correctly.

I tried removing the Thread.Sleep(1000); but then it crashes anyway a line before.

What can I try or do differently?


Edit

i dont have the stack trace yet, as i am not on my faster PC where it crashes. but I will post it as soon as possible.


Edit

As mentioned by TheLethalCoder, it could be that i try to acces IsCompleted While it is being updated. If that is why it happens, How would I check if it is being altered or wait for it to be done.
Edit

As i dont really know what the call stack is for, or what a stack trace is, and how i can use it ill provide an image of what i saw one moment before the crash. Stack Trace


Edit I did some snooping around and found a few things i tried.

first, in the application properties -> build, i ticked "Prefer 32bit" off Because some people fixed their problems with this. And i did not get a crash but the script also failed to run and caused my internet connection to drop.
so i turned it back on. I also tried the netsh winsock reset command and restarting my pc but it still crashed.

Im all out of clues now, but i posted these two things for people who come by looking for an answer and maybe this will work.

12
  • What is the complete error (including stack trace)? Commented Jan 19, 2017 at 10:46
  • I can't get that yet because Im working right now and it works fine on this machine, but i will post it as soon as possible Commented Jan 19, 2017 at 10:54
  • Seeing as that error indicates something happened inside unsafe code and you are not using unsafe code I believe it is more to do with the script than the C# code. Commented Jan 19, 2017 at 10:54
  • @TheLethalCoder I ran the script on my faster machine line for line in Powershell without an error and it worked fine. Is there a difference in running it with C#? Commented Jan 19, 2017 at 10:57
  • Whenever I get an error like that it is because I am using pointers in C# in an unsafe context to access Bitmaps faster. You're C# code, as far as I can tell, isn't doing anything with pointers or in an unsafe context. That was all I was pointing out. But I don't know what the underlying classes you are using are doing so they could use some unsafe methods... Commented Jan 19, 2017 at 10:59

1 Answer 1

1

The MSDN article: Polling for the Status of an Asynchronous Operation states that the way you are polling the result is correct. However their example doesn't include a Thread.Sleep:

while (result.IsCompleted != true)
{
    UpdateUserInterface();
}

So to eliminate this I would use the following snippet that keeps track of the variables without sleeping, note that printing to the Console on every loop is going to quickly pollute the window though:

Stopwatch sw = new Stopwatch();
sw.Start();
while (!result.IsCompleted)
{
    if (sw.EllapsedMilliseconds >= 60000) //60 seconds
    {
        break;
    }

    Console.WriteLine(DateTime.Now + ">> Running script");
}

if (!result.IsCompleted)
{
    ScriptFailed();
    powerShellInstance.Stop();
}

This is more of a comment than an answer but it was getting too long to be used as a comment.

Sign up to request clarification or add additional context in comments.

2 Comments

It actually makes more sense to wait for it like this, because it runs better than Thread.Sleep(1000); because that blocks the thread. So thanks for this improvement, but I do know it didn't matter if I used Thread.Sleep() or not because it crashed even without it. Still very useful.
@Jeremy Like I said it's more of a comment than an answer but with all the markdown and it's length I couldn't really do that

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.