ラベル Programing の投稿を表示しています。 すべての投稿を表示
ラベル Programing の投稿を表示しています。 すべての投稿を表示

2007/01/23

via Proxy.

今日はフランスはパリ13区にお住まいの、Rachel Roblin(仮名)さんからの質問にお答えしたいと思います。

CSharpでWebBrowserControlを使った簡易なインターネットブラウザを作ってるんだけど、Proxyサーバーの設定方法がわからないんだ。

もちろん、Internet Explorerの設定を共有しているのは知ってるよ。だけど、FireFoxとIEの関係みたないに独立した設定がしたいんだ。

僕の作ったBrowserの為にIEの設定まで変更されてしまうのはどうかなと思うし。

不思議な事にControlのプロパティにもメゾッドにもそれらしき項目は無いんだよ。

何か方法はない?

こんなFrenchな人のFrankな質問メールですが、ちょっと調べてみましたが確かに該当するPropertyもMethodも無いんですね。

IEのコンポーネントになんて長いこと使ってなかったのですが、Urlmon.dllで確かって記憶が残ってました。実際に調べてみるとUrlMkSetSessionOptionとかで自プロセスで扱うコンポーネントのProxy設定とかが出来るようです。

C#はそれなりに便利にAPIを呼ぶ仕掛けが用意されているのですが、構造体とか入ってくるとちょっと難易度は上がります。というかかなり変態なコードになるので、通常のBusiness Logicなんか書いてあるファイルには書きたくない感じになります。

とりあえず、こんなコードを書いてみました。



using System;
using System.Runtime.InteropServices;

class urlmon
{
[DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
private static extern int UrlMkSetSessionOption(
int dwOption, IntPtr pIpi, int nLength, int dwReserved);

public enum InternetOpenType: int{
INTERNET_OPEN_TYPE_PRECONFIG = 0 // use registry configuration
,INTERNET_OPEN_TYPE_DIRECT = 1 // direct to net
,INTERNET_OPEN_TYPE_PROXY = 3 // via named proxy
,INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY = 4 // prevent using java/script/INS
}

private struct INTERNET_PROXY_INFO
{
public InternetOpenType dwAccessType;
public IntPtr proxy;
public IntPtr proxyBypass;
};

//
public static int InternetOptionProxy(InternetOpenType nOpenType)
{
return InternetOptionProxy(nOpenType,"","");
}

//
public static int InternetOptionProxy(InternetOpenType nOpenType
, string proxy, string proxyBypass)
{
const int INTERNET_OPTION_PROXY = 38;

INTERNET_PROXY_INFO ipi;
ipi.dwAccessType = nOpenType;
ipi.proxy = Marshal.StringToHGlobalAnsi(proxy);
ipi.proxyBypass = Marshal.StringToHGlobalAnsi(proxyBypass);

IntPtr pStruct = Marshal.AllocCoTaskMem(Marshal.SizeOf(ipi));
Marshal.StructureToPtr(ipi, pStruct, true);

return UrlMkSetSessionOption(INTERNET_OPTION_PROXY, pStruct, Marshal.SizeOf(ipi), 0);
}
}


クラス名とかはurlmon.dllを呼び出すコードを誰かが書き足してくれればという願いを込めて付けましたりしてますし、本来はPropertyとしてGet,Setを実装すべきだろうとは思いますが、自分で使わないのと説明がメインのコードなんで。

Function自体はstaticになっているので、以下のような感じでWebBrowserControlの貼ってあるFormのLoadイベントとかで呼び出せばいいんではないでしょうか。設定変更があるならば、その都度呼んでも良いと思いますし。

urlmon.InternetOptionProxy(urlmon.InternetOpenType.INTERNET_OPEN_TYPE_PROXY, "localhost:8080", "");

というわけでRachel 、また旨いワイン奢ってね。

続きを読む・・

2006/12/22

Blogger Widget (3) for Amazaon Associates.

クロスドメイン問題に行き詰っていたAmazon アフィリエイト向けのWidgetですが、専用の外部ファイルを必要としない形、つまりはWidget内完結型での最終形はこんな感じになりました。


<script type="text/javascript" language="javascript">
<!--
/* Script for Amazon Associates */

var MAX_ADS = 3;
var LABEL_WORD_FACTOR = 4;

cKeyWords=function(name,value){this.name=name;this.value=value};
cKeyWords.compare=function(a,b){return b.value-a.value};

var org=window["onload"];
window["onload"]=
(typeof org!="function"?
function(event){insertAds(document.body,'div','post-body')}:
function(event){insertAds(document.body,'div','post-body');org(event)});


function insertAds(elm,tagName,className){
var elms=elm.getElementsByTagName(tagName);

for(var i=0; i<elms.length;i++){
var e=elms[i];
if(e.getAttribute("className")==classNamee.getAttribute("class")==className){

var words = getKeywordsFromElement(e);
var labelWords = getLabelWords(e);

// Evaluate keywords by Label
for(var n=0;n<labelWords.length;n++)
if(words[labelWords[n]])
words[labelWords[n]]*=LABEL_WORD_FACTOR;

var wordList = sortKeywordsByPoint(words);


// for Debug...
for(var n=0,t="Keywords::Debug=";n<wordList.length;n++){
t=t+wordList[n].name+"["+wordList[n].value+"] ";
}
var eee=document.createElement("p");
eee.style.fontSize="75%";
eee.style.display="none";
eee.innerHTML=t;
e.appendChild(eee);

var eDiv = document.createElement("div");

for(var n=0;n<MAX_ADS&&n<wordList.length;n++){
var eSpan = document.createElement("span");
var eAd = document.createElement("iframe");
eAd.setAttribute("src"
, "http://rcm-jp.amazon.co.jp/e/cm?t=isawseash-22"
+ "&o=9&p=9&l=st1"
+ "&mode=books-jp"
+ "&search=" + encodeURI(wordList[n].name)
+ "&fc1=<1=&lc1=&bg1=&f=ifr");
eAd.setAttribute("scrolling","no");
eAd.setAttribute("frameborder","0");
eAd.setAttribute("border","0");
eAd.setAttribute("height","150");
eAd.setAttribute("width","180");
eAd.setAttribute("marginheight","0" );
eAd.setAttribute("marginwidth","0");

if (document.documentElement.getAttribute("style") == document.documentElement.style){
eAd.style.borderStyle ="none";
var s1 ="BORDER-TOP-STYLE: none; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"
var s2 = eAd.outerHTML;
s2 = s2.replace(s1,"border:none");
eSpan.innerHTML =s2;
}
else{
eAd.setAttribute("style","border:none;");
eAd = eSpan.appendChild(eAd);
}
eDiv.appendChild(eSpan);
}//__for(ads)
e.appendChild(eDiv);
}//__if
}//__for
}


function getKeywordsFromElement(elm){
var re = new RegExp;
re.compile("([A-Z]+[a-z0-9\.#\+-]+[ \.][A-Z0-9]+[a-z0-9\.#\+-]+)"
+"([A-Z]+[A-Za-z0-9\.\+#\-]+)([繧。-繝エ繝シ]+)","g");

var s = getPostDocumentText(elm,"(prescriptform)");

var token = s.match(re);
var rslt=new Array();

if(token){
for(var i=0;i<token.length;i++){
if( rslt[token[i]])
rslt[token[i]]++;
else
rslt[token[i]]=1;
}//__for
}//__if(token)

return rslt;
}//__function getKeyworksFromElement;

function getPostDocumentText(elm,exceptTagNames){
var sRslt="";
var re=new RegExp(exceptTagNames,"i");
for(var i=0;i<elm.childNodes.length;i++){
var e=elm.childNodes[i];
if(elm.childNodes[i].nodeType==1
&&!String(e.tagName).match(re)){
sRslt=sRslt+getPostDocumentText(e,exceptTagNames);
}
else if(e.nodeType==3){
sRslt=sRslt+e.nodeValue;
}
}//__for(childNodes)
return sRslt;
}

function sortKeywordsByPoint(keywords){
var wordList = new Array();
for( v in keywords)
if(typeof keywords[v]!="function")
wordList.push(new cKeyWords(v,keywords[v]));
wordList.sort(cKeyWords.compare);
return wordList;
}//__sortKeywordsByPoint

function getLabelWords(ePost){
var arRslt = new Array();

for(var eNext = ePost.nextSibling;eNext.nodeType!=1;eNext=eNext.nextSibling);
var eSpans = eNext.getElementsByTagName("span"); //Lable is in Span Elemnet.

for(var i=0; i<eSpans.length;i++){
var e=eSpans[i];
if(e.getAttribute("className")=="post-labels"e.getAttribute("class")=="post-labels"){
var eKeywords= e.getElementsByTagName("a");
for(var l=0;l<eKeywords.length;l++){
arRslt.push(eKeywords[l].innerHTML);
}
break;
}//__if
}//__for

return arRslt;
}//__getSearchKeyword
-->
</script>

そんなに特殊な事をしてるわけではなくて、ベタにキーワードを抽出というか、英単語とカタカナの単語を抜き出して出現回数で順位付け、それらの単語がLabelで使われている場合は倍率ドンって感じにして、上位から順にAmazon用のタグを作成して並べるって感じです。

例によって該当しないキーワードの場合は売れ筋商品が表示されたり、Books-jp指定しているだけなので、キーワードによっては不思議な書籍が表示されますが、それはそれで楽しめないようではダメですな。

BlogのPost(記事)に直接アフィリエイトなiframeとか埋めてしまうと、後で消すとか変更とか出来ませんが、Widgetにした事で動的な後付ですから変更が容易になるあたりが利点ではありますが、意図しない物が選択・表示されてしまう悲哀を背負っていますので、その辺りの改善は外部ファイル連携バージョンで対応する予定です。

外部に置くのはxslファイルにするか、それともRESTでJSONPな感じなAPIを用意するかは、まだ考え中ですが、最近のテーマは「素敵なGoogle生活」だったりするんで、場所もGoogle関係とするとGoogle Page Createtorとかになってしまうんで、Javascriptファイルやxslファイルは置けてもAPIの実装は無理だしとか。

続きを読む・・

2006/11/30

VS.Php for Visual Studio

PHPから離れて久しいですが、VS.Php for Visual Studio なんてのが出ているのに気づいてちょっと使って見たくなりました。

名前の通りにVisual StudioをIDEとして使うPHP開発用のFrontendなんですが、Zend Studioとかよりリーズナブルだし使い勝手で悩むことも少なそうだし、Eclipseさんはちょっと苦手なんでとか考えてる私には合いそうな予感はしています。

結構初期からVisual StudioのIDEは好きで、JavaなんかもわざわざVisual Studio上で書いてたりしてた時期もありました。(JDK1.2になっても)

PHPはPHP/FIというか2.0の頃から使ってはいたんですが、Perlと同じで余人にはお勧めできないというか部下に教えるとちょっとCodingの行儀が悪くなりそうだったりとかで個人的に以外は使ってきませんでしたけ。当時満足なDebug環境が無くPrintf的なDebug中心だった事も理由ではあります。

そいうわけで開発環境としてDebug環境まで整ったZend StudioとかVS.Phpとかってちょっといいかなとは思うのですが、ASP.NetのCode Behindとかを知ってしまうと、今更PHPか・・・・とも考えてしまう。 だってお洒落じゃないですか、Code-Behind。デザインとロジックが別ファイルで管理出来るんですから。

それと基本的にDynamic typing of variablesな言語ってあまり好きではないんですよね。分かってる人が書いたのはStaticなのよりも逆に読みやすく簡素だったりするんですが、世に氾濫してるのはDirtyなCodeの方が多数を占めてたりもしますから。 昔VBとかで随分泣かされましたし。これは型付けの問題というよりも未宣言の変数に対する問題も多かったですけど。他人のコードをDebugしていると、Spellミスの別の変数使ってたりとか・・。

続きを読む・・

2006/11/20

Windows Power Shell

PowerShellがいつの間にか正式版になってたので使って見ました。

単純に使うだけではなく、CommandLetを作ってみたないとか思ったのですが、どうしてかWindows PowerShell SDKをダウンロードする場所が見つかりません。PowerShell CMDLET Visual Studio 2005 Item Template なんてのも見つけたのですが、 とりあえずはSDKを探してます。ご存知の方いませんか?

SDKにCmdLetのBaseクラスとか入ってるとか思ってるんですが違うんですかね?

とか思ったら別にSDKとかなくても、using System.Management.Automationとか使えるから問題ないじゃん。

てな訳で、いくつか単機能的というかツール的なクラスをPowerShellから使ったり他のCmdLetにして組み合わせてたりしてみようかと。

やってみないと楽しいか or 詰まらないはわかりませんしね。

続きを読む・・

2006/10/10

Dual Head Display

正式名称(?) はなんて言えば良いのでしょうか?

私は今使ってるVideo Cardが、Matrox G450 Dual HeadなんでDual Headと呼んでしまいますが、単純にDual Display とかMulti Displayで良いのかな。

数年前なら贅沢感たっぷりの17LCDでのDual環境ですが、いまどきは大した金額もかからないし、OSが複数のVideo Cardの同時使用を見事にサポートしてくれるのでまったく珍しくありません。自宅の環境はAuctionで買い揃えたものばかりですが、LCD は 2万円程度が2台と本体も3万円もかかっていないというCheapさ。

ですけど、未だに少数派ですよね。LCD(液晶Display)への入れ替えとか、本体入れ替えと同時の新しいDisplayも買っちゃったりして、会社とかではDisplayが余ったり廃棄したりしてるんではないかと思うのですが、机のう上のスペースも限られてるからなのか、ディスプレイは一台のままの人多いですよね。

私の職場では机は十分に広い(21inch 二台も十分にいけるぐらい)なのと、余ったディスプレイを廃棄しようとしていたので、なんとかVideoカードを入手してDual Display環境にしています。
開発環境は特にDual Displayが効果あるんですけどね。Document見ながらCodingとか、実行中の画面を片側に出しながらDebugしたりとか。

費用対効果は絶大なのに何故にやらないのか。これは開発者ならびにその管理者・経営者が開発の作業効率に関して無頓着だからでしょうね。ノートPCの 1024x768の画面での開発作業と、17inch 1280 x1024がDualで開発とどれくらい作業効率が違うとか数値的に考えた事がないでしょうし。

私は業務系のコンサルティングをやってましたので、一つの作業にかかる時間とかに非常に興味があるというか注意がいくようになりました。何をすれば効率が上がるのかって事に。当然開発作業は作業者本人が考えないと・志向しないといけない部分がいまだ多分にあるので、単純作業のように純粋に肉体的な効率だけを考えていけばよいわけではないのですが、視覚を広げる、Diaplay の表示面積を広げる事は重要だと思います。

私にしてみれば、いまだにTouch Typing(旧称Blind Touch)が出来ない人とかはちょっと勘弁してほしいです。Touch Typingできないが故に、コメントか書かないとか、Copy and Pasteでコード書く事が多くて、それが逆に見ていてイライラするぐらい、時間はかかるは直さなければいけない部分を忘れたり。変数名やファンクション名は第三者から見たら意味の分からない略語ばかり。そんなソースコードを書く人と一緒に仕事するのは辛いです。

Joel on Software "http://japanese.joelonsoftware.com/Articles/TheJoelTest.html" とか読んで欲しいです。
特に、"8. プログラマは静かな労働環境にあるか?" って大事じゃない?
>広く書かれていることだが、生産的な利益は、知識労働者に空間と
>静かさとプライバシーを与えることによってもたらされる。古典的なソ
>フトウェア管理の本「ピープルウェア」はこれらの生産性が広範囲に
>渡ることを述べている

もう、顧客からの質問の電話がかかってくるだけで、集中は途切れてしまうし、まわりの動きだって気になる。そんなものは生産性・効率の面からいったら排除すべき問題なのに、そういった事にまったく無頓着な職場はどうなんでしょう?

続きを読む・・