20210509のC#に関する記事は4件です。

DisplayPortスリープ問題をお手製アプリで回避してみた

概要 DisplayPortスリープ問題とやらに有効な策が取れずにいたので、自作アプリで対処しました。 本文 アプリ概要 Windowsフォームアプリ saveボタンを押すと、ウィンドウ情報を保存する restoreボタンを押すと、save時と位置情報が違う場合は復元する 起動時 味気ない・・・ save時 復元候補をずらっと表示します。プロセス名とウィンドウタイトルを出してます。 restore時 ウィンドウ位置・サイズが変わっていた場合は復元を試みて、行末に結果を付加しています。 既知の未解決問題点 管理者権限で動いているウィンドウを復元するには、アプリも管理者権限じゃないとだめみたいです。(当然といえば当然なんでしょうか) 一部のアプリは復元できないようです。私の愛用しているアプリに「壁カレ」というのがあるのですが、これは復元に失敗します。ウィンドウの形態が特殊なのでそのせいだとは思いますが、できれば復元できるようにしたいところです。 単独exeファイルで動くようにしたいのですが、そのようなビルド設定をしても、うまくいかずにいます・・・自分で使う分には別にいいのですが、ほかの人の需要があるかもしれないなどと妄想すると少し残念です。 起動している覚えがないのに、復元候補に電卓が出てきます。たいした問題ではないですがもやもやします。 ソースコード 今後 WindowsUpdateで根本解決したら、このコードは無用になります。 そうなるまでは、未解決問題点を改良できればなーとか思ってます。 思ったように動くかわからないまま書いたのでテストコードどころじゃなかったです。拡張するならテストコードとかちゃんと整備したいです。 単一exeファイルにできれば知り合いとかに使ってみてもらうとかありえそうなので、そこをなんとかしたいです。 チラシの裏 デビュー作です WindowsFormアプリ初めて作りました。 コンソールアプリでもよかったんですけど、フォームにウィンドウ情報覚えさせておくのが楽かなと思ってこうなりました。 ポエムな開発経緯 DisplayPortスリープ問題は今後のWindowsUpdateで解決される問題らしい が、それがいつになるかわからないし、そもそも私の環境はDisplayPortじゃなくてHDMIなので、ほんとに解決するかも疑わしい ウィンドウ位置復元のフリーソフトは探すと見つかるけど、探した限りでは「仮想デスクトップ未対応」と来た じゃあ自分で何とかするか・・・?と、仮想デスクトップ対応をどうするかという視点で、雑に探してみる 「仮想デスクトップ」という単語だと99.9%リモートのVDIでヒットしてしまい、むきー。となる apiとかそのへんのキーワードを加えて、SylphyHorn 作者さまの VirtualDesktop を見つける おお、これを使えば仮想デスクトップ対応のウィンドウ位置復元ができるのね?と思い込む 幸いC#は一応書ける インストールなしで動くVSCODEでなんとかしようと思い立ってみる VirtualDesktopがapp.manifest設定やらデバッグなし実行が必要やらで、うんともすんとも動かない manifestやらなんやら試してみたけどうまくいかず、諦めてVisualStudio Communityをインストール VirtualDesktopはあっさり動いた。 VSCODEはあくまでエディタで、素人がどうにかできるとは思うなってことか・・・ 想像では、VirtualDesktopの機能で、getVirtualDesktops().foreach(getWindows()) みたいな感じで仮想デスクトップごとにアプリ情報を取っていく・・・のだと思っていた が、そんな機能は見当たらなかった(最初に見とけって話か・・・) ぐぐりながら「ウィンドウすべてを取得」をしてみて、「それを保存」「それを復元」してみた やってみたところ、仮想デスクトップとか関係なしに復元できてしまった (公開されているウィンドウ復元ソフトが仮想デスクトップ非対応なのは何故・・・?) そんな疑問を残しつつ、自分の要求は、VirtualDesktopを使わずとも古来の機能で満たせるらしい ひとまず自分は少し幸せになれた
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【C#】Androidアプリの画面遷移

前回書いたC#のandroidアプリの作成方法の続き(補足)として、今回は一つのアプリ内で別のページを表示する方法について書いていこうと思います。 基本的には、デフォルトで生成されたコードを読み解けばわかる内容ではあるので、読まなくてもわかるという方はスルーしてください(笑) 下記が前回書いた記事ですので、今回の内容がわからない、もしくは単純に興味があるという方は見ていただけるとありがたいです。 https://qiita.com/NagaJun/items/87f126249028fa2b23a0 実装 前回の記事で書いた内容(プロジェクト作成時に自動で作成されるコード)を前提として、コードを書いていきます。 前提としては、/Resource/Layout/フォルダー下にページデザイン用のファイルであるcontent_main.xmlとactivity_main.xmlがあり、動きを制御するコードとしてMainActivity.csがあります。 今回のサンプルを作成するために以上の三つのファイルを修正します。 修正内容は以下の通りです。 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffe0"> <TextView android:text="activity_main_page" android:textAppearance="?android:attr/textAppearanceLarge" android:layout_width="match_parent" android:layout_height="match_parent" android:minWidth="25px" android:minHeight="25px" android:id="@+id/textView1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="change view content_menu" android:id="@+id/btn_show_content_main_page" android:layout_marginTop="@dimen/design_bottom_navigation_active_item_max_width" > </Button> </android.support.design.widget.CoordinatorLayout> content_main.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffd700" > <TextView android:text="content_main" android:textAppearance="?android:attr/textAppearanceLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:minWidth="25px" android:minHeight="25px" android:id="@+id/textView1" android:layout_marginBottom="35.5dp" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="change view activity" android:id="@+id/btn_show_activity_main_page" android:layout_marginTop="@dimen/design_bottom_navigation_active_item_max_width" > </Button> </RelativeLayout> MainActivity.cs //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public class MainActivity : AppCompatActivity { /// <summary>content_mainページ表示用ボタン</summary> private Button BtnShowContent { get; set; } /// <summary>activity_mainページ表示用ボタン</summary> private Button BtnShowActivity { get; set; } /// <summary>アプリ起動時</summary> /// <param name="savedInstanceState"></param> protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); // 初期ページを表示 SetContentView(Resource.Layout.activity_main); // contentページ表示ボタン BtnShowContent = FindViewById<Button>(Resource.Id.btn_show_content_main_page); BtnShowContent.Click += BtnShowContent_Click; } /// <summary>contentページ表示イベント</summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnShowContent_Click(object sender, EventArgs e) { SetContentView(Resource.Layout.content_main); // activityページ表示ボタン BtnShowActivity = FindViewById<Button>(Resource.Id.btn_show_activity_main_page); BtnShowActivity.Click += BtnShowActivity_Click; } /// <summary>activityページ表示イベント</summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnShowActivity_Click(object sender, EventArgs e) { SetContentView(Resource.Layout.activity_main); // contentページ表示ボタン BtnShowContent = FindViewById<Button>(Resource.Id.btn_show_content_main_page); BtnShowContent.Click += BtnShowContent_Click; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 不要なコードは全て省いてあるため、必要に応じて調整してください。 activity_main.xmlとcontent_main.xmlに関しては、今回サンプルとして記述した内容をそのままコピペしてもらえば大丈夫かと思います。 元のactivity_main.xmlには<include Layout=~>という記述があったかと思いますが、その記述でcontent_main.xmlの内容を読み込んでいるみたいなので、その記述は消してあります。(画面遷移を見たいので、ページを入れ子で読み込ませてあるとわかりにくいため) 今回、MainActivity.csに対して記述した内容は、各ページのボタンクリック時にSetContentView()で別ページを表示するようにしてあります。 ここで注意点ですが、FindViewById()で取得できるオブジェクト(今回の場合だとButton)は処理時に画面上に存在しているものに限られるため、OnCreate()メソッド内で初期画面に表示されないbtn_show_activity_main_pageボタンを取得することはできません。 また、画面が切り替わると取得済みのボタンのコントロールが失われるため、ページを切り替えるたびにオブジェクトの取得とイベントの設定を行う必要があります。(設定したはずのイベントも失われます) 動作確認 上記の修正を加えたら、前回同様の手段でデバッグを行います。 挙動は単純で下記画像の様な画面が立ち上がり、CHENGE VIEW~ボタンを押すたびに画面が切り替わります。 背景色と文字列が変わっているだけなので、一見、プロパティをいじっているだけにも見えますが(笑) もっとわかりやすい変化を見たいという方は.xmlファイルを修正してみるとよいかと思います。   終わりに 今回調べていて知ったのですが、.xmlファイルに記述する内容に関しては、android studioでアプリを作成する場合と基本的に同じなんですね(当然といえば当然ですが) C#のandroidアプリより、android studioの情報の方が、ネット上の先人の知恵が多いので助かります(笑)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C#で共有フォルダに接続する

接続機能クラス Connectで接続、DisConnectで切断。 WNetAddConnection2 と WNetCancelConnection2 の引数と戻り値は下記サイトが詳しい。 public class RemoteHostConnection { private NETRESOURCE netResource; [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2", CharSet = System.Runtime.InteropServices.CharSet.Unicode)] private static extern int WNetAddConnection2(ref NETRESOURCE lpNetResource, string lpPassword, string lpUsername, Int32 dwFlags); [DllImport("mpr.dll", EntryPoint = "WNetCancelConnection2", CharSet = System.Runtime.InteropServices.CharSet.Unicode)] private static extern int WNetCancelConnection2(string lpName, Int32 dwFlags, bool fForce); private string RemoteHostIP { get; set; } private string RemoteHostUserID { get; set; } private string RemoteHostPassword { get; set; } /// <summary> /// コンストラクタ /// </summary> /// <param name="remoteHostIP">リモートコンピュータのIP。( 例:192.168.1.1 )</param> /// <param name="remoteHostUserID">ログインID ( 例:user )</param> /// <param name="remoteHostPassword">パスワード ( 例:password )</param> public RemoteHostConnection(string remoteHostIP, string remoteHostUserID, string remoteHostPassword) { RemoteHostIP = $@"\\{remoteHostIP}"; RemoteHostUserID = remoteHostUserID; RemoteHostPassword = remoteHostPassword; } [StructLayout(LayoutKind.Sequential)] public struct NETRESOURCE { public int dwScope; public int dwType; public int dwDisplayType; public int dwUsage; [MarshalAs(UnmanagedType.LPWStr)] public string lpLocalName; [MarshalAs(UnmanagedType.LPWStr)] public string lpRemoteName; [MarshalAs(UnmanagedType.LPWStr)] public string lpComment; [MarshalAs(UnmanagedType.LPWStr)] public string lpProvider; } //(戻り値 == 0)は成功。 0以外は失敗。 public int Connect() { netResource.dwScope = 0; netResource.dwType = 1; netResource.dwDisplayType = 0; netResource.dwUsage = 0; netResource.lpLocalName = null; netResource.lpRemoteName = RemoteHostIP; netResource.lpProvider = null; int ret = WNetCancelConnection2(RemoteHostIP, 0, true); ret = WNetAddConnection2(ref netResource, RemoteHostPassword, RemoteHostUserID, 0); return ret; } //(戻り値 == 0)は成功。 0以外は失敗。 public int DisConnect() { return WNetCancelConnection2(RemoteHostIP, 0, true); } } 使い方 var connection = new RemoteHostConnection("192.168.1.1","user","password"); if(connection.Connect() == 0) { //共有フォルダにファイルコピーしたり削除したりする。 connection.DisConnect(); }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VS Code で ASP.NET MVC (Part 1) - MVC プロジェクトの作成と Hello World

はじめに 前提 とりあえず ASP.NET MVC で Hello World してみたい人向け? MVC の概念をざっくり知っている VS Code で C# の環境構築を終えている まだ環境構築を終えていない場合は VSCode|Visual Studio CodeでC#を動かしてみよう!- https://usimaru.net/vscode-install-cs/ を参考にすると良いと思います 投稿者は ASP.NET や MVC 自体触るのが初めて & 理解が追いついていない部分が多々ある ルーティングとかの細かい設定や説明は省いてます とりあえず備忘録も兼ねてます 実施環境 Mac を使っています(が、Windows でも大抵操作は同じかと思われます) 今後Windowsに切り替える可能性も出てきます Mac の場合は環境構築に加えて「Command + Shift + P」→「Shell」と入力し「PATH 内に 'code' コマンドをインストール」しておくと、ターミナルから VS Code を起動できるようになります この記事でやること ASP.NET MVC プロジェクトの作成 Hello World 1. ASP.NET MVC プロジェクトの作成 ターミナルから任意のディレクトリに移動して以下のコマンドを入力します。 $ dotnet new mvc -n SampleMVCApp // dotnet new mvc -n <任意のプロジェクト名> $ code SampleMVCApp // VS Code で <任意のプロジェクト名> を開く VS Code が起動し、SampleMVCApp を開くことができました。 SampleMVCApp フォルダの中身は以下の通りになっています。 プログラムを起動するには、ターミナルから以下のコマンドを入力します。 $ dotnet run localhost 上で立ち上がったので https://localhost:(ポート番号) に接続して動作確認してみます https://localhost:(ポート番号) にアクセスし、以下のようになっていれば成功です ターミナルで「Ctrl + C」を押すとプログラムを停止できます。 2. Hello World 2-1. Controller を作る Controller で View や Model を制御していきます(今回は Model は出てきません)。 Controllers フォルダ内に HelloController.cs を作成します。 Controllers フォルダ内に元からある HomeController.cs の中身をコピペして以下のように書き換えます。 Controllers/HelloController.cs using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using SampleMVCApp.Models; namespace SampleMVCApp.Controllers { public class HelloController : Controller { // https://localhost:<ポート番号>/<コントローラ名>/<アクション名> で発火 // https://localhost:<ポート番号>/Hello で発火 public IActionResult Index() { // cshtml ファイル (View) に向けて値を受け渡す // ViewBag や ViewData を使ってデータをやり取りする ViewBag.Message = "Here is 'Hello/Index.cshtml'"; return View(); } // https://localhost:<ポート番号>/Hello/sayHello で発火 public IActionResult sayHello() { ViewBag.Message = "Hello World!"; // Views/Hello/Index.cshtml に処理を反映させる return View("Index"); } } } 2-2. View を用意する View は画面上に処理結果を出力するために必要です。 まずは Views フォルダ内に Hello フォルダを作成します。 さらに Hello フォルダの中に Index.cshtml を作成します。 階層的にはこんな感じになっているかと思われます。 SampleMVCApp/ ├ bin/ ├ Controllers/ │ ├ HelloController.cs // "Controller を作る"で追加した分 │ └ HomeController.cs ├ Models/ ├ obj/ ├ Properties/ ├ Views/ │ ├ Hello/ // "View を用意する"で追加した分 │ │ └ Index.cshtml // "View を用意する"で追加した分 │ ├ Home/ │ ├ Shared/ │ ├ _ViewImports.cshtml ├ └ _ViewStart.cshtml ├ appsettings.Development.json ├ appsettings.json ├ Program.cs ├ SampleMVCApp.csProj └ StartUp.cs Views/Hello/Index.cshtml の中身を編集します。 Controllerから値を受け取るには "@" を使ってバインドしてあげます。 Views/Hello/Index.cshtml @{ ViewData["Title"] = "Home Page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p> @* HelloController.cs から受け取った値を表示 *@ <h2>@ViewBag.Message</h2> </div> 2-3. プログラムの実行 ターミナルから dotnet run で実行し、localhost 上で動作確認をします。 ルーティングの設定がデフォルトの状態(Views/Home/Index.cshtmlを参照するようになっている)なので、単純に localhost にアクセスした場合は何も変化がありません。 アクションを発火させるには URL を以下のように設定します。 https://localhost:<ポート番号>/<コントローラ名>/<アクション名> 例に倣って URL を https://localhost:<ポート番号>/Hello にすると以下のようになります。 Hello/Index.cshtml に向けて HelloController の Index( ) アクションが実行されています。 さらに、URL の末尾に /sayHello を追加すると Hello World が成功しているはずです。 Hello/Index.cshtml に向けて HelloController の sayHello( ) アクションが実行されています。 おわりに 今回は非常にざっくりでしたが、VS Code で ASP.NET MVC プロジェクト (Hello World) を実行する手順を書きました。 今後、理解が深まってきたら説明できていない部分の追記および Model を使った続編を書きたいと思っています。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む