Currently I am working on a web page which will tell user about certain configurations on client machine. Out of this there is also requirement of detecting if Adobe Reader is installed on client machine or not. I am using ASP.NET/C#.
I have looked the following url for the answer
"Check Adobe Reader is installed (C#)?" but the code look into the server registry entires where IIS is installed and not the client machine where browser is running.
Is it possible to detect if Adobe reader is installed on client machine and not the server which is hosting the website?
pls, check the script below, it worked fine for me in IE, FireFox and Chrome
<html>
<body>
<script type="text/javascript">
var found = false;
var info = '';
try
{
acrobat4 = new ActiveXObject('PDF.PdfCtrl.1');
if (acrobat4)
{
found = true;
info = 'v. 4.0';
}
}
catch (e)
{
//???
}
if (!found)
{
try
{
acrobat7 = new ActiveXObject('AcroPDF.PDF.1');
if (acrobat7)
{
found = true;
info = 'v. 7+';
}
}
catch (e)
{
//???
}
if (!found && navigator.plugins && navigator.plugins.length>0)
{
for (var i = 0; i<navigator.plugins.length; i++)
{
if (navigator.plugins[i].name.indexOf('Adobe Acrobat') > -1)
{
found = true;
info = navigator.plugins[i].description + ' (' + navigator.plugins[i].filename + ')';
break;
}
}
}
}
document.write("Acrobat Reader Installed : " + found);
document.write("<br />");
if (found) document.write("Info : " + info);
</script>
</body>
</html>
hope this helps, regards
I used this script and called it on ready function :
Note: i used the alerts here just to know how to use it.
<script type="text/javascript">
$(document).ready(function () {
alert(getAcrobatInfo().browser);
alert(getAcrobatInfo().acrobat === "installed");
alert(getAcrobatInfo().acrobatVersion);
});
var getAcrobatInfo = function () {
var getBrowserName = function () {
return '<%=Session["browser"].ToString()%>';
};
var getActiveXObject = function (name) {
try { return new ActiveXObject(name); } catch (e) { }
};
var getNavigatorPlugin = function (name) {
for (key in navigator.plugins) {
var plugin = navigator.plugins[key];
if (plugin.name == name) return plugin;
}
};
var getPDFPlugin = function () {
return this.plugin = this.plugin || function () {
if (getBrowserName() == 'ie' || getBrowserName().toLocaleLowerCase() == 'internetexplorer') {
//
// load the activeX control
// AcroPDF.PDF is used by version 7 and later
// PDF.PdfCtrl is used by version 6 and earlier
return getActiveXObject('AcroPDF.PDF') || getActiveXObject('PDF.PdfCtrl');
}
else {
return getNavigatorPlugin('Adobe Acrobat') || getNavigatorPlugin('Chrome PDF Viewer') || getNavigatorPlugin('WebKit built-in PDF') || getWebKitPlugin();
}
}();
};
var getWebKitPlugin = function () {
for (var key in navigator.plugins) {
var plugin = navigator.plugins[key];
if (plugin.name && plugin.name.substring(0, 6) == "WebKit" && (plugin.name.indexOf("pdf") != -1 || plugin.name.indexOf("PDF") != -1)) return plugin;
}
};
var isAcrobatInstalled = function () {
return !!getPDFPlugin();
};
var getAcrobatVersion = function () {
try {
var plugin = getPDFPlugin();
if (getBrowserName() == 'ie' || getBrowserName().toLocaleLowerCase() == 'internetexplorer') {
var versions = plugin.GetVersions().split(',');
var latest = versions[0].split('=');
return parseFloat(latest[1]);
}
if (plugin.version) return parseInt(plugin.version);
return plugin.name
}
catch (e) {
return null;
}
}
// The returned object
return {
browser: getBrowserName(),
acrobat: isAcrobatInstalled() ? 'installed' : false,
acrobatVersion: getAcrobatVersion()
};
};
</script>
Also add this code behind:
public void detectBrowser()
{ //Set the Browser session variable
System.Web.HttpBrowserCapabilities browser = Request.Browser;
Session["Browser"] = browser.Browser;
}
Hope it helps.
Related
This case should be very simple, but I have a little bug that I don't know how to solve. I'm working with a Xamarin.Forms app that does some API calls to a localhost API running in my PC. This is the main part of the API call:
try
{
HttpClient client = new HttpClient();
client.MaxResponseContentBufferSize = BUFFER_SIZE;
client.DefaultRequestHeaders.Add(CULTURE_ID, "es");
client.DefaultRequestHeaders.Add(VALUE, LAST_WEEK_VALUE);
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(BEARER, token);
var content = new StringContent("", System.Text.Encoding.UTF8, APPLICATION_JSON);
HttpResponseMessage response = await client.GetAsync(url);
var result = await response.Content.ReadAsStringAsync();
List<SubProductParser> prices;
try
{
prices = JsonConvert.DeserializeObject<List<SubProductParser>>(result);
}
catch
{
// exception missin the final character in JSON "]"
}
return prices.ElementAt(0);
}
catch
{
return null;
}
The content of the result variable before trying to do the deserialize:
As you can see is not a valid JSON format, is strange because as you can see in the next screenshot when I do the same API call with POSTMAN is working always perfectly, but I don't know why sometimes doesn't receive all the JSON content when I do the call in the app.
Any idea, seeing the variable result content in debug, sometimes doesn't have the final character of the JSON "]", the API call is made after a button tapped in this way:
private async void Handle_Item_Tapped(object sender, ItemTappedEventArgs e)
{
var selected = e.Item as ProductParser;
var lastPrice= await ApiConnector.GetLastWeekSubProductPrices(
App.ViewModel.LoginViewModel.SesionToken,
subCatViewModel.Selected.ProductId,
subCatViewModel.Selected.Id);
await subCatViewModel.IsFavorite();
subCatViewModel.BarViewModel.Selected = selected;
subCatViewModel.BarViewModel.Categories = _categories;
subCatViewModel.LinearViewModel.Selected = selected;
subCatViewModel.LinearViewModel.Categories = _categories;
await Navigation.PushAsync(new Graphs(subCatViewModel));
}
The API functions that implement this API call, the API is developed in Larvael using php. I tried to simplify them as much as possible:
public static function getLastWeekPrices($cultureId)
{
self::initialize();
$year = self::getLastYear();
$prejson = json_encode(DB::table('product')
->join(SOME_CONDITIONS..)
...
->where(SOME_CONDITIONS..)
...
->select(SOME_ROWS)
->get());
$currentWeek = self::getCurrentWeek();
$json_decoded = json_decode($prejson, true);
$json_final = array();
foreach ($json_decoded as $slider_value)
{
$max_week= DB::table(SOME_CONDITIONS)
->max(SOME_CONDITIONS);
$last_week_price = json_encode(SOME_CONDITIONS)
...
->get());
...
//ADDING SOME VALUES TO $slider_value
...
array_push($json_final, $slider_value);
}
return json_encode($json_final);
}
public static function subProductsPricesQuery($id, $subId, $cultureId, $values)
{
self::initialize();
if (self::doesCultureExist($cultureId)){
if ($values == self::LAST_WEEK) {
$json = self::getLastWeekSubProductPrices($id, $subId, $cultureId);
}
....
}
}
public function FunctionCalledInAPIRoute(Request $request, $id, $subId)
{
try{
$user = JWTAuth::parseToken()->toUser();
$json = DatabaseQuerys::subProductsPricesQuery($id, $subId, $request->header("cultureId"), $request->header("value"));
return self::jsonIsEmpty($json);
}catch(JWTException $e){
return $this->respondInternalError("Any token found!");
}
}
public static function jsonIsEmpty($products)
{
self::initialize();
$initial = $products[0] === "[" ? TRUE : FALSE;
$final = $products[1] === "]" ? TRUE : FALSE ;
if (strlen($products) === 0 || ($initial == TRUE && $final == TRUE))
{
header('Content-type:application/json;charset=utf-8');
return (new self)->respondNotFound("Any result found in this category");
} else {
header('Content-type:application/json;charset=utf-8');
return $products;
}
}
The JsonIsEmpty is a little method that I create to control if the database return something, if not as the functions return json_encoder($array), always will be [].
The content of the variable result when receives the faulty JSON:
[
{
"id": 19,
"name": "Conejo de más de 2125 gr",
"units": "€/Kg",
"price": "1.91",
"week": 10,
"year": 2019,
"last_price": "1.79",
"difference": "0.12",
"arrow": "up_arrow.png"
}
As you can see is missing the closing "]".
I implemented a little test to see if the app is working fine, the test function and the function that calls it:
public static function jsonIsEmptyTest($products)
{
self::initialize();
$initial = $products[0] === "[" ? TRUE : FALSE;
$final = $products[1] === "]" ? TRUE : FALSE ;
if (strlen($products) === 0 || ($initial == FALSE && $final == FALSE))
{
return 1;
} else {
return 0;
}
}
public static function the foo(....)
{
$correct = 0;
$wrong = 0;
for($x = 0; $x < 1000; $x++)
{
$json = DatabaseQuerys::subProductsPricesQuery($id, $subId, $request->header("cultureId"), $request->header("value"));
print_r($json);
print_r("\n\n");
$result = JsonController::jsonIsEmptyTest($json);
if($result == 0)
{
$correct = $correct + 1;
}
if($result == 1)
{
$wrong = $wrong + 1;
}
}
print_r("Correct: ");
print_r($correct);
print_r("\n");
print_r("Wrong: ");
print_r($wrong);
exit();
}
Doing the API call with postman the result is:
Trying to jQuerify CEF browser in winform solution but the script is not executing, tried many methods but still it didn't work.
I am executing the script in the LoadingStateChanged .. already installed cefsharp from Nuget packages solution !
if there is another option better than CEFsharp please recommend !
string script = #"(function () {
// more or less stolen form jquery core and adapted by paul irish
function getScript(url, success) {
var script = document.createElement('script');
script.src = url;
var head = document.getElementsByTagName('head')[0],
done = false;
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function () {
if (!done && (!this.readyState
|| this.readyState == 'loaded'
|| this.readyState == 'complete')) {
done = true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
getScript('http://code.jquery.com/jquery-latest.min.js', function () {
if (typeof jQuery == 'undefined') {
console.log('Sorry, but jQuery wasn\'t able to load');
} else {
console.log('This page is now jQuerified with v' + $.fn.jquery);
$(document).ready(function () {
alert(1);
//here you can write your jquery code
});
}
});
})();";
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate {
LoginchromeBrowser.ExecuteScriptAsync(script);
LoginchromeBrowser.EvaluateScriptAsync(script).ContinueWith(x =>
{
var response = x.Result;
if (response.Success && response.Result != null)
{
var startDate = response.Result;
MessageBox.Show(response.Result.ToString());
//startDate is the value of a HTML element.
}
});
});
}
else
{
LoginchromeBrowser.EvaluateScriptAsync(script).ContinueWith(x =>
{
var response = x.Result;
if (response.Success && response.Result != null)
{
var startDate = response.Result;
MessageBox.Show(response.Result.ToString());
//startDate is the value of a HTML element.
}
});
}
Please help me out by sharing the step by step procedure to achieve the scanning functionality using Twain in ASP.Net MVC5. Thank you
Solution is here:
In ASP.Net/Core Project you send message to call winform project:
var start = function () {
var i = 0;
var wsImpl = window.WebSocket || window.MozWebSocket;
window.ws = new wsImpl('ws://localhost:8181/');
ws.onmessage = function (e) {
$('#submit').hide();
$('#scanBtn').hide();
$('.loader').show();
if (typeof e.data === "string") {
//IF Received Data is String
}
else if (e.data instanceof ArrayBuffer) {
//IF Received Data is ArrayBuffer
}
else if (e.data instanceof Blob) {
i++;
var f = e.data;
f.name = "File" + i;
storedFiles.push(f);
formdata.append(f.name, f);
var reader = new FileReader();
reader.onload = function (e) {
var html = "<div class=\"col-sm-2 text-center\"
style=\"border: 1px solid black; margin-left: 2px;\"><img
height=\"200px\" width=\"200px\" src=\"" + e.target.result + "\"
data-file='" + f.name + "' class='selFile' title='Click to
remove'><br/>" + i + "</div>";
selDiv.append(html);
$('#submit').show();
$('#scanBtn').show();
$('.loader').hide();
}
reader.readAsDataURL(f);
}
};
ws.onopen = function () {
//Do whatever u want when connected succesfully
};
ws.onclose = function () {
$('.dalert').modal('show');
};
}
window.onload = start;
function scanImage() {
ws.send("1100");
};
https://javascript.info/websocket
In Winforms Project you scan document and send graphic data back to Asp.Net/Core project:
public partial class Form1 : Form
{
ImageCodecInfo _tiffCodecInfo;
TwainSession _twain;
bool _stopScan;
bool _loadingCaps;
List allSockets;
WebSocketServer server;
public Form1()
{
InitializeComponent();
if (NTwain.PlatformInfo.Current.IsApp64Bit)
{
Text = Text + " (64bit)";
}
else
{
Text = Text + " (32bit)";
}
foreach (var enc in ImageCodecInfo.GetImageEncoders())
{
if (enc.MimeType == "image/tiff") { _tiffCodecInfo = enc; break; }
}
this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;
allSockets = new List<IWebSocketConnection>();
server = new WebSocketServer("ws://0.0.0.0:8181");
server.Start(socket =>
{
socket.OnOpen = () =>
{
Console.WriteLine("Open!");
allSockets.Add(socket);
};
socket.OnClose = () =>
{
Console.WriteLine("Close!");
allSockets.Remove(socket);
};
socket.OnMessage = message =>
{
if (message == "1100")
{
this.Invoke(new Action(()=> {
this.WindowState = FormWindowState.Normal;
}));
}
};
});
}
Link to project.
https://github.com/mgriit/ScanAppForWeb
You can remake this project, as you want.
At this moment, none of the browsers support scanning out of the box. You need to use a third-party library (not part of Microsoft's .NET core components). Below example uses Scanner.js, which is a product offered by our company:
Enable Scanning from TWAIN Scanners to ASP.NET Pages: Step by Step
Below steps use Scanner.js as example; they may differ for other products.
1) Include the scanning library in your HTML code:
<script type="text/javascript" src="//asprise.azureedge.net/scannerjs/scanner.js"></script>
2) Add a button to trigger the scanning process:
function scanToJpg() {
scanner.scan(displayImagesOnPage,
{
"twain_cap_setting" : {
"ICAP_PIXELTYPE" : "TWPT_RGB", // Color
"ICAP_XRESOLUTION" : "100", // DPI: 100
"ICAP_YRESOLUTION" : "100",
"ICAP_SUPPORTEDSIZES" : "TWSS_USLETTER" // Paper size: TWSS_USLETTER, TWSS_A4, ...
},
"output_settings" :
[
{
"type" : "return-base64",
"format" : "jpg"
}
]
}
);
}
3) Handle the scan result - display, upload, etc.
Below code creates an img element for each image scanned to display on the current web page:
/** Processes the scan result */
function displayImagesOnPage(successful, mesg, response) {
var scannedImages = scanner.getScannedImage(response, true, false); // returns an array of ScannedImage
for(var i = 0; (scannedImages instanceof Array) && i < scannedImages.length; i++) {
var scannedImage = scannedImages[i];
processScannedImage(scannedImage);
}
}
/** Images scanned so far. */
var imagesScanned = [];
/** Processes a ScannedImage */
function processScannedImage(scannedImage) {
imagesScanned.push(scannedImage);
var elementImg = createDomElementFromModel( {
'name': 'img',
'attributes': {
'class': 'scanned',
'src': scannedImage.src
}
});
document.getElementById('images').appendChild(elementImg);
}
For examples of scanning into PDF formats and direct uploading, please visit the code repository: https://github.com/Asprise/scannerjs.javascript-scanner-access-in-browsers-chrome-ie.scanner.js
I'm using javascript to set the value of a cookie when I open the debugger panel so that if the user has already opened it, it will automatically open when they reload the page.
Here is the javascript:
jQuery(document).ready(function () {
DebuggingPanel.init(jQuery);
DebuggingPanel.GetPanelState();
});
DebuggingPanel.GetPanelState = function () {
jQuery.ajax({
url: "/sitecore modules/DebuggingPanel/DebuggingPanel.asmx/GetPanelState",
type: 'POST',
success: function(data) {
if (data.open === true) {
DebuggingPanel.TogglePanel();
}
}
});
}
DebuggingPanel.TogglePanel = function (changeState) {
var tinyDiv = $('.debuggingPanel.tinyDiv');
if (tinyDiv.text() == '+') {
tinyDiv.text('-');
DebuggingPanel.GetInformation();
DebuggingPanel.panel.slideDown();
interval = setInterval(DebuggingPanel.GetInformation, 5000);
if (changeState) {
DebuggingPanel.SetPanelState("open");
}
} else {
tinyDiv.text('+');
DebuggingPanel.panel.slideUp();
clearInterval(interval);
if (changeState) {
DebuggingPanel.SetPanelState("closed");
}
}
};
tinyDiv.click(function () {
DebuggingPanel.TogglePanel(true);
});
And here are the methods related to the cookie:
public void SetPanelState(string state)
{
var panelCookie = HttpContext.Current.Response.Cookies["PanelState"];
if (panelCookie == null)
{
panelCookie = new HttpCookie("PanelState") {Value = state};
HttpContext.Current.Response.Cookies.Add(panelCookie);
}
else
{
HttpContext.Current.Response.Cookies["PanelState"].Value = state;
}
}
[ScriptMethod(ResponseFormat = ResponseFormat.Json), WebMethod(EnableSession = true)]
public void GetPanelState()
{
var panelCookie = HttpContext.Current.Response.Cookies["PanelState"];
var data = new PanelState(){open = false};
if (panelCookie == null || panelCookie.Value == null)
{
data.open = false;
}
else if (panelCookie.Value == "open")
{
data.open = true;
}
WriteOut(data);
}
In debugging the cookie looks as though it is getting the value correctly, but the next time I go into GetPanelState(), panelCookie.Value is always "" (not "open" as it should be, or "closed", which would indicate it was set by the toggle).
This happens when I reload the page, and it also happens when I call GetPanelState() at the end of SetPanelState(); panelCookie.Value = "open" in SetPanelState() but then equals "" in GetPanelState()
When you are reading from the Cookie, you need to use the Request instead of the response. So your code will be as follows:
public void SetPanelState(string state)
{
var panelCookie = HttpContext.Current.Response.Cookies["PanelState"];
if (panelCookie == null)
{
panelCookie = new HttpCookie("PanelState") {Value = state};
HttpContext.Current.Response.Cookies.Add(panelCookie);
}
else
{
HttpContext.Current.Response.Cookies["PanelState"].Value = state;
}
}
[ScriptMethod(ResponseFormat = ResponseFormat.Json), WebMethod(EnableSession = true)]
public void GetPanelState()
{
//It is here that you are reading the cookie.
var panelCookie = HttpContext.Current.Request.Cookies["PanelState"];
var data = new PanelState(){open = false};
if (panelCookie == null || panelCookie.Value == null)
{
data.open = false;
}
else if (panelCookie.Value == "open")
{
data.open = true;
}
WriteOut(data);
}
Thanks
I have the following script in an page called ajax.aspx page:
<script type="text/javascript">
$(document).ready(function () {
var nameFoundMessage = $('#nameFoundMessage');
var nameInput = $('#name');
nameFoundMessage.hide();
nameInput.blur(function () {
if ($(this).val()) {
$.getJSON('Services/ArtistFound.aspx?' + escape($(this).val()), function (results) {
if (results.available) {
if (nameFoundMessage.is(':visible')) {
nameFoundMessage.html('The name was found');
}
}
else {
nameFoundMessage.show();
nameFoundMessage.html('The name was not found');
}
});
}
});
});
</script>
The page has an input field with an id of "name" and when I blur off of that it goes into a service folder which has another aspx page ArtistFound.aspx and in that Page load, I have the following:
Response.ContentType = "application/json";
string name = Request.QueryString.ToString();
string output = string.Empty;
name = db.Names.Single(x => x.Name== name).Name;
if(name == null)
{
output = "{available:false}";
}
else
{
output = "{available:true}";
}
Response.Write(output);
}
When I run the page and blur off the input, it says the following:
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
I have tried ../Services/ArtistFound.aspx... and /Services/ArtistFound.aspx..., but it still gives me the same error.
You want:
name = db.Names.FirstOrDefault(x => x.Name== name);
if(name != null && name.Name != null)
{
output = "{available:true}";
}
else
{
output = "{available:false}";
}
This will return null if it is not found rather than throwing an exception like Single() does.
I would also recommend you use an ASHX handler rather than an ASPX page to do this call.
To do this you just add a 'Generic Handler' file in visual studio then you can put replace the ProcessRequest method with this:
public void ProcessRequest(HttpContext context)
{
string name = context.Request.QueryString.ToString();
string output = string.Empty;
name = db.Names.FirstOrDefault(x => x.Name == name);
if (name != null && name.Name != null)
{
output = "{available:true}";
}
else
{
output = "{available:false}";
}
context.Response.ContentType = "application/json";
context.Response.Write(output);
}