たかやまのプログラミング

プログラミング中心のブログです。

移転します。

以下のFC2ブログに移転します。
http://takymsystems.blog.fc2.com/
ただし、記事はこのままにしておきます。
もし記事を書き換えたりする場合は、移転先でリメイク版として公開します。
詳細→http://takymsystems.blog.fc2.com/blog-entry-6.html

ポインタを使った値型の参照渡し

前回は、ポインタを使ってメモリにアクセスできるので、暗黙的に型を別の型に変換できるのではないかと思いましたのでC#で試してみました。今回は、ポインタを使って値型の参照渡しをしてみたいと思います。
(※ポインタを使うには '/unsafe' でコンパイルする必要があります。)


Program.cs

using System;

namespace MemoryTest
{
    // ポインタにするためアンセーフにする。
    static unsafe class Program
    {
        static void Main(string[] args)
        {
            // ポインタを使う変数。
            Target tc = new Target();
            tc.number = 0x12345678;

            // 変更前の値を表示。
            Console.WriteLine("number=0x{0:X}", tc.number);

            // 値を変更する関数呼び出し。
            Test(&tc);

            // 変更後の値を表示。
            Console.WriteLine("number=0x{0:X}", tc.number);
        }

        static void Test(Target* pointer)
        {
            // 値を変更。
            pointer->number = 0x9ABCDEF0;
        }

        // ターゲットの型。
        // 値型でなければいけない。(フィールドも。)
        struct Target
        {
            public uint number;
        }
    }
}



感想
これは、ポインタを使わずにoutキーワードを使えば簡単に同じことをできると思いました。

ソースコードのダウンロード

ポインタを使った暗黙的な型変換

ポインタを使ってメモリにアクセスできるので、暗黙的に型を別の型に変換できるのではないかと思いましたのでC#で試してみました。
(※ポインタを使うには '/unsafe' でコンパイルする必要があります。)


Program.cs

using System;

namespace MemoryTest
{
    // ポインタにするためアンセーフにする。
    static unsafe class Program
    {
        static void Main(string[] args)
        {
            // ポインタを使う変数。
            Target tc = new Target();
            // tc のポインタ。
            Target* tc_pointer = &tc;
            // 値を代入する。
            tc_pointer->number1 = 0x12345678;
            tc_pointer->number2 = 0x00ABCDEF;
            // tc と同じアドレスで、LongTarget型のポインタを作る。
            LongTarget* lt_pointer = ((LongTarget*)(tc_pointer));

            // 結果の表示
            Console.WriteLine("アドレス:0x{0:X}", new IntPtr(tc_pointer));
            Console.WriteLine("number1=0x{0:X}", tc.number1);
            Console.WriteLine("number2=0x{0:X}", tc.number2);
            Console.WriteLine("number3=0x{0:X}", lt_pointer->number3);
        }

        // ターゲットの型。
        // 値型でなければいけない。(フィールドも。)
        struct Target
        {
            public uint number1;
            public uint number2;
        }

        // ターゲットの型。
        struct LongTarget
        {
            public ulong number3;
        }
    }
}



ソースコードのダウンロード

C#のMicrosoft.Win32.RegistryKeyクラスを使用してプロトコルの登録

C#プロトコルの登録する方法を見つけました。
Microsoft.Win32.RegistryKeyクラスを使用します。


Protocol.cs

using Microsoft.Win32;
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Sample
{
    public class Protocol
    {
        public Protocol()
        {
            // GUIDの取得。
            Assembly asm = Assembly.GetExecutingAssembly();
            GuidAttribute ga = ((GuidAttribute)(Attribute.GetCustomAttribute(asm, typeof(GuidAttribute))));
            string guid = ga.Value;

            // 登録するプロトコル。
            string ProtcolType = "test";

            // 実行するコマンドライン。
            string commandline = "\"" + Application.ExecutablePath + "\" \"%1\"";

            // 説明。
            string description1 = "test: Test Protocol Handler";
            string description2 = "URL:test Protocol";

            // 動詞。
            string verb = "open";

            // アイコンの指定。
            string iconPath = Application.ExecutablePath;
            int iconIndex = 0;


            // ※以下のコードは書き変えないで使ってください。
            RegistryKey rootkey = Registry.ClassesRoot;

            RegistryKey regkey = rootkey.CreateSubKey("PROTOCOLS\\Handler\\" + ProtcolType);
            regkey.SetValue("", description1);
            regkey.SetValue("CLSID", guid);
            regkey.Close();

            RegistryKey typekey = rootkey.CreateSubKey(ProtcolType);
            typekey.SetValue("", description2);
            typekey.SetValue("Source Filter", guid);
            typekey.SetValue("URL Protocol", "");
            typekey.Close();

            RegistryKey verblkey = rootkey.CreateSubKey(ProtcolType + "\\shell\\");
            verblkey.SetValue("", verb);
            verblkey.Close();

            RegistryKey open = rootkey.CreateSubKey(ProtcolType + "\\shell\\" + verb);
            open.SetValue("CommandId", "");
            open.SetValue("DontReturnProcessHandle", "");
            open.Close();

            RegistryKey cmdkey = rootkey.CreateSubKey(ProtcolType + "\\shell\\" + verb + "\\command");
            cmdkey.SetValue("", commandline);
            cmdkey.SetValue("DelegateExecute", guid);
            cmdkey.Close();

            RegistryKey iconkey = rootkey.CreateSubKey(ProtcolType + "\\DefaultIcon");
            iconkey.SetValue("", iconPath + "," + iconIndex.ToString());
            iconkey.Close();
        }
    }
}



ソースコードのダウンロード

C#のMicrosoft.Win32.RegistryKeyクラスを使用して拡張子登録

リメイク版の記事ができましたのでこちらの記事を見てください。
C#で拡張子を登録する方法を見つけました。
C#Microsoft.Win32.RegistryKeyクラスを使用します。


Extension.cs

using Microsoft.Win32;
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Sample
{
    public class Extension
    {
        public Extension()
        {
            // 登録する拡張子。
            // (※お好みで指定してください。)
            string extension = ".test";

            // 実行するコマンドライン。
            string commandline = "\"" + Application.ExecutablePath + "\" \"%1\"";
            string fileType = Application.ProductName;

            // 説明。
            // (※お好みで指定してください。)
            string description = "test ファイル";

            // 動詞。
            // (※お好みで指定してください。)
            string verb = "open";
            string verbDescription = "開く(&O)";

            // アイコンの指定。
            string iconPath = Application.ExecutablePath;
            int iconIndex = 0;


            // ※以下のコードは書き変えないで使ってください。
            RegistryKey rootkey = Registry.ClassesRoot;

            RegistryKey regkey = rootkey.CreateSubKey(extension);
            regkey.SetValue("", fileType);
            regkey.Close();

            RegistryKey typekey = rootkey.CreateSubKey(fileType);
            typekey.SetValue("", description);
            typekey.Close();

            RegistryKey verblkey = rootkey.CreateSubKey(fileType + "\\shell\\" + verb);
            verblkey.SetValue("", verbDescription);
            verblkey.Close();

            RegistryKey cmdkey = rootkey.CreateSubKey(fileType + "\\shell\\" + verb + "\\command");
            cmdkey.SetValue("", commandline);
            cmdkey.Close();

            RegistryKey iconkey = rootkey.CreateSubKey(fileType + "\\DefaultIcon");
            iconkey.SetValue("", iconPath + "," + iconIndex.ToString());
            iconkey.Close();
        }
    }
}



ソースコードのダウンロード

C#のMicrosoft.Win32.RegistryKeyクラスを使用してアプリケーションのインストール

C#でアプリケーションをインストールする方法を見つけました。
Microsoft.Win32.RegistryKeyクラスを使用します。


Install.cs

using Microsoft.Win32;
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Sample
{
    public class Install
    {
        public Install()
        {
            // GUID の取得。
            Assembly asm = Assembly.GetExecutingAssembly();
            GuidAttribute ga = ((GuidAttribute)(Attribute.GetCustomAttribute(asm, typeof(GuidAttribute))));
            string guid = ga.Value;

            // アイコンの設定。
            string iconPath = Application.ExecutablePath;
            int iconIndex = 0;

            // アプリケーションの名前を登録。
            string displayName = Application.ProductName;

            // アプリケーションのバージョンを登録。
            string displayVersion = Application.ProductVersion;

            // アプリケーションの場所を登録。
            string location = Application.StartupPath;
            string source = Application.StartupPath;

            // アプリケーションの言語を指定。
            // (※現在は日本語で指定している。)
            int lang = 00000409;
            string publisher = Application.CompanyName;

            // アンインストーラのパス。
            // (※お好みで指定してください。)
            string uninstall = "";


            // ※以下のコードは書き変えないで使ってください。
            RegistryKey rootkey =
                Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");

            RegistryKey regkey = rootkey.CreateSubKey(guid);
            regkey.SetValue("DisplayIcon", iconPath + "," + iconIndex.ToString());
            regkey.SetValue("DisplayName", displayName);
            regkey.SetValue("DisplayVersion", displayVersion);
            regkey.SetValue("InstallLocation", location);
            regkey.SetValue("InstallSource", source);
            regkey.SetValue("Language", lang, RegistryValueKind.DWord);
            regkey.SetValue("Publisher", publisher);
            regkey.SetValue("UninstallPath", "\"" + uninstall + "\"");
            regkey.SetValue("UninstallString", "\"" + uninstall + "\"");
            regkey.Close();
        }
    }
}



ソースコードのダウンロード

忘れてました・・・

ブログを書くのを忘れてました。すみません。
これからも書きます。