最近のトラックバック

2017年9月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Google AdSense2

« 2009年7月 | トップページ | 2009年9月 »

2009年8月

C#で共有フォルダ作成/削除

C#で共有フォルダを作成/削除するサンプルを紹介する。


本サンプルではWin32APIの「NetShareAdd」「NetShareDel」を利用している。
これらAPIの実行権限には以下のセキュリティ要件がある。


Administrators または Account Operators ローカルグループのメンバ、あるいは Communication Operators、Print Operators、Server Operators のいずれかのグループのメンバだけがこの関数を実行できます。
Print Operator はプリンタキューだけを追加/削除できます。
Communication Operator は、通信デバイスキューだけを追加/削除できます。


どのユーザーでも共有フォルダ作成/削除できるというわけでないことを念頭に置いてほしい。


下記サンプルの共有フォルダ作成/削除クラス(ShareFolderManager)の公開メソッド定義は以下の通り。
概要 メソッド名
共有フォルダ作成 fnShareAdd()
共有フォルダ削除 fnShareDel()

■共有フォルダ作成/削除クラス(ShareFolderManager)

using System;
using System.Runtime.InteropServices;

/// <summary>
/// 共有フォルダ作成/削除クラス
/// </summary>
/// <remarks>
/// ■セキュリティ要件(NetShareAdd/NetShareDel関数)
/// Administrators または Account Operators ローカルグループのメンバ、あるいは 
/// Communication Operators、Print Operators、Server Operators のいずれかのグループの
/// メンバだけがこの関数を実行できます。
/// Print Operator はプリンタキューだけを追加/削除できます。
/// Communication Operator は、通信デバイスキューだけを追加/削除できます。
/// ■参考URL
/// NetShareAdd 関数
/// http://msdn.microsoft.com/ja-jp/library/cc446956.aspx
/// NetShareDel 関数
/// http://msdn.microsoft.com/ja-jp/library/cc446962.aspx
/// NetShareSetInfo 関数
/// http://msdn.microsoft.com/ja-jp/library/cc446974.aspx
/// </remarks>
public static class ShareFolderManager
{
    //=========================================================================================
    // Win32API 定数
    //=========================================================================================
    /// <summary>
    /// 共有デバイスがディスクドライブを示す定数
    /// <summary>
    private const short STYPE_DISKETREE = 0;
    // ==================
    // Win32API 戻り値
    // ==================
    /// <summary>
    /// 成功
    /// <summary>
    private const int NERR_Success = 0;
    /// <summary>
    /// ユーザーには、要求した情報へのアクセス権がありません。
    /// <summary>
    private const int ERROR_ACCESS_DENIED = 5;
    /// <summary>
    /// level パラメータで指定した値が無効です。
    /// <summary>
    private const int ERROR_INVALID_LEVEL = 124;
    /// <summary>
    /// 文字またはファイルシステム名が無効です。
    /// <summary>
    private const int ERROR_INVALID_NAME = 123;
    /// <summary>
    /// 指定されたパラメータは無効です。
    /// <summary>
    private const int ERROR_INVALID_PARAMETER = 87;
    /// <summary>
    /// 指定した共有名は、既にこのサーバーで使われています。
    /// <summary>
    private const int NERR_DuplicateShare = 2118;
    /// <summary>
    /// リダイレクトされたリソースに対して、この操作は無効です。指定されたデバイス名は、
    /// 共有リソースに割り当てられています。
    /// <summary>
    private const int NERR_RedirectedPath = 2117;
    /// <summary>
    /// デバイスまたはディレクトリが存在しません。 
    /// <summary>
    private const int NERR_UnknownDevDir = 2116;
    /// <summary>
    /// 利用可能なメモリが不足しています。
    /// <summary>
    private const int ERROR_NOT_ENOUGH_MEMORY = 8;
    /// <summary>
    /// 指定された共有名が存在しません。
    /// <summary>
    private const int NERR_NetNameNotFound = 2310;

    //=========================================================================================
    // Win32API 構造体
    //=========================================================================================
    /// <summary>
    /// 共有フォルダの設定
    /// </summary>
    /// <remarks>
    /// lmshare.h における _SHARE_INFO_2構造体定義
    /// typedef struct _SHARE_INFO_2 {
    ///     LMSTR   shi2_netname;
    ///     DWORD   shi2_type;
    ///     LMSTR   shi2_remark;
    ///     DWORD   shi2_permissions;
    ///     DWORD   shi2_max_uses;
    ///     DWORD   shi2_current_uses;
    ///     LMSTR   shi2_path;
    ///     LMSTR   shi2_passwd;
    /// } SHARE_INFO_2, *PSHARE_INFO_2, *LPSHARE_INFO_2;
    /// </remarks>
    private struct SHARE_INFO_2
    {
        /// <summary>
        /// 共有名
        /// </summary>
        public int shi2_netname;
        /// <summary>
        /// 共有タイプ
        /// </summary>
        public int shi2_type; 
        /// <summary>
        /// コメント
        /// </summary>
        public int shi2_remark;
        /// <summary>
        /// パーミッション
        /// </summary>
        public int shi2_permissions;
        /// <summary>
        /// 最大接続数
        /// </summary>
        public int shi2_max_uses;
        /// <summary>
        /// ?
        /// </summary>
        public int shi2_current_uses;
        /// <summary>
        /// 共有フォルダの絶対パス
        /// </summary>
        public int shi2_path;
        /// <summary>
        /// パスワード
        /// </summary>
        public int shi2_passwd;
        /// <summary>
        /// 引数付コンストラクタ
        /// (VisualStudio2008でビルド警告を防ぐためだけに利用)
        /// </summary>
        /// <param name="shi2_netname">共有名</param>
        /// <param name="shi2_type">共有タイプ</param>
        /// <param name="shi2_remark">コメント</param>
        /// <param name="shi2_permissions">パーミッション</param>
        /// <param name="shi2_max_uses">最大接続数</param>
        /// <param name="shi2_current_uses">?</param>
        /// <param name="shi2_path">共有フォルダの絶対パス</param>
        /// <param name="shi2_passwd">パスワード</param>
        private SHARE_INFO_2(
            int shi2_netname, int shi2_type, int shi2_remark, int shi2_permissions,
            int shi2_max_uses, int shi2_current_uses, int shi2_path, int shi2_passwd)
        {
            // VisualStudio2008でビルド警告を防ぐためだけに設定している
            // この初期化処理は全く意味がない
            this.shi2_netname = 0;      // 文字列:null
            this.shi2_type = 0;         // 数値:0
            this.shi2_remark = 0;       // 文字列:null
            this.shi2_permissions = 0;  // 数値:0
            this.shi2_max_uses = 0;     // 数値:0 
            this.shi2_current_uses = 0; // 数値:0
            this.shi2_path = 0;         // 文字列:null
            this.shi2_passwd = 0;       // 文字列:null
        }
    }

    //=========================================================================================
    // Win32API 関数参照
    //=========================================================================================
    /// <summary>
    /// 共有フォルダ作成
    /// </summary>
    /// <param name="servername">実行対象のリモートサーバー</param>
    /// <param name="level">情報レベル</param>
    /// <param name="buf">情報を保持しているバッファ</param>
    /// <param name="parm_err">エラーの発生場所を示すインデックス</param>
    /// <returns>
    /// ※エラー内容は上記の「Win32API 定数 - Win32API 戻り値」参照
    /// ERROR_ACCESS_DENIED
    /// ERROR_INVALID_LEVEL
    /// ERROR_INVALID_NAME
    /// ERROR_INVALID_PARAMETER
    /// NERR_DuplicateShare
    /// NERR_RedirectedPath
    /// NERR_UnknownDevDir
    /// </returns>
    /// <remarks>
    /// API定義
    /// NET_API_STATUS NetShareAdd(
    ///     LPWSTR servername, // 実行対象のリモートサーバー
    ///     DWORD level,       // 情報レベル
    ///     LPBYTE buf,        // 情報を保持しているバッファ
    ///     LPDWORD parm_err   // エラーの発生場所を示すインデックス
    /// );
    /// </remarks>
    [DllImport("Netapi32.dll", CharSet= CharSet.Unicode)]
    private static extern int NetShareAdd(
        string servername, int level, ref SHARE_INFO_2 buf, ref int parm_err);
    /// <summary>
    /// 共有フォルダ削除
    /// </summary>
    /// <param name="servername">実行対象のリモートサーバー</param>
    /// <param name="netname">削除対象の共有</param>
    /// <param name="reserved">予約済み</param>
    /// <returns>
    /// ※エラー内容は上記の「Win32API 定数 - Win32API 戻り値」参照
    /// ERROR_ACCESS_DENIED
    /// ERROR_INVALID_PARAMETER
    /// ERROR_NOT_ENOUGH_MEMORY
    /// NERR_NetNameNotFound
    /// </returns>
    /// <remarks>
    /// API定義
    /// NET_API_STATUS NetShareDel(
    ///     LPWSTR servername,  // 実行対象のリモートサーバー
    ///     LPWSTR netname,     // 削除対象の共有
    ///     DWORD reserved      // 予約済み
    /// );
    /// </remarks>
    [DllImport("Netapi32.dll", CharSet = CharSet.Unicode)]
    private static extern int NetShareDel(string servername, string netname, int reserved);

    //=========================================================================================
    // 公開メソッド
    //=========================================================================================
    /// <summary>
    /// 共有フォルダ作成
    /// </summary>
    /// <param name="sServerName">サーバー名</param>
    /// <param name="sShareName">共有名</param>
    /// <param name="iMaxUses">同時共有できる最大ユーザ数</param>
    /// <param name="sComment">コメント</param>
    /// <param name="sPhysicsFolderPath">共有フォルダの物理フォルダパス</param>
    /// <param name="sPassword">パスワード</param>
    /// <exception cref="SystemException">共有フォルダ作成失敗</exception>
    public static void fnShareAdd(
        string sServerName, string sShareName, int iMaxUses, string sComment,
        string sPhysicsFolderPath, string sPassword)
    {
        SHARE_INFO_2 si2;
        //-------------------------------------------------------------------------------------
        // 共有フォルダの設定
        //-------------------------------------------------------------------------------------
        // 共有名
        GCHandle gchNetName = GCHandle.Alloc(sShareName, GCHandleType.Pinned);
        si2.shi2_netname = gchNetName.AddrOfPinnedObject().ToInt32();
        // 共有タイプ
        si2.shi2_type = STYPE_DISKETREE;
        // コメント
        GCHandle gchNetRemark = GCHandle.Alloc(sComment, GCHandleType.Pinned);
        si2.shi2_remark = gchNetRemark.AddrOfPinnedObject().ToInt32();
        // パーミッション
        si2.shi2_permissions = 0;
        // 最大接続数
        si2.shi2_max_uses = iMaxUses;
        // ?
        si2.shi2_current_uses = 0;
        // 共有フォルダパス
        GCHandle gchPath = GCHandle.Alloc(sPhysicsFolderPath, GCHandleType.Pinned);
        si2.shi2_path = gchPath.AddrOfPinnedObject().ToInt32();
        // パスワード
        GCHandle gchPassword = GCHandle.Alloc(sPassword, GCHandleType.Pinned);
        si2.shi2_passwd = gchPassword.AddrOfPinnedObject().ToInt32();
        //-------------------------------------------------------------------------------------
        // 共有フォルダ作成
        //-------------------------------------------------------------------------------------
        int iParamErr = 0;
        // 第二引数はSHARE_INFO_2構造体を使うことを示している(らしい)
        int iResult = NetShareAdd(sServerName, 2, ref si2, ref iParamErr);
        //-------------------------------------------------------------------------------------
        // GCHandle解放
        //-------------------------------------------------------------------------------------
        gchNetName.Free();
        gchNetRemark.Free();
        gchPath.Free();
        gchPassword.Free();
        //-------------------------------------------------------------------------------------
        // 戻り値判定
        //-------------------------------------------------------------------------------------
        switch (iResult)
        {
            case NERR_Success:
                return;
            case ERROR_ACCESS_DENIED:
                throw new SystemException(
                    "ユーザーには、要求した情報へのアクセス権がありません。");
            case ERROR_INVALID_LEVEL:
                throw new SystemException("level パラメータで指定した値が無効です。");
            case ERROR_INVALID_NAME:
                throw new SystemException("文字またはファイルシステム名が無効です。");
            case ERROR_INVALID_PARAMETER:
                throw new SystemException("指定されたパラメータは無効です。");
            case NERR_DuplicateShare:
                throw new SystemException(
                    "指定した共有名は、既にこのサーバーで使われています。");
            case NERR_RedirectedPath:
                throw new SystemException(
                    "リダイレクトされたリソースに対して、この操作は無効です。" +
                    "指定されたデバイス名は、共有リソースに割り当てられています。");
            case NERR_UnknownDevDir:
                throw new SystemException("デバイスまたはディレクトリが存在しません。 ");
            default:
                string sMsg = string.Format(
                    "不明なエラー。NetShareAdd戻り値:{0}、iParamErr:{1}",
                    iResult, iParamErr);
                throw new SystemException(sMsg);
        }
    }
    /// <summary>
    /// 共有フォルダ削除
    /// </summary>
    /// <param name="sServerName">サーバー名</param>
    /// <param name="sShareName">共有名</param>
    /// <exception cref="SystemException">共有フォルダ削除失敗</exception>
    public static void fnShareDel(string sServerName, string sShareName)
    {
        //-------------------------------------------------------------------------------------
        // 共有フォルダ削除
        //-------------------------------------------------------------------------------------
        int iResult = NetShareDel(sServerName, sShareName, 0);
        //-------------------------------------------------------------------------------------
        // 戻り値判定
        //-------------------------------------------------------------------------------------
        switch (iResult)
        {
            case NERR_Success:
                return;
            case ERROR_ACCESS_DENIED:
                throw new SystemException(
                    "ユーザーには、要求した情報へのアクセス権がありません。");
            case ERROR_INVALID_PARAMETER:
                throw new SystemException("指定されたパラメータは無効です。");
            case ERROR_NOT_ENOUGH_MEMORY:
                throw new SystemException("利用可能なメモリが不足しています。");
            case NERR_NetNameNotFound:
                throw new SystemException("指定された共有名が存在しません。");
            default:
                string sMsg = string.Format(
                    "不明なエラー。NetShareDel戻り値:{0}", iResult);
                throw new SystemException(sMsg);
        }
    }
}


■上記クラスの利用方法は以下の通り

using System;

class Program
{
    static void Main(string[] args)
    {
        //-------------------------------------------------------------------------------------
        // 共有フォルダ作成
        //-------------------------------------------------------------------------------------
        ShareFolderManager.fnShareAdd(
            null,                           // サーバ名(nullの場合、ローカルPCに作成)
            "アプリ設定した共有フォルダ",   // 共有名
            10,                             // 最大接続数(-1で無制限)
            "コメント文",                   // コメント
            @"C:\temp\share",               // 共有フォルダの物理パス(事前に用意すること)
            "");                            // パスワード
        //-------------------------------------------------------------------------------------
        // 作成確認などのため1分間待機
        //-------------------------------------------------------------------------------------
        System.Threading.Thread.Sleep(60000);
        //-------------------------------------------------------------------------------------
        // 共有フォルダ削除
        //-------------------------------------------------------------------------------------
        ShareFolderManager.fnShareDel(
            null,                           // サーバ名(nullの場合、ローカルPCに作成)
            "アプリ設定した共有フォルダ");  // 共有名
    }
}


本サンプルとは直接関係ないことだが、共有フォルダには「隠し共有フォルダ」という属性がある。
設定方法は簡単で共有名の最後に$をつければよい。


隠し共有フォルダ設定にするとエクスプローラから共有フォルダが表示されなくなる。


しかしプログラムやショートカットファイルやエクスプローラアドレスバーに[\\localhost\hidden_share$]のようにパス指定すれば、隠し共有フォルダにアクセスできる。


隠し共有フォルダは要件次第では知っておいて損のない機能だ。



C#でショートカットファイル作成

C#でショートカットファイル作成するサンプルを紹介する。
ショートカットファイルを作る為にWSH(Windows Scripting Hosting)のCOMオブジェクトの1つである 「WshShortcutクラスのインタフェースIWshShortcut」を利用する。



■IWshShortcutインタフェースのプロパティ/メソッド
IWshShortcutインタフェースには以下のプロパティ/メソッドがある。
  プロパティ/メソッド名 概要 備考
TargetPath リンク先 必須
Arguments コマンドライン引数 TargetPathプロパティのコマンドライン引数
WorkingDirectory 作業フォルダ 起動アプリケーションの作業フォルダ
Hotkey ショートカットキー -
実行時の大きさ WindowStyle 1:通常のウィンドウ、3:最大、7:最小
コメント Description -
アイコン IconLocation [アイコンファイル]または[アイコンリソースが格納されたexe,dllファイル+","+"リソースの順番"
保存(メソッド) Save() -

上記表の①~⑦は以下の図の番号の設定に該当する。


■プロジェクトに"Windows Script Host Object Model"の参照追加
①Viual Sutidoの[プロジェクト]メニュー→[参照の追加]メニューから[参照の追加]ダイアログを開く。


②[COM]タブを選択し、"Windows Script Host Object Model"を選択する。


※この操作はVisualStudio2008上で操作です。バージョン違いなどで操作手順やイメージが異なる場合がある。


サンプルソースは以下の通り。

using System;
using System.Runtime.InteropServices;
using IWshRuntimeLibrary;

namespace CreateShortcutFile
{
    /// <summary>
    /// ショートカットファイル作成サンプル
    /// </summary>
    /// <remarks>
    /// 参考:
    /// http://homepage2.nifty.com/pasocon/nyumon/12.html
    /// </remarks>
    class Program
    {
        /// <summary>
        /// ショートカットファイル作成[シンブル版]
        /// </summary>
        /// <param name="sShortcutFilePath">ショートカットファイルの保存先パス</param>
        /// <param name="sLinkPath">リンク先</param>
        private static void fnCreateShortcutFile(string sShortcutFilePath, string sLinkPath)
        {
            IWshShell shell = null;         // シェルオブジェクト
            IWshShortcut shortcut = null;   // ショートカットオブジェクト
            try
            {
                //---------------------------------------------------------------------------------
                // オブジェクト作成
                //---------------------------------------------------------------------------------
                // シェルオブジェクト作成
                shell = new WshShellClass();
                // ショートカットオブジェクト作成
                //---------------------------------------------------------------------------------
                // ショートカット プロパティ設定
                //---------------------------------------------------------------------------------
                shortcut = (IWshShortcut)shell.CreateShortcut(sShortcutFilePath);
                // ショートカットのリンク先を設定
                shortcut.TargetPath = sLinkPath;
                //---------------------------------------------------------------------------------
                // ショートカットファイル作成
                //---------------------------------------------------------------------------------
                shortcut.Save();
            }
            finally
            {
                //---------------------------------------------------------------------------------
                // COMオブジェクト解放
                //---------------------------------------------------------------------------------
                // ショートカットオブジェクトの解放
                if (shortcut != null) Marshal.ReleaseComObject(shortcut);
                // シェルオブジェクトの解放
                if (shell != null) Marshal.ReleaseComObject(shell);
            }
        }
        /// <summary>
        /// ショートカットファイル作成[全プロパティ版]
        /// </summary>
        /// <param name="sShortcutFilePath">ショートカットファイルの保存先パス</param>
        /// <param name="sTargetPath">リンク先</param>
        /// <param name="sArguments">TargetPathのコマンドライン引数</param>
        /// <param name="sWorkingDirectory">作業フォルダ</param>
        /// <param name="sHotkey">ショートカットキー</param>
        /// <param name="iWindowStyle">実行時の大きさ(1:通常のウィンドウ、3:最大、7:最小)</param>
        /// <param name="sDescription">コメント</param>
        /// <param name="sIconLocation">アイコン</param>
        private static void fnCreateShortcutFile(
            string sShortcutFilePath,
            string sTargetPath,
            string sArguments,
            string sWorkingDirectory,
            string sHotkey,
            int iWindowStyle,
            string sDescription,
            string sIconLocation)
        {
            IWshShell shell = null;         // シェルオブジェクト
            IWshShortcut shortcut = null;   // ショートカットオブジェクト
            try
            {
                //---------------------------------------------------------------------------------
                // オブジェクト作成
                //---------------------------------------------------------------------------------
                // シェルオブジェクト作成
                shell = new WshShellClass();
                // ショートカットオブジェクト作成
                shortcut = (IWshShortcut)shell.CreateShortcut(sShortcutFilePath);
                //---------------------------------------------------------------------------------
                // ショートカット プロパティ設定
                //---------------------------------------------------------------------------------
                // リンク先
                shortcut.TargetPath = sTargetPath;
                // TargetPathのコマンドライン引数
                shortcut.Arguments = sArguments;
                // 作業フォルダ
                shortcut.WorkingDirectory = sWorkingDirectory;
                // ショートカットキー
                shortcut.Hotkey = sHotkey;
                // 実行時の大きさ
                shortcut.WindowStyle = iWindowStyle;
                // コメント
                shortcut.Description = sDescription;
                // アイコン
                shortcut.IconLocation = sIconLocation;
                //---------------------------------------------------------------------------------
                // ショートカットファイル作成
                //---------------------------------------------------------------------------------
                shortcut.Save();
            }
            finally
            {
                //---------------------------------------------------------------------------------
                // COMオブジェクト解放
                //---------------------------------------------------------------------------------
                // ショートカットオブジェクトの解放
                if (shortcut != null) Marshal.ReleaseComObject(shortcut);
                // シェルオブジェクトの解放
                if (shell != null) Marshal.ReleaseComObject(shell);
            }
        }
        /// <summary>
        /// メイン関数
        /// </summary>
        /// <param name="args"></param>
        static void Main()
        {
            //-------------------------------------------------------------------------------------
            // ショートカットファイル作成[シンブル版]
            //-------------------------------------------------------------------------------------
            // Excelファイルのショートカットファイル作成
            fnCreateShortcutFile(
                @"c:\temp\simple_excel.lnk",    // ショートカットファイルパス
                @"c:\temp\excel.xls");          // リンク先ファイルパス
            // メモ帳のショートカットファイル作成
            fnCreateShortcutFile(
                @"c:\temp\simple_notepad.lnk",  // ショートカットファイルパス
                @"notepad.exe");                // 実行ファイル名
            // Yahoo! JAPANのURLショートカットファイル作成
            fnCreateShortcutFile(
                @"c:\temp\simple_yahoo.lnk",    // ショートカットファイルパス
                @"http://www.yahoo.co.jp");     // リンク先URL
            //-------------------------------------------------------------------------------------
            // ショートカットファイル作成[全プロパティ版]
            //-------------------------------------------------------------------------------------
            // 「メモ帳で指定ファイルを開く」ショートカットファイル作成
            fnCreateShortcutFile(
                @"c:\temp\full_notepad.lnk",    // ショートカットファイルパス
                "notepad.exe",                  // リンク先
                @"c:\temp\memo.txt",            // コマンドライン引数
                @"c:\temp",                     // 作業フォルダ
                "",                             // ショートカットキー                        
                3,                              // 実行時の大きさ(3:最大化)
                "メモ帳で開きます。",           // コメント
                @"C:\Windows\regedit.exe, 1");  // アイコン
            // 「IEでYahoo! JAPANを開く」ショートカットファイル作成
            fnCreateShortcutFile(
                @"c:\temp\full_ie_yahoo.lnk",                           // ショートカットファイルパス
                @"C:\Program Files\Internet Explorer\iexplore.exe",     // リンク先
                @"http://www.yahoo.co.jp",                              // コマンドライン引数
                "",                                                     // 作業フォルダ
                "",                                                     // ショートカットキー                        
                7,                                                      // 実行時の大きさ(7:最小化)
                "IEでYahoo! JAPANを開く",                               // コメント
                @"C:\Program Files\Internet Explorer\iexplore.exe,1");  // アイコン
        }
    }
}



Windows 7起動中に固まる

同じ現象が発生している人の為にメモっておきます。


Windows 7 UltimateのRTMを入手したのでインストールしてみたのだが「シャットダウン→起動」と行うと高確率で Windows 7の起動中に固まる(フリーズする)現象に当たってしまった。

ちなみに同じ環境の別HDDでWindows Vista Ultimateを動かしているが、こちらは起動中に固まることはない。

当然、Windows 7付属の修復機能では問題不明。

最初はインストールイメージファイルが壊れていたのかと思い、32bit版のイメージを再取得→クリーンインストールとか、64bit版をクリーンインストール→稼働してみたりしたが、一向に解消しない。

続いてWindowsの起動中に固まる現象の対処をググッてみたらWindows XPやWindows Vistaでは「メモリーが壊れていないか」とか「ハードディスクが壊れていないか」とかあるが、メモリ・HDDのチェックツールを使っても正常だった。

しばらくして、イベントログにこんなエラーが出ていることに気がついた。

ログの名前: System
ソース: Kernel-Power
イベント ID: 41
タスクのカテゴリ: (63)
レベル: 重大
キーワード: (2)
ユーザー: SYSTEM
コンピューター: (コンピュータ名)
説明: システムは正常にシャットダウンする前に再起動しました。このエラーは、システムの応答の停止、クラッシュ、または予期しない電源の遮断により発生する可能性があります。

「Kernel-Power イベントID 41」でググるとWindows Vistaだが「休止状態時のバックアップの容量が大きい場合、ディスククリーンアップをしてみたらどうか?」という感じの検索結果に当たったが、これまた当方の問題と関係なかった。

半分お手上げ...と思っていたのだが、ふとDVD-ROMドライブの調子がおかしいことに気がついた。
※デバイスマネジャーでは"問題なし"だったけど...

DVD-ROMドライブを新品と交換したら...治ってしまった!!

イベントログの説明からの推測だが、シャットダウン時にDVD-ROMドライブが終了していないうちにOSがシャットダウン完了したのが、次回起動時に悪さしていたのかな~

ASP.NET(C#)でIEにOfficeドキュメントを表示

ASP.NET(C#)でIEにOfficeドキュメントを表示するサンプルを作成してみた。

【注意】
※本内容ではGoogleドキュメント等のWebアプリケーションの利用は考慮していません。
※本内容はクライアントPCにIEとMicrosoft Officeがインストールされていることを前提に書いています。
※クライアントPCにインストールされているMicrosoft Officeのバージョンによってデフォルトの挙動が異なります。挙動の違いはブラウザ上にExcel・Word・PowerPointドキュメントを表示/非表示する設定を調べてみたを参照してください。
※本内容はIEを取り扱っていますが、IE Tab :: Firefox Add-onsを組み込んだFirefoxでも同様な結果になることを確認しています。
※CSVやPDF等の他形式のバイナリファイルをブラウザ表示する方法についてはASP.NET(C#)でバイナリファイルをブラウザ表示を参照してください。



メインソースコードは以下の通り

// Response情報クリア
Response.ClearContent();
// HTTPヘッダー情報設定
Response.ContentType = {ここにMIMEを設定 };
// ファイル書込
Response.WriteFile(sFilePath);
// レスポンス終了
Response.End();


MIMEの一例を挙げると以下の通り。
Officeアプリケーション 一般的なファイル拡張子 MIMEタイプ
Microsoft Word .doc,.docx application/msword
Microsoft Excel .xls,.xlsx application/msword
Microsoft Power Point .ppt,.pptx application/vnd.ms-powerpoint

※他にx-application/~、applicathion/~等のMIMEがあります。
※CSVやPDF等の他形式のバイナリファイルをブラウザ表示する方法についてはASP.NET(C#)でバイナリファイルをブラウザ表示を参照してください。


IEにOfficeドキュメントを表示するサンプルソースを記述する。
なお使い勝手の関係で処理を「Officeドキュメントを開くページ(BinaryFile2Open.aspx)」「Officeドキュメントを表示する画面ページ(BinaryFile2.aspx)」の2ページに分割している。

※クライアントPCにインストールされているMicrosoft Officeのバージョンによってデフォルトの挙動が異なります。挙動の違いはブラウザ上にExcel・Word・PowerPointドキュメントを表示/非表示する設定を調べてみたを参照してください。

BinaryFile2Open.aspx
実行結果及びASP.NETソースコードの確認


<%@ Page Language="C#" Title="IEでOfficeドキュメントを開く" AutoEventWireup="true" %>
 :
 :
<asp:Content ID="ct" ContentPlaceHolderID="cpf1" runat="server">
<script type="text/javascript">
    /// <summary>
    /// [javascript]ダウンロードページを新規ウィンドウで開く
    /// </summary>
    /// <param name="sUrl">ダウンロードページのURL</param>
    function OpenWindow(sUrl)
    {
        window.open(sUrl, "", "");
    }
    /// <summary>
    /// [javascript]ダウンロードページをiframeタグ内で開く
    /// </summary>
    /// <param name="sUrl">ダウンロードページのURL</param>
    function InsertIFrame(sUrl)
    {
        document.getElementById('ifDownloadPage').contentWindow.location.href = sUrl;
    }
</script>
<script runat="server">
    /// <summary>
    /// Word97-2003ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnDoc_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("doc");
    }
    /// <summary>
    /// Word2007ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnDocx_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("docx");
    }
    /// <summary>
    /// Excel97-2003ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnXls_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("xls");
    }
    /// <summary>
    /// Excel2007ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnXlsx_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("xlsx");
    }
    /// <summary>
    /// PowerPoint97-2003ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnPpt_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("ppt");
    }
    /// <summary>
    /// PowerPoint2007ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnPptx_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("pptx");
    }
    /// <summary>
    /// ファイルを開く
    /// </summary>
    /// <param name="sFileName"></param>
    /// <param name="sMIME"></param>
    public void fnBinaryFileOpen(string sFileType)
    {
        // 指定形式でJavaScript登録
        string sScript = "<script type='text/javascript'>";
        if (rblOpenPlace.SelectedValue == "window")
        {
            sScript += string.Format(
                "OpenWindow('BinaryFile2.aspx?FileType={0}&time={1:HHmmss}');",
                sFileType, DateTime.Now);
        }
        else
        {
            sScript += string.Format(
                "InsertIFrame('BinaryFile2.aspx?FileType={0}&time={1:HHmmss}');",
                sFileType, DateTime.Now);
        }
        sScript += "<" + "/script>";
        // JavaScript登録
        ClientScript.RegisterStartupScript(GetType(), "fnBinaryFileOpen", sScript);
    }
</script>
<h1>IEでOfficeドキュメントを開く</h1>
<!-- コンテンツ説明 -->
<div class="contents_info">
    ASP.NETからIEIEでWord/Excel/PowerPoint等のOfficeファイルを開くサンプルです。<br />
    <br />
    ※クライアントPCにIEとOffice2000~2007がインストールされている場合に限ります。<br />
    ※OfficXP(Office2002)以前のバージョンのOfficeでは~2007ファイルは開けません。<br />
    ※Offic2007ではブラウザ内にドキュメントが表示されず、外部にOfficeアプリケーションが開くことがあります。<br />
    この現象は以下を参照してください。<br />
    <a href="http://niyodiary.cocolog-nifty.com/blog/2009/08/excelwordpowerp.html">ブラウザ上にExcel・Word・PowerPointドキュメントを表示/非表示する設定を調べてみた - niyoな日記</a><br />
</div>
<!-- コンテンツ -->
<asp:RadioButtonList id="rblOpenPlace" runat="server" RepeatDirection="Horizontal">
    <asp:ListItem Text="iframeで開く" Value="ifame" Selected="True" />
    <asp:ListItem Text="新規ウィンドウで開く" Value="window" />
</asp:RadioButtonList>
<asp:Button ID="btnDoc" runat="server" Text="Word97-2003ファイルを開く"  onclick="btnDoc_Click" /><br />
<asp:Button ID="btnDocx" runat="server" Text="Word2007ファイルを開く"  onclick="btnDocx_Click" /><br />
<asp:Button ID="btnXls" runat="server" Text="Excel97-2003ファイルのを開く"  onclick="btnXls_Click" /><br />
<asp:Button ID="btnXlsx" runat="server" Text="Excel2007ファイルを開く" onclick="btnXlsx_Click" /><br />
<asp:Button ID="btnPpt" runat="server" Text="PowerPoint97-2003ファイルを開く" onclick="btnPpt_Click" /><br />
<asp:Button ID="btnPptx" runat="server" Text="PowerPoint2007ファイルを開く" onclick="btnPptx_Click" /><br />
<br />
<iframe id="ifDownloadPage" style=" width:100%; height: 400px;"></iframe>
 :
 :

BinaryFile2.aspx


<%@ Page Language="C#" Title="Officeドキュメント表示" AutoEventWireup="true" %>
<%@ Import Namespace="System.IO" %>
<script runat="server">
    /// <summary>
    /// ページロード
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        string sFileType;   // ファイルタイプを取得
        string sFileName;   // ファイル名
        string sFilePath;   // ファイルパス
        string sMIME;       // MIME
        //-----------------------------------------------------------------------------------------
        // クエリ引数からファイルタイプ取得
        //-----------------------------------------------------------------------------------------
        sFileType = Request.QueryString["FileType"];
        //-----------------------------------------------------------------------------------------
        // ファイルタイプからファイル名とMIMEを設定
        //-----------------------------------------------------------------------------------------
        switch (sFileType)
        {
            case "doc":
                sFileName = "Word2003ファイル.doc";
                sMIME = "application/msword";
                break;
            case "docx":
                sFileName = "Word2007ファイル.docx";
                sMIME = "application/msword";
                break;
            case "xls":
                sFileName = "Excel2003ファイル.xls";
                sMIME = "application/vnd.ms-excel";
                break;
            case "xlsx":
                sFileName = "Excel2007ファイル.xlsx";
                sMIME = "application/vnd.ms-excel";
                break;
            case "ppt":
                sFileName = "PowerPoint2003ファイル.ppt";
                sMIME = "application/vnd.ms-powerpoint";
                break;
            case "pptx":
                sFileName = "PowerPoint2007ファイル.pptx";
                sMIME = "application/vnd.ms-powerpoint";
                break;
            default:
                sFileName = "Word2003ファイル.doc";
                sMIME = "application/msword";
                break;
        }
        //-----------------------------------------------------------------------------------------
        // 物理ファイルパス取得
        //-----------------------------------------------------------------------------------------
        sFilePath = MapPath(string.Format(@"./File/{0}", sFileName));
        //-----------------------------------------------------------------------------------------
        // バイナリファイルを開く処理
        //-----------------------------------------------------------------------------------------
        // Response情報クリア
        Response.ClearHeaders();
        Response.ClearContent();
        // バッファリング
        Response.Buffer = true;
        // HTTPヘッダー情報設定
        Response.ContentType = sMIME;
        // ファイル書込
        Response.WriteFile(sFilePath);
        // フラッシュ
        Response.Flush();
        // レスポンス終了
        Response.End();
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>バイナリファイル表示</title>
</head>
<body>
<form id="form1" runat="server">
</form>
</body>
</html>




ブラウザ上にExcel・Word・PowerPointドキュメントを表示/非表示する設定を調べてみた

ブラウザ上にExcel・Word・PowerPointドキュメントを表示/非表示する設定を調べてみた。

※本内容はクライアントPCにMicrosoft Officeがインストールされていることを前提に書いています。
※本内容ではGoogleドキュメント等のWebアプリケーションの利用は考慮していません。

IE6上にWordファイルを表示
  IE6上にExcelファイルを表示
  IE6上にPowerPointファイルを表示


■ブラウザ毎にExcelファイル表示可能かどうか調査した結果

ブラウザ 表示可能?
IE6
IE8
Firefox 3.5 ×
Opera 9.5 ×
Chrome 2.0 ×
Sleipnir 2.85(with IE8)

※動作確認環境はIE6はWindows XP SP3、その他はWindows Vista SP2。
※本結果にはGoogleドキュメント等のWebアプリケーションの利用は考慮していない。
※本結果にはプラグインも考慮していない。Firefox 3.5でIE Tabアドオンを利用した場合はIEと同じ結果になるようだ。


■IEバージョンとOfficeドキュメントの表示設定の調査結果

IEバージョン+Officeバージョン 既定値 設定変更可能か?
IE6 + Office 2003 IE内でOfficeドキュメント表示
IE6 + Office 2007 Excel・Word・PowerPointを起動→Officeドキュメント表示
IE8 + Office 2003 IE内でOfficeドキュメント表示
IE8 + Office 2007 Excel・Word・PowerPointを起動→Officeドキュメント表示

※動作確認環境はWindows XP SP3。IE8 + Office 2007のみWindows Vista SP2・Windows 7でも確認。



【テスト環境】

・Windows XP SP3 + IE 6.0 + Office 2003
・Windows XP SP3 + IE 6.0 + Office 2007
・Windows XP SP3 + IE 8.0 + Office 2003
・Windows XP SP3 + IE 8.0 + Office 2007


【設定手順】

1.エクスプローラを起動し、[ツール]→[フォルダ オプション]メニューを選択。


2.フォルダオプションダイアログから[ファイルの種類]タグを選択し、Officeドキュメントの該当拡張子(.doc/.xls/.ppt等)を選択。


3.[同じウィンドウで開く]のチェックをON/OFFに変更する。


チェック 動作内容
ON IE内でOfficeドキュメント表示
OFF Excel・Word・PowerPointを起動、Officeドキュメント表示


【設定後、IE上でOfficeドキュメントを開いた結果】

■チェックONの場合


■チェックOFFの場合(該当アプリでドキュメント起動)


【注意】 レジストリ操作は「システムを壊す」「既存アプリケーションの挙動をおかしくする」等の可能性がある。
レジストリを理解していない場合、Microsoft Windows レジストリの説明等を読み、理解を深めてから操作してください。
レジストリ操作をする前には必ずレジストリのバックアップをとってください。
この本操作により問題が発生した時の保障は出来ません。自己責任でお願いします。


【テスト環境】

・Windows XP SP3 + IE 6.0 + Office 2003
・Windows XP SP3 + IE 6.0 + Office 2007
・Windows XP SP3 + IE 8.0 + Office 2003
・Windows XP SP3 + IE 8.0 + Office 2007
・Windows Vista SP2 + IE 8.0 + Office 2007
・Windows 7 + IE 8.0 + Office 2007


【設定手順】

1.メモ帳を起動し、以下のテキストで必要な設定のみコピーし、メモ帳に貼り付ける。


■IEでOfficeドキュメントを表示させる設定 - Windows XP・Windows Vista・Windows 7
※対象拡張子:.doc;.rtf;.docx;.docm;.xls;.xlsx;.xlsm;.xlsb;.ppt;.pptx;.pptm;.pps;.ppsx;.ppsm


■IEでOfficeドキュメントを表示させない設定(該当アプリでドキュメント起動)- Windows XP・Windows Vista
※対象拡張子:.doc;.rtf;.docx;.docm;.xls;.xlsx;.xlsm;.xlsb;.ppt;.pptx;.pptm;.pps;.ppsx;.ppsm


■IEでOfficeドキュメントを表示させない設定(該当アプリでドキュメント起動)- Windows 7
※対象拡張子:.doc;.rtf;.docx;.docm;.xls;.xlsx;.xlsm;.xlsb;.ppt;.pptx;.pptm;.pps;.ppsx;.ppsm


3.[IEOffice.reg]という名前でファイル保存。


4.[IEOffice.reg]をダブルクリックして、レジストリスクリプトを実行、レジストリ登録。



【レジストリ登録後、IE上でOfficeドキュメントを開いた結果】

■IEでOfficeドキュメントを表示させる設定を行った場合


■IEでOfficeドキュメントを表示させない設定を行った場合(該当アプリでドキュメント起動)





« 2009年7月 | トップページ | 2009年9月 »

Google AdSense


  • ---

Amazon ウィジェット

  • ウィジェット

@niyo_naのツイート

無料ブログはココログ

Google Analytics