JavaScript

2012年8月28日 (火)

クリップボードにアクセスするスクリプト

wsf(wsh)のJavascriptでクリップボードにアクセスする方法を
web検索したら、

WSH よりクリップボードを使う
WSH よりクリップボード、次の手

が見つかりました。
前者は、いちいちダイアログが立ち上がるので
後者を使いたいわけですが、CライクだからJavaScriptを使う
私にはとっかかりの部分がよくわかりません。

で、自分がとっつきやすいようにするため、二つをあわせて
以下のように変更(ほとんどパクリですみません)。とりあえず動作。

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
<job id="ClipTest">
<?job error="True" debug="True" ?>
<object id="objFs" progid="Scripting.FileSystemObject" />
<script language="JavaScript">
<![CDATA[

var clipboard = new Clipboard ();
var stxt = clipboard.getText ();
WScript.Echo (stxt);//クリップボードの内容をダイアログ表示

clipboard.setText ("OK : " + stxt);//"OK : "を追加して文字列をクリップボードに書き込み

function Clipboard ()
{
// コマンドのID
var OLECMDID_COPY = 12;
var OLECMDID_PASTE = 13;
var OLECMDID_SELECTALL = 17;

// IE のインスタンスを作成
this.internetExplorer = new ActiveXObject ('InternetExplorer.Application');

// IEの初期化
this.internetExplorer.Navigate ('about:blank');
while (this.internetExplorer.Busy)
  WScript.Sleep (10);

// textarea 要素を作成する
var _textarea = this.internetExplorer.document.createElement ("textarea");
this.internetExplorer.document.body.appendChild (_textarea);
_textarea.focus ();

// クリップボードより文字列を取得するメソッド
this.getText = function ()
{
  _textarea.innerText = "";
  this.internetExplorer.execWB (OLECMDID_PASTE, 0);
  return _textarea.innerText;
};

// クリップボードに文字列をコピーするメソッド
this.setText = function (s)
{
  _textarea.innerText = s;
  this.internetExplorer.execWB (OLECMDID_SELECTALL, 0);
  this.internetExplorer.execWB (OLECMDID_COPY, 0);
  return true;
}

// IE を解放するメソッド
this.release = function ()
{
  this.internetExplorer.Quit ();
  return true;
}

return this;
}
]]>
</script>
</job>
</package>

| | コメント (2) | トラックバック (0)

2012年8月21日 (火)

TortoiseSVNでの変更ファイル等をcopyするwsf

TortoiseSVNでの変更ファイル等をcopyするバッチファイル
使っていましたが、ファイルやフォルダ名にスペース文字があったときなど
対応ができないので、困ることが多くなり、wsfで作り直しました。

以下がそれです。

<copytsvn.wsf>

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
<job id="copytsvn">
<?job error="True" debug="True" ?>
<object id="objFs" progid="Scripting.FileSystemObject" />
<script language="JavaScript">
<![CDATA[

LISTTXT = "list.txt";
SRC_FOLDER = "AAA";
DST_FOLDER = "AAA_bk";

var strCurrentFolder = objFs.GetParentFolderName(WScript.ScriptFullName);
//WScript.Echo ("CurrentFolder : " + strCurrentFolder);

var strSourceFolder = strCurrentFolder + "\\" + SRC_FOLDER;
var strDestinationFolder = strCurrentFolder + "\\" + DST_FOLDER;
var strListText = strCurrentFolder + "\\" + LISTTXT;
var strTemp;

if(!objFs.FolderExists(strCurrentFolder))
{
WScript.Echo ("SourceFolderがありません");
}
else if(!objFs.FileExists(strListText))
{
WScript.Echo (LISTTXT + "がありません");
}
else if(objFs.FolderExists(strDestinationFolder))
{
WScript.Echo ("DestinationFolderが既に存在します");
}
else
{
objFs.CreateFolder(strDestinationFolder);//DestinationFolder作成
var objTs = objFs.OpenTextFile(strListText,1,false);//ReadOnlyでLISTTXTを開く

do{
  strLine = objTs.ReadLine();//1line読み出し
  //WScript.Echo ("> " + strLine);
  splitData = strLine.split("/");//'/'で区切る
  //WScript.Echo ("num: " + splitData.length);
  if(splitData.length == 0)
  {
   //処理しない
  }
  else
  {
   if(splitData.length == 1)//file copyのみ
   {
    //for file copy
    strTemp = splitData[splitData.length-1];//file pathの後半部分
   }
   else
   {
    //mkdir
    //strDestinationFolder;
    for(i=0; i<(splitData.length-1); i++)//最後の文字列はファイルであるとみなす
    {
     //WScript.Echo ("str: " + splitData[i]);
     if(i == 0)
     {
      strTemp = splitData[i];
     }
     else
     {
      strTemp = strTemp + "\\" + splitData[i];
     }
     if(!objFs.FolderExists(strDestinationFolder + "\\" + strTemp))
     {
      objFs.CreateFolder(strDestinationFolder + "\\" + strTemp);//Folder作成
     }
    }
   
    //for file copy
    strTemp = strTemp + "\\" + splitData[splitData.length-1];//file pathの後半部分
   }
   //file copy
   if(!objFs.FileExists(strSourceFolder + "\\" + strTemp))
   {
    WScript.Echo ("ファイル:" + splitData[splitData.length-1] + "がありません");
   }
   else
   {
    objFs.CopyFile(strSourceFolder + "\\" + strTemp, strDestinationFolder + "\\" + strTemp);//from,toの順
   }
  }
}while(!objTs.AtEndOfStream);

objTs.Close();
}

]]>
</script>
</job>
</package>

<このスクリプトの使い方>
copytsvn.batとほとんど変わりません。
作業フォルダで右クリック→tortoiseSVN→「変更をチェック」
として変更ファイル等を表示、copyしたいものをマウスでアクティブにして
右クリックで「クリップボードにパスをコピー」。
これを「パス」などファイル名以外がある行は削ってlist.txtとして保存、
作業フォルダが入っているフォルダに置く。
このスクリプトファイルを、作業フォルダが入っているフォルダに置き、スクリプト中の
SRC_FOLDERに元のフォルダ(上記のままなら"AAA")を、DST_FOLDERに出力フォルダ(上記のままなら"AAA_bk")を記述して保存する。
あとは実行(このスクリプトをクリック)するだけ。
(必要なフォルダを作りながらファイルをコピーします。)

| | コメント (0) | トラックバック (0)

2012年8月15日 (水)

svnのpre-lockスクリプト(windows)

pre-lockスクリプトではまったのでメモ。

ほかのhookではバッチファイルの実行結果が出ないのに、
何故かpre-lockではそのまま出てしまう
。これが災いしてエラーになる。
たとえば以下のように。

@echo off
rem "@echo off"は先頭に必要です。
set PATH=C:\Windows;C:\Windows\system32;

cscript //nologo %~dp0_pre-lock.wsf %1 %2 %3 %4 %5
if ERRORLEVEL 1 goto fail

:success
exit 0

:fail
exit 1

さらに上記では、wsfを呼び出している。そこももし表示するようにしていればエラーになるので注意。以下はその_pre-lock.wsfの内容。

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
<job id="SvnPreLock">
<?job error="True" debug="True" ?>
<object id="objFs" progid="Scripting.FileSystemObject" />
<script language="jscript">
<![CDATA[

//WScript.echo("OK!");//pre-lockではechoを出してはいけない
//WScript.Quit(1);//異常終了
WScript.Quit(0);//正常終了

]]>
</script>
</job>
</package>

追記:
上記にエラー処理も入れた場合、エラーのとき「ロックが pre-lock フックによって妨げられました (終了コード: 99)。出力はありません。」と出てしまいます。

何のエラーかわかるようにしたいと思い、無理やりバッチファイルでメッセージを標準エラーに出力。

@echo off
rem "@echo off"は先頭に必要です。
set PATH=C:\Windows;C:\Windows\system32;

cscript //nologo %~dp0_pre-lock.wsf %1 %2 %3 %4 %5
if ERRORLEVEL 2 goto fail
if ERRORLEVEL 1 goto fail1

:success
exit 0

:fail1
@echo on
echo コメントを入力してください。>&2
exit 99

:fail
exit 1

標準エラーに出力してもいいのかよくわかってませんが、とりあえず思惑通りの動き。
「ロックが pre-lock フックによって妨げられました (終了コード: 99)。出力:
コメントを入力してください。」のように表示されます。

| | コメント (0) | トラックバック (0)

2012年8月12日 (日)

WSHでプログラムを実行する際のコンソールウィンドウを非表示に

WSHでプログラムを実行して出力を受け取って
処理するものを考えていたのですが、
コンソールウィンドウがいちいち出てくるのが非常にうざったいので
非表示にする方法を検索。

WScript.ShellのExec()でコンソールアプリを非表示で実行する。
ドラッグ&ドロップされたファイルにまとめて何かする。

1番目はVBScript、2番目はJavaScript。
私にはJavaScriptのほうが少しだけとっつきやすいですが、
2番目をmodifyしてみてもなぜか表示されます。
(やり方に問題があるのでしょうけど)

結局、「Runのところで0にしないと非表示にならない」というだけ、
なんじゃないかと試したらとりあえず動作。
下がそのサンプル。

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
<job>
<?job error="True" debug="False" ?>
<script language="jscript">
// コンソールを非表示に(ここで「job id="SvnList"」を実行、非表示の対象とする)
var args = ['CScript.exe //job:exec', '"' + WScript.ScriptFullName + '"'];
for (var arg = new Enumerator(WScript.Arguments); !arg.atEnd(); arg.moveNext()) {
  args.push('"' + arg.item() + '"');
}
var shell = new ActiveXObject('WScript.Shell');
shell.Run(args.join(' '), 0, true);//->0で非表示
WScript.Quit(0);
</script>
</job>

<job id="exec">
<?job error="True" debug="True" ?>
<object id="objFs" progid="Scripting.FileSystemObject" />
<script language="jscript">
<![CDATA[

//svn listを実行してみる
var str1 =  exe1("\"C:\\Program Files\\TortoiseSVN\\bin\\svn.exe\" list -v \"file:///D:/rep/test/trunk\"")
//WScript.Echo(str1);
var current_dir = objFs.GetParentFolderName(WScript.ScriptFullName);
//WScript.Echo(current_dir);
var path = current_dir + "\\svn.txt";
filewrite1(path,str1);
//WScript.Echo(path);

function filewrite1(path,str)
{
var objFileSys = new ActiveXObject("Scripting.FileSystemObject");
if(!objFs.FileExists(path))
{
objFileSys.CreateTextFile(path);
}
var objOutFile = objFileSys.OpenTextFile(path ,2);//2は書き込み(上書き)
var splitstr = str.split("\n");
var i;
for(i=0;i<splitstr.length;i++)
{
objOutFile.WriteLine(splitstr[i]);
}
objOutFile.Close();
objOutFile = null;
objFileSys = null;
}
function exe1(cmd_path)
{
var shell = new ActiveXObject("WScript.Shell");
var exec = shell.Exec(cmd_path);
var out = '';
while (!exec.StdOut.AtEndOfStream)
{
  out += exec.StdOut.ReadLine() + "\n";
}
exec = null;
shell = null;
return(out);
}

]]>
</script>
</job>
</package>

ただ、Echoのコメントアウトをはずしてもメッセージが出ないのは、
そういうものなのでしょうか。
最初の<job>~</job>をはずせばもちろん表示されますけど。
→わかりました。Echoもコマンドプロンプトのほうに出力されているからですね。

| | コメント (0) | トラックバック (0)

2010年3月12日 (金)

flotのx2axisを使って

コミット数積算グラフプラグイン(その2)では
flot0.6を使って、milestoneを地味に表示させてみました。
この、上部にx2axisを使って文字列表示する
やり方を忘れないうちに書いておきます。

例えばflot0.6に入ってるbasic.htmlの

    $.plot($("#placeholder"), [ d1, d2, d3 ]);

    var tickdata = [[10, "AAA"], [20, "BBB"],[60, "CCC"],[90, "DDD"]];

    $.plot($("#placeholder"),
    [{ label: "d1", data: d1 },
     { label: "d2", data: d2 },
     { label: "d3", data: d3 },
     { label: "", data: [null] , xaxis: 2}],
    {x2axis: { min: 0 , max: 100 , ticks: tickdata }});

と書き換えます。

これをブラウザに表示すると、下のようになります。

Basic2

つまり、ラベルを追加して、グラフ上端の指定位置に
文字列をおくことができます。

こうするために、labelが""(これによりラベルが凡例に表示されない)、
dataをnull(これによりdataを非表示にする)にし、x2axisを使ってます。

tickdataには数字とそれを置き換えたい文字列を入れてます。

ここまでやってなんですけど、この文字列が長かったり、
文字列の間隔が狭いと重なってしまうのが…。

| | コメント (0) | トラックバック (0)