2017-01-19 9 views
1

Wi-Fiホットスポットを作成し、powershellスクリプトを使用してインターネット接続共有を自動的に有効にするプログラムを作成しています。Powershellスクリプトを実行すると 'メモリ破損'または '読み書きできません'

スクリプトは正常に動作しますが、完了するまで待たなければなりません。そのため、ユーザーに完了を通知できます。私は以下のコードを使用していますが...

しかし、それはクラッシュし、私の家のコンピュータではより速く割り当てられます。 私は実際には説明できない、読み込みや書き込みができないか、メモリが壊れているというエラーが表示されます。

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をアクセスもしようとしている可能性があります。それが起こる理由なら、それが変更されているかどうかを確認したり、それが完了するまで待ってください。
編集

私は本当に、コールスタックがためである、またはどのようなスタックトレースがあり、そしてどのように私は墜落前に1つの瞬間を見たものの画像を提供病気にそれを使用することができるかを知らないと。 Stack Trace


編集 私はいくつかの周りスヌーピングを行なったし、私が試したいくつかのことを発見しました。

最初に、アプリケーションのプロパティ - >ビルドで、私は "好ましい32ビット"をオフにしました 一部の人がこの問題を解決したためです。私はクラッシュすることはありませんでしたが、スクリプトも実行されず、インターネット接続が切断されました。
だから私はそれを元に戻した。 私もnetsh winsock resetコマンドを試して、自分のPCを再起動しましたが、それでもクラッシュしました。

私はすべての手がかりを今すぐ外しましたが、私は答えを探しに来て、おそらくこれがうまくいく人のためにこれらの2つのものを掲示しました。

+0

完全なエラー(スタックトレースを含む)は何ですか? – Richard

+0

私はまだそれを得ることができません。私は今働いており、このマシンでうまく動作しますが、できるだけ早く投稿します。 – Jeremy

+0

エラーが「安全でない」コード内で何か起こったことを示していて、 'コード私はそれがC#コードよりもスクリプトに関係していると考えています。 – TheLethalCoder

答えて

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

これは、答えよりもコメントの詳細ですが、それは、コメントとして使用するには長すぎるなっていました。

+0

スレッドをブロックするので、' Thread.Sleep(1000); 'よりもうまく動作するので、実際にはこれを待つほうが意味があります。だから、この改善のおかげで、私は 'Thread.Sleep()'を使っていても、それがなくてもクラッシュしてしまったので問題ではないことは分かっています。それでも非常に便利です。 – Jeremy

+0

@Jeremy私は答えよりもコメントのほうが多いと言っていたが、すべてのマークダウンと長さで私は本当にそれをすることができなかった – TheLethalCoder

関連する問題