运行Powershell脚本会导致“内存损坏”或“无法读取或写入”

时间:2017-01-19 10:45:20

标签: c# powershell

我正在制作一个为您制作Wi-Fi热点的程序,并使用powershell脚本自动启用Internet连接共享。

脚本工作和运行完美,但我必须等待它完成,所以我可以通知用户完成。我使用下面的代码但是......

但它崩溃并导致我的家用电脑上的错误分配更快。 我得到一个无法读取或写入或内存是腐败的错误,我无法解释。

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");
        }
    }

这是我得到的错误:

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

我没有得到说明崩溃位置但在Thread.Sleep(1000);之后崩溃的行。我发现使用断点

正如我所说,我的笔记本电脑上的脚本运行正常,它可以在我的速度更快的计算机上运行,​​但是一旦它到达Thread.Sleep(1000)就会崩溃。 崩溃之后,我检查了网络和共享中心是否启用了ICS,并且它确实正确。

我尝试删除Thread.Sleep(1000);,但之前它仍然崩溃了。

我可以尝试或做些什么?

<小时/> 编辑

我还没有堆栈跟踪,因为我不在我崩溃的更快的PC上。但我会尽快发布。

<小时/> 编辑

正如TheLethalCoder所提到的那样,我可能会在更新时尝试访问IsCompleted。如果这就是它发生的原因,我将如何检查它是否被改变或等待它完成。
修改

因为我真的不知道调用堆栈是什么,或者堆栈跟踪是什么,以及我如何使用它生病提供了我在崩溃前一刻看到的图像。 Stack Trace


编辑 我做了一些窥探,发现了一些我尝试过的东西。

首先,在应用程序属性中 - &gt;建立时,我勾选了“Prefer 32bit”  因为有些人解决了这个问题。我没有遇到崩溃,但脚本也无法运行,导致我的互联网连接断开 所以我把它重新打开了。 我也尝试了netsh winsock reset命令并重新启动我的电脑,但它仍然崩溃了。

我现在全都没有线索了,但是我把这两件事发布给那些来寻找答案的人,也许这会有效。

1 个答案:

答案 0 :(得分:1)

MSDN article: Polling for the Status of an Asynchronous Operation表示您轮询结果的方式是正确的。但是,他们的示例并未包含Thread.Sleep

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

所以为了消除这种情况,我会使用以下片段来跟踪变量而不会睡觉,请注意,在每个循环上打印到Console会快速污染窗口:

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();
}

这不仅仅是一个评论而是一个答案,但是它被用作评论的时间太长了。