2007年12月11日火曜日

D言語で相対パスを絶対パスに変換するの巻(コマンドプロンプトでコンテキストメニューを開く)

 コマンドプロンプトで普段の作業をするときに困ってしまうのが、ファイルのプロパティとか見るとき。普通にマウスを使えば右クリックで簡単に見ることができるのですが、CUIからだと、もうどうしようもない。

 そんな中、見つけたのがここにあった「単機能ツール集」の「コンテキストメニュー」です。これさえあれば、コマンドプロンプトでコンテキストメニューが開ける!・・・と思ったのも束の間。なんと、このツールは絶対パスしか引数で受け取ってくれなかったのです。もともと、そんな使い方は想定されていなかったのかな?

 という訳で、必要なら自分で作ってしまおう、と相対パス->絶対パスの変換ツールを作ってみました。

toabs.d

import std.stdio;
import std.string;
import std.file;
import std.path;
import std.process;

void main(string[] args){

if(args.length < 2)
return;

if(args.length < 3){
// path only
string path = get_abs_path(args[1]);
if(find(path," ") != -1)
path = "\"" ~ path ~ "\"";
printf(std.file.toMBSz(path));

} else {
// include command
string path[];
path.length = args.length - 2;
foreach(i, p; args[2 .. $]){
path[i] = get_abs_path(p);
if(find(path[i], " ") != -1)
path[i] = "\"" ~ path[i] ~ "\"";
}

string com = args[1] ~ " ";
foreach(p; path){
com ~= p;
com ~= " ";
}
execute(com);
}
}

string get_abs_path(string path){

if(isabs(path))
return path;

string atm[] = split(path, "\\");
int loc;

path = getcwd();

foreach(s; atm){
switch(s){
case ".":
// current directory
break;
case "..":
// parent directory;
loc = rfind(path, "\\");
path = path[0 .. loc];
break;
default:
// add
path = join(path, s);
break;
}
}

// drive letter only
if(getDrive(path) == path)
path ~= "\\";

return path;

}

// utf8 -> sjis
private void execute(string text){

char* c = cast(char*)std.file.toMBSz(text);
char[] sjis;

for(int i=0; *c!=0x00; i++){
sjis.length = i+1;
sjis[i] = *c;
c++;
}

string com = cast(string)sjis;
system(com);
}

 引数1つの場合は、絶対パスに変換して返します。引数が2つ以上の場合は、最初の引数をコマンドと解釈して、以下に続くパスを絶対パスに変換して実行します。
 実際はこんな感じのバッチファイルを作成して利用しています。結構快適です。

toabs.bat

toabs.exe ContextMenu.exe %*

0 件のコメント: