Saturday, October 30, 2010

Ho to get the Genius IpCam Secure300R working with any browser

A few days ago I bought the Genius IpCam Secure300R ip camera (do not confuse with Secure300 – it’s two different products). It was about twice chipper than other cams with the same features (I need camera with night view), but it turns out that it is very user unfriendly. The worst thing is that the camera’s web interface works only in IE under the Windows XP SP2 (not higher).

Fortunately, I found the way to get it working with any browser. The camera publishes an image in JPEG format at the special link (http://<camera-IP>/cgi-bin/getimage?java=2). So I wrote an html page (with JavaScript) that shows that image and refreshes it as frequently as it can.

I’ve tested it in FireFox 3.6.8, IE 8.0.7600.16385, Google Chrome 7.0.517.41, Opera 10.63. Unfortunately it doesn’t works in IE 7.0 under Windows XP (because it is unable to show the image from the address mentioned above – may be because of incorrect format of an image – I’ve seen somewhere the image doesn’t fully conforms to JPEG specification).

Here is a code of “custom web-interface” to Genius IpCam Secure300R. Save it to html file, replace baseUrl value by the address (and optionally port) of your camera (for example, http://192.168.1.58 or http://192.168.1.58:80) and enjoy!

<HTML>

<BODY onload="LoadLoginFrame()">

<P>
<img src="" id="webcam" />
</P>

<!-- workaround for IE 8 bug with onload event of a dymanically generated iframe -->
<span id="iframe_wrap"></span>

<script type="text/javascript">
<!--
// !!! REPLACE by your camera ip adress
var baseUrl = "http://your.camera.ip.address:port"

function LoadLoginFrame()
{

document.getElementById("iframe_wrap").innerHTML =
"<iframe id='loginFrame'" +
" src='" + baseUrl + "'" +
" style='display:none'" +
" onload='CredentialsEntered()'" +
"></iframe>";
}

function CredentialsEntered()
{
document.getElementById("iframe_wrap").innerHTML = "";

document.images.webcam.onload = LoadImage;
LoadImage();
document.images.webcam.onerror = OnImageError;

LoadIRFrame();
}

var i = 2;
function LoadImage()
{
document.images.webcam.src = baseUrl + "/cgi-bin/getimage?java=" + (i++);
}

function LoadIRFrame()
{
var frame = document.createElement("iframe");
frame.id = 'ir_frame';
frame.src = baseUrl + "/webcam_logoIROff.htm";
frame.setAttribute('width', 1047);
frame.setAttribute('scrolling', "no");
document.body.insertBefore(frame, document.body.firstChild);
}

function OnImageError()
{
document.images.webcam.style.display = "none";
alert("Couldn't get a picture!");
}
//-->
</script>

</BODY>
</HTML>

Tuesday, May 11, 2010

WiX: The meaning of MergeRedirectFolder variable

I faced with MergeRedirectFolder in the default merge module created by Votive (when you add new WiX Merge Module Project to your solution in Visual Studio).

I’ve failed to find any information about it. Even WiX documentation completely ignores it. So I’ve carried out the investigation.

Conclusion I’ve made:
MergeRedirectFolder refers to the directory where merge module files will be put according to Product installation scenario. In other words it refers to the directory referenced by Directory element to which Merege element belongs to in Product wix scenario file.

Here is scenario of my investigation.
Two files were created: one for msi and another for msm. After that I made a reference to msm (as it is suggested in WiX documentation)

Investigation.msi.wxs:
...
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder'>
<Directory Id='MyDir' Name='Test Program'>
<Directory Id='subDir' Name=’SubDir’>
<Merge Id='MyModule' Language='1033' src= ‘Investigation.msm' DiskId='1' />
</Directory>
</Directory>
</Directory>
</Directory>
...


Investigation.msm.wxs:
...
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="MergeRedirectFolder" FileSource="." >
<Component Id="ProductComponent" Guid="27af1a85-9a01-4c79-bdeb-d73fd4bd9574">
<File Name="readme.txt" />
</Component>
</Directory>
</Directory>
...


Then builded installation finished, readme.txt was in %ProgramFiles%\MyDir\subDir\ (according to Investigation.msi.wxs)

Second time I exclude MergeRedirectFolder directory from Investigation.msm.wxs:
...
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder'>
<Directory Id='MyDir' Name='Test Program'>
<Component Id="ProductComponent" Guid="27af1a85-9a01-4c79-bdeb-d73fd4bd9574">
<File Name="readme.txt" />
</Component>
</Directory>
</Directory>
</Directory>
...


And readme.txt changed it’s location to %ProgramFiles%\MyDir\. So it was put into directory set by Investigation.msm.wxs file and ignores directory in which it should be put according to Investigation.msi.wxs.

Tuesday, May 4, 2010

WiX: How to skip LicenseAgreementDlg – more elegant solution

According to WiX documentation if you want to remove the LicenseAgreementDlg from the WixUI_InstallDir dialog set, you suggested to copy the full contents WixUI_InstallDir.wxs from the WiX sources to your project and than manually edit it.
It isn’t very convenient way.
There is more elegant solution I have found here:

<UI>
<UIRef Id="WixUI_InstallDir" />
<!-- skip licence dialog -->
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg" Order="2">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">1</Publish>
</UI>

Because of a greater value in the Order attribute new events have priority over events, which were set up in WixUI_InstallDir.wxs to redirect to license dialog.

You can use the same technique to add your own manually created dialogs to the installation sequence.

Thanks to slashh!

Monday, April 26, 2010

How to install shared assembly into GAC using Inno Setup

Well... This is my first post about IT. From now I’m going to share my experience in troubleshooting problems I faced with. There are some reasons to do so. First of all I hope that this info would be helpful to other people. I often find answers to my tech questions at someone’s blog. It saves me a lot of time. So I feel responsibility to return this energy back to the World. If someone will find my post useful – I’ll reach the goal. Another reason is to practice my written English. My native language is Russian. But if I have a problem I prefer to google solution in English because, on my humble opinion, there are much more info available on English and it is more detailed than info on Russian (because English-speaking audience is much wider than Russian-speaking). So it is a good idea to share information (especially IT information) on English.

Now, let's begin.

Here the results of my investigation on how Inno Setup (I've used version 5.3.9 - latest at the moment) works with GAC.
First of all, it do allow to install assemblies in GAC (you should add gacinstall flag to the file). Inno also automatically uninstall assemblies from GAC during uninstall process.

If you forget to add StrongAssemblyName parameter to the file you will be prompted by setup compiler to do that. Note that full assembly name have to be ended by "ProcessorArchitecture=MSIL" in order the assembly to be uninstalled correctly.

But if you have more than one application using the same assembly from GAC you faced with a problem. Inno Setup (as opposed to WiX) doesn't support GAC reference counting mechanism. When both applications are installed and you uninstall one of them, Inno will remove assembly from GAC (that makes other app nonworking).

To solve this issue, you can use another Windows internal mechanism of reference counting which Inno Setup supports. You can apply sharedfile flag to the file and it will solve the issue. But you will get a small side effect. Two copies of the assembly will be installed: one in GAC and another in a destination folder of installed app. The reference counting mechanism is keep working even if the file is installed by two different apps in there own folders. Of course installers of both apps should be written on Inno Setup (I haven’t tested the case when one setup is .msi and another is made by Inno).

Another side effect – during uninstall you get a dialog that asks you whether shared assembly should be uninstalled or not (if an assemblies’ reference count become 0).

To wipe out this dialog you should add uninsnosharedfileprompt to the file’s list of flags.

Thereby to more or less reliably install an assembly into GAC by the help of Inno Setup you should add three attributes to the files in [Files] section of setup script: gacinstall sharedfile uninsnosharedfileprompt.

Example:

[Files]
Source: "Files\MyAssembly.dll"; DestDir: "{app}"; StrongAssemblyName: "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=48d60606109a2257, ProcessorArchitecture=MSIL"; Flags: "gacinstall sharedfile uninsnosharedfileprompt"

Last, I should say I haven’t tested the case of a shared assembly between two applications which written in different installation systems (for example WiX and Inno Setup), but suppose you will have some troubles if you are going to mix them up.