質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Q&A

解決済

1回答

1909閲覧

c# マウス操作イベントを出力しつつファイルダウンロードがうまくできない

montai21

総合スコア17

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

0グッド

0クリップ

投稿2020/05/25 22:52

編集2020/05/25 22:58

#事象
プログラム動かす環境が一定時間ユーザの無操作状態が続くと、強制ログオフするようになっております。ユーザが業務終了後に、大容量のファイル(6GBくらい)をダウンロードするために、ダウンロードを予約し、また、予約を画面からキャンセルできるようにしたいと考えております。一定時間放置後にも予約をキャンセルできるようにしたいため、強制ログオフしないように、プログラムからマウス操作イベントを定期的に出力するようにしております。また、ダウンロード処理も同プログラム内で実行するようします。検証でおこなったところ、ダウンロード処理を走らせない場合は、一定時間放置しても、ディスプレイ電源offや強制ログオフは起こらなかったんですが、ダウンロード処理を走らせますと、プログラムが応答なしとなり、一定時間放置しますと、ディスプレイ電源がoffになりました。しかし、ダウンロード処理は時間がかかりますが、正常に終了します。ファイル容量が小さい場合は強制ログオフをかいひしつ

#アドバイスいただきたいこと
0. 事象に挙げた内容を踏まえ、強制ログオフが起きないようにしつつ、ダウンロード処理を行うにはどのようにすればよいでしょうか?
0. ダウンロード処理にファイル共有し、コピーを行っているのですが、ftpダウンロードの方が負荷が少ないでしょうか?
0. タイマースレッドを用いて、マウスイベントを定期的に出力しているのですが、以下のコードの書き方があまりよくないのでしょうか。

#Form

using System; using System.Diagnostics; using System.IO; using System.Windows.Forms; namespace AidleStatusDisableApp { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { const string commandMount = @"/c net use \servername\kyouyu password /user:user /PERSISTENT:NO"; ExecuteCommand(commandMount); CopyFiles(@".\test.txt", @"\servername\kyouyu\testbigfile"); } private void button2_Click(object sender, EventArgs e) { } public void ExecuteCommand(string command) { using (var p = new Process()) { //ComSpec(cmd.exe)のパスを取得して、FileNameプロパティに指定 p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec"); ////ウィンドウを表示しないようにする p.StartInfo.CreateNoWindow = true; //コマンドラインを指定("/c"は実行後閉じるために必要) p.StartInfo.Arguments = command; //起動 p.Start(); p.WaitForExit(); } } public void CopyFiles(string srcfile, string dstfile) { File.AppendAllText(@".\log.txt", "コピーを開始します。" + DateTime.Now + Environment.NewLine); System.IO.File.Copy(srcfile, dstfile, true); File.AppendAllText(@".\log.txt", "コピーを終了します。" + DateTime.Now + Environment.NewLine); } } }

#Program

using System; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; using System.Threading.Timer namespace AidleStatusDisableApp { public static class Program { const int MOUSEEVENTF_MOVED = 0x0001; [STAThread] public static void Main() { TimerCallback callback = state => { INPUT[] input = new INPUT[1]; // イベントを格納 // ドラッグ操作の準備 (イベントの定義 = 相対座標へ移動) input[0].mi.dx = 0; // 相対座標で0 つまり動かさない input[0].mi.dy = 0; // 相対座標で0 つまり動かさない input[0].mi.dwFlags = MOUSEEVENTF_MOVED; // ドラッグ操作の実行 (イベントの生成) SendInput(1, input, Marshal.SizeOf(input[0])); }; // タイマー起動(0.5秒後に処理実行、1秒おきに繰り返し) Timer MyTimer = new System.Threading.Timer(callback, null, 500, 1000); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } [DllImport("user32.dll")] extern static uint SendInput( uint nInputs, // INPUT 構造体の数(イベント数) INPUT[] pInputs, // INPUT 構造体 int cbSize // INPUT 構造体のサイズ ); [StructLayout(LayoutKind.Sequential)] struct INPUT { public int type; // 0 = INPUT_MOUSE(デフォルト), 1 = INPUT_KEYBOARD public MOUSEINPUT mi; } [StructLayout(LayoutKind.Sequential)] struct MOUSEINPUT { public int dx; public int dy; public int mouseData; // amount of wheel movement public int dwFlags; public int time; // time stamp for the event public IntPtr dwExtraInfo; } } }

##環境
.Net Framework 4.6
Windows 10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/05/25 23:20

サードパーティーのダウンロードマネージャーを使えばいいのでは?
KOZ6.0

2020/05/25 23:58

SendInput を実行しているスレッドが UI スレッドでないのが気になります。 System.Threading.Timer でなく、 System.Windows.Forms.Timer だとどうなんでしょう?
退会済みユーザー

退会済みユーザー

2020/05/26 01:04

省電力防止関係で SetThreadExecutionState なんてAPIもあるみたいですね。(全く検証はしてません)
montai21

2020/05/26 12:50

>>Zuishinさん 恐れながら、無知なためサードパーティーのダウンロードマネージャーについて存じ上げません。
montai21

2020/05/26 12:53

>>radianさん 試したのですが、あまりうまくいかなかったため、SendInputを利用しました。
guest

回答1

0

ベストアンサー

ダウンロード処理を走らせない場合は、一定時間放置しても、ディスプレイ電源offや強制ログオフは起こらなかったんですが、ダウンロード処理を走らせますと、プログラムが応答なしとなり

実行時間が長時間掛かるメソッドをUIスレッドで実行すると、メソッドが終了するまでフォーム全体の処理が停止しますので、Task.Run等を使用して非同期で実行する必要があります。

C#

1 var copyTask = Task.Run(() => 2 { 3 const string commandMount = @"/c net use \servername\kyouyu password /user:user /PERSISTENT:NO"; 4 ExecuteCommand(commandMount); 5 CopyFiles(@".\test.txt", @"\servername\kyouyu\testbigfile"); 6 });

上記サンプルコードは、重そうな処理だけTaskで起動する例ですが、実際は

  • 既にTaskを実行中か
  • Taskをどうやって中断させるか
  • Task中の例外処理

等、色々考慮しないといけない事も増えますので注意が必要です。
また、中断まで考慮するなら、File.Copy を FileStream での読み書きに変更したほうが良いかもしれません。

投稿2020/05/25 23:55

編集2020/05/26 00:37
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

montai21

2020/05/26 12:48

回答いただきまして、ありがとうございます! 提案いただいた内容を試したところ、プログラムが応答なしにならず、また数分放置後も画面暗転しませんでした。 非同期処理にすることで増える注意点については今後対策を考えていこうと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問