Windows Server 2008 R2 で FTP サイトを立ち上げる (イントラ)

割とめんどくさかったのでメモ書きします。すべてサーバー側の設定です。一応イントラでの環境設定を想定しているので、インターネットで公開する場合は対象箇所を置き換えて読み取ってください。

接続条件

  • 基本認証のみ
  • 21番ポートを使用した接続
  • イントラ環境のみ使用

手順

  1. 基本認証を行うためのユーザーアカウントを作成 (Users グループなどは削除して問題ありません。不用意にログインできないようにしましょう)。パスワードも設定しておきます。(FTP ログインのユーザー名とパスワードに使用されます)
  2. 任意のフォルダパスに FTP 用のフォルダを作成。対象フォルダに先ほど作成したユーザーの権限 (プロパティのセキュリティタブから)を付加する
  3. サーバーマネージャーの役割から Web サーバー(IIS) を選択し、役割サービスの中からFTPサーバーを選択しインストール
  4. IIS管理ツールを開き、サイトを右クリックして「FTPサイトの追加」を選択
  5. 物理パスは先ほど作成したフォルダのパスを指定。
  6. SSL を使わない場合は「なし」に設定。今回は匿名認証を使わないので基本認証のみにチェックを入れる
  7. FTP サイトを作成したら「FTP IPv4 アドレスとドメインの制限」を開き、操作から「許可エントリの追加」を選択。IP アドレス範囲を「192.168.0.0」マスク「255.255.255.0」のように設定 (この場合 192.168.0.0~192.168.0.255 の IP アドレスを持つ PC から接続が許可されます)
  8. 続いて FTP ホームから「FTP の承認規則」を開き、操作から「許可規則の追加」を選択。指定されたユーザーをチェックし、先ほど作成したユーザーアカウントの名前を設定します。このユーザーアカウントの名前とパスワードで外部から FTP 接続できます。
  9. 最後にサーバーマネージャーから Windows ファイアウォールを選択、受信の規則から新しい規則を作成し、TCP の 21番ポートを有効にします。

以上の設定が終わったら別な PC から FTP コマンドなりツールなり使用して接続確認をして下さい。

]]>

Windows Update が実行できない場合の対処法

環境

  • Windows Server 2008
  • Windows Server 2008 R2
  • Windows 7

注意

ここに書かれている内容は動作を保証するものではありませんので、ここに書かれている内容を実行する場合は自己責任で行ってください。

内容

Hyper-V のゲストOS環境として Windows Server 2008系列をインストールしている場合に、VHD ファイルを別なPC に移行して新しい環境で稼働させると、結構高い確率で Windows Update が実行できない状況に陥ります。ですが、この状態に陥る現象はよくわかっていません。

image

一度上の状態になってしまうと、更新プログラムの確認ボタンを押しても下のようなダイアログが表示され実行できず、OS を再起動しても直りません。

image

これを直すには .bat ファイルを作成し、以下のコードを作成しておきます。.bat は新規でテキストファイルを作成して拡張子を変えたもので構いません。文字コードは Ascii と同じコードをもつ Shift-JIS や UTF-8 (BOM なし)で保存してください。

net stop wuauserv
cd %systemroot%
ren SoftwareDistribution SoftwareDistributionold
net start wuauserv
net stop bits
net start bits
net stop cryptsvc
cd %systemroot%system32
ren catroot2 catroot2old
net start cryptsvc

image

ファイルを作成したらダブルクリックして実行します。コマンドプロンプトが表示されて処理が開始され、完了すると自動的に閉じられます。

image

実行が終わったら OS を再起動して Windows Update を実行します。最初の画像のようにエラーが表示されているままの状態になっていますが、更新プログラムの確認ボタンをクリックして正常に Windows Update が実行されるか確認してみてください。

]]>

SQL Server Reporting Services で登録されているサブスクリプションを一括実行する SQL

概要

サブスクリプションは登録したスケジュールに従って自動的に実行されますが、任意のタイミングで一括実行したい場合もあるかと思います。ここではそれを行うための実行 SQL を載せています。

注意

この記事の内容はすべての環境で実行を保証しているわけではありません。また公式でサポートしている内容でもありませんので自己責任でお使いください。

動作確認環境

  • SQL Server 2008 Standard SP3

実行 SQL

-- SubscriptionID を入れる変数
declare @id as uniqueidentifier
-- ReportServer データベースの Subscriptions テーブルから登録されている
-- サブスクリプション ID 一覧を取得
declare NEW_cursor cursor for
select SubscriptionID
from ReportServer.dbo.Subscriptions
-- カーソルオープン
open NEW_cursor
-- FETCH スタート
fetch next from NEW_cursor
into @id
while @@FETCH_STATUS = 0
begin
  -- サブスクリプションの実行イベント追加 (非同期)
  exec ReportServer.dbo.AddEvent @EventType='TimedSubscription', @EventData=@id
  -- 次の ID へ
  fetch next from NEW_cursor
  into @id
end
-- カーソルクローズ
close NEW_cursor
deallocate NEW_cursor

補足

この SQL はあくまでもイベントを登録しているだけなので即座にサブスクリプションの内容が実行されるわけではありません(非同期)。この SQL を実行すればサブスクリプションの実行内容がすべて完了しているものと思い込んでしまうと、次の処理を実行たときに、実はまだ処理が完了していなかった、なんてことになりかねないので注意してください。

]]>

[ASP.NET] エラー:オブジェクトの現在の状態に問題があるため、操作は有効ではありません。

リンク先情報なのですが、セキュリティパッチにより 500 個以上のコントロールを Postback するとタイトルのようなエラーが出てしまうみたいですね。回避策としては「コントロールの数を減らす」か「Web.config に上限数を設定する」のどちらかみたいですね。

]]>

jQuery とラジオボタンメモ

ラジオボタンのラベルクリックでもチェックできるようにする

<input type="radio" id=”AAA1” name=”BBB” val=”0” checked="checked" /><label for=”AAA1”>サンプル</label>
<input type="radio" id=”AAA2” name=”BBB” val=”1” /><label for=”AAA2”>サンプル</label>

 

ラジオボタンのチェック状態が変更されたときに処理を行う

$(“input[name=’BBB’]”).change(function()
{
  // なんたら処理
});

 

チェックがついているラジオボタンの値を取得する (ラジオボタンのイベント内で)

var data = $(this).val();

 

イベントを発行したラジオボタンがチェックされているか取得する (ラジオボタンのイベント内で)

if ($(this).attr("checked") == true)
{
  // なんたら
}

]]>

コマンドプロンプトでプログラムを実行後に戻り値を確認する方法

コマンドプロンプトで .exe や .vbs など各種プログラムを実行した後に戻り値を確認したい場合があります。プログラム実行後は環境変数「ERRORLEVEL」に戻り値が設定されるのでこれを呼び出せば確認することができます。

  1. コマンドプロンプトでプログラムを実行する
  2. 実行完了後、「echo %ERRORLEVEL%」を実行して確認
]]>

Windows 認証、または SQL Server 認証 sa ユーザー以外のユーザーに SQL Server エージェントのジョブ実行権限を付与する方法

メモ書きです。

  1. SQL Server Management Studio から「セキュリティ」-「ログイン」を開き、対象ユーザーのプロパティを開く
  2. 「ユーザーマッピング」を選択し、「msdb」にチェックを入れる。
  3. さらに msdb を選択した状態でメンバーシップから以下のメンバーシップにチェックを入れる
    • SQLAgentUserRole
    • SQLAgentReaderRole
    • SQLAgentOperatorRole
  4. 後はプログラムなどから対象ユーザーの接続文字列を使用してジョブが実行されるかチェックする
]]>

[ASP.NET] IE の互換表示で ReportViewer コントロールのサイズを小さくすると IE がフリーズする現象を回避する方法

ReportViewer+SSRS のレポートを IE で互換表示すると高確率でフリーズする」で質問させていただいたのですが、回避方法が見つかったのでこちらにも書いておきます。

【環境】(現象確認環境であるため、似たような環境でも発生すると思います)

❏サーバー

  • Windows Server 2008 R2 Standard (SPなし)
  • IIS 7.5
  • ASP.NET MVC 3
  • ReportViewer コントロール バージョン 10.0.0.0 (.NET Runtime 2.0.50727)
  • SQL Server 2008 R2 (SPなし)
  • 見出しマップを表示されたレポート (.rdl)

 

❏クライアント

  • OS : Windows XP, Vista, Windows Server 2008 R2
  • ブラウザ:IE8, 9

 

【現象】

ReportViewer コントロールに見出しマップがあるレポートをバインドさせ、その Web ページを IE 8, または 9 の「互換表示」で開き、ReportViewer コントロールのサイズを小さく表示させると IE がフリーズする。(ReportViewer コントロールのサイズがウインドウサイズに追従する場合は、IE のウインドウサイズを小さくしていけば現象は確認できる)

おそらくではあるが、IE の内部処理でレイアウトを計算する際に無限ループ、またはそれに近い再起処理が行われているためだと思われる。

 

【対処法】

IE のレイアウトの解析処理を変更させることでフリーズを回避させることができる。具体的には HTML の解析は DOCTYPE で変えられるため、この宣言の内容を変更することによって可能。

・修正前

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

↓↓↓↓

・修正後

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

 

しかし、HTML 4.01 Transitional を指定すると今度は逆に互換表示していない IE での表示が崩れてしまうという現象に見舞われる。そのため、HTML で互換表示かそうでないか (正確には IE のレンダリングバージョン)で条件分けをして現象を回避します。

下記では「IE 8 以降であるか」「IE 8 未満であるか」「それ以外のブラウザであるか」で分岐しています。

<!--[if gte IE 8]>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<![endif]-->
<!--[if lt IE 8]>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<![endif]-->
<![if !IE]>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<![endif]>

 

別案としてサーバーから「<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />」のようなメタ情報を返してクライアントで互換モードを指定するという方法もあるが、最終的な互換モードの決定権はクライアントにあるため、必ずしも有効であるとは限らない。(でも何もしないよりはいいと思います。)

]]>

[ASP.NET MVC] FilePathResult でファイルを返すと IE8 以前のブラウザで意図しないファイル名でダウンロードされる

アクションメソッド内で File メソッド (FilePathResult) を使用してファイルを返している処理があったのですが、IE でファイルをダウンロードした際にすべて同じファイル名でダウンロードされてしまうという報告を受けたので調べてみました。

理由については「ASP.NET MVC2 の FileContentResult で日本語ファイル名で返すと IE で日本語ファイル名にならない」のリンク先を見てもらえればそのままなのですが、IE8 以前だと、File メソッドの fileDownloadName 引数にファイル名を指定してもアクション名でファイル名が返ってしまうみたいです。

対応策はやはりリンク先のようにクラスを派生させて対応できました。私の場合はローカルにあるファイルからダウンロードさせるようにしていたので「FilePathResult」クラスから派生させています。コードは下のような感じです。(クラス名は適当なので気にしないでください)

/// <summary>
/// IE 8 以前でファイル名を正常に返せない不具合に対応した FilePathResult。
/// </summary>
public class FilePathResultEx : FilePathResult
{
    public FilePathResultEx(string fileName,
                            string contentType,
                            string fileDownloadName)
        : base(fileName, contentType)
    {
        base.FileDownloadName = fileDownloadName;
    }
    public override void ExecuteResult(ControllerContext context)
    {
        // IE 以外では基底の処理に任せる(RFC2231)
        if (context.HttpContext.Request.Browser.Browser != "IE")
            base.ExecuteResult(context);
        else
        {
            var fileName = this.FileDownloadName;
            fileName = HttpUtility.UrlEncode(fileName).Replace("+", "%20");
            var response = context.HttpContext.Response;
            response.ContentType = this.ContentType;
            response.AddHeader("content-disposition", "attachment; filename=" + fileName);
            this.WriteFile(response);
        }
    }
}

 

アクションメソッドでは下のように変更して返します。

string localFilePath = @"<ローカルのファイルパス>";
string contentType = "<ファイルのコンテンツタイプ>";
string downloadFileName = "<ダウンロードさせるファイル名>";
// 下のメソッドはやめる
//return File(localFilePath, contentType, downloadFileName);
// ヘッダーを変更したレスポンスを返す FilePathResul 拡張クラスで対応
return new FilePathResultEx(localFilePath, contentType, FileName);

]]>