Google Fonts API for C# - System.AccessViolationException - c#

I'm trying to do a call to the Google API Services (specifically Google.Apis.Webfonts.v1.WebfontsService) from a C# console application. And each time i'm getting the very same exception:
An unhandled exception of type 'System.AccessViolationException' occurred in mscorlib.dll
Additional information: Attempted to read or write protected memory.
This is often an indication that other memory is corrupt.
My complete test application code is below and the google api is added as NuGet packages. I'm using the latest version of the API NuGet packages and i'm targeting .Net 4.5 on windows 8.1 and VS2013 sp4:
using Google.Apis.Services;
using Google.Apis.Webfonts.v1;
using Google.Apis.Webfonts.v1.Data;
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// create the service
var service = new WebfontsService(new BaseClientService.Initializer
{
ApplicationName = "Webfonts Sample",
ApiKey = "my private api key",
});
// run the request
var result = service.Webfonts.List().Execute();
// display the results
if (result.Items != null)
{
foreach (Webfont font in result.Items)
{
Console.WriteLine(font.Family);
}
}
}
}
}
The same problem exist for any API call to Google.Apis. So this made me think it's not directly related to the Webfonts, but to the BaseClientService.
I tried to solve it by running it in 32bit mode, but this didn't help me. Next, instead of nuget packages i used the source version of the api and tried to debug it. So i got to the point where the exception is thrown, but still can't see how it's been generated.
Did anybody encounter this problem before and able to resole it. And how?
UPDATE: the same code runs fine on other boxes with the same setup.

I just tested it and it worked fine for me.
You need the following NuGet Packages.
Install-Package Google.Apis.Webfonts.v1
Install-Package Google.Apis.Auth
Usings
using Google.Apis.Webfonts.v1;
using Google.Apis.Webfonts.v1.Data;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
Auth
/// <summary>
/// Used for accessing public api data.
/// </summary>
/// <param name="apiKey">Public API key from Google Developers console</param>
/// <returns>a valid WebfontsService</returns>
public static WebfontsService AuthenticatePublic(string apiKey)
{
if (string.IsNullOrEmpty(apiKey))
throw new Exception("apiKey is required.");
try
{
// Create the service.
var service = new WebfontsService(new BaseClientService.Initializer()
{
ApiKey = apiKey,
ApplicationName = "Webfonts Authentication Sample",
});
return service;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
throw ex;
}
}
Request Method
/// <summary>
/// Retrieves the list of fonts currently served by the Google Fonts Developer API
/// Documentation: https://developers.google.com/fonts/docs/developer_api/v1/webfonts/list
/// </summary>
/// <param name="service">Valid authentcated WebfontsService</param>
/// <returns></returns>
public static WebfontList list(WebfontsService service)
{
try
{
var request = service.Webfonts.List();
return request.Execute();
}
catch (Exception ex)
{
Console.WriteLine("Request Failed " + ex.Message);
throw ex;
}
}
Putting it all together
var service = StandardGoogleAuth.AuthenticatePublic("Your Public API key");
var result = WebfontsSample.list(service);
if (result.Items != null)
{
foreach (var font in result.Items)
{
Console.WriteLine(font.Family);
}
}

Related

Separate Logging Flow From Web Service Method Flow && Logging In Background With Queue

I have simple web service method which log to ElasticSearch DB like as below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
/// <summary>
/// used for user sample operation
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class SampleWebServiceClass : System.Web.Services.WebService
{
public SampleWebServiceClass() {
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public string SampleWebServiceMethod()
{
string status = String.Empty;
string statusCode = String.Empty;
string returnResult = String.Empty;
try
{
//Get Data From Oracle DB
returnResult = GetDataFromOracleDB();
}
catch(Exception exc)
{
status = exc.Message;
statusCode = "-1";
}
finally {
//create elastic search log with status and statusCode
CreateElasticSearchLog();
}
return returnResult;
}
private string GetDataFromOracleDB() {
////Go Oracle Database And Get Data
}
private void CreateElasticSearchLog(string status, string statusCode)
{
//create elastic search db log with status and statuscode
try
{
//Create Log To ElasticSearch DB
}
catch(Exception exc) {
////Create Log To Oracle DB
}
}
}
My Web Service create elasticsearch log for all method states ( success, exception vs..). If log method get errror and then it logs to oracle db in catch block.
All problems are experienced when too many simultaneous requests come to the service method.
The response of the service method is very slow and the elastic search logging method fails and writes some of the logs to oracledb. The service method gives a response in a very long time.
We have questions like as below:
1--> How can we make the service method not wait for logging to return the response ?
2--> How can we detect logging with a queue structure at the background ? We want logging not to affect the response of the service.
3--> Is it possible to install a queue structure on iis? In other words, can a thread be sent to the queue on iis from the web service method and logs can be made on the back side with the queue structure?
Our aim is to separate the logging from the web service method flow and to make the service method capable of rapid response.
Thanks a lot for your suggestions.
To be able to separate the logging from the web service method flow and make the service method capable of rapid response

Windows service exits with code 0 and no errors even though it hasn't done its thing

I have a windows service that calls a web API service. All the API calls have been tested and work as they should.
What happens is the service runs a particular piece of code that sends data to the API. Its supposed to return and continue round the loop. What it does is just stop. The JSon has been sent to the API with fiddler and works fine.
Here is the offending code :-
public async Task<WorkOrderCreationResponseDto> ImportWorkOrders(WorkOrderCreationRequestDto request)
{
try
{
WorkOrderCreationResponseDto resp = await RestClient.PostAsync<WorkOrderCreationRequestDto, WorkOrderCreationResponseDto>(string.Format("{0}/WorkOrders", Resource), request);
return resp;
}
catch (Exception ex)
{
throw ex;
}
}
Now the code gets to the await line. At this point the code exits with code 0. It never hits the return and no error is trapped in the catch.
Can anyone explain why this happens as I am at a complete loss after a morning trolling round google trying to make sense of it all.
Anything that can shed some light on this would be greatly appreciated.
The environment is Windows 10 anniversary update and Visual Studio 2015. We are coding in c#.
Thanks
Steve
ADDED IN RESPONSE TO COMMENT
We build a data object which is wo in the code below. _rest contains the user credentials for the API.
using (SopImportDataService service = new SopImportDataService(_rest))
{
string jsonString = JsonConvert.SerializeObject(wo);
//WorkOrderCreationResponseDto c = await service.ImportWorkOrders(wo);
await service.ImportWorkOrders(wo);
Console.WriteLine("");
}
Thanks to Glorin for pointing me in the right direction. The problem was Main in the Progrm.cs file is not Async. We have used the AsyncEx library by Stephen Cleary, and altered the program.cs to look like this :-
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
try
{
AsyncContext.Run(() => MainAsync());
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
}
static async Task MainAsync()
{
#if (!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new UnityService()
};
ServiceBase.Run(ServicesToRun);
#else
UnityService myServ = new UnityService();
//myServ.SetupService().ConfigureAwait(true);
await myServ.BeginService();
#endif
}
These changes seem to have solve dour issue.
Thanks again everyone

Debugging Program Keeps Sending Emails After Exit

I have the below code which I use as part of a program which reads some event logs.
After stepping through the code this morning to test something out, I keep getting error messages emailed to me:
EventLogHelper error occurred in QueryEvents
Exception: The RPC server is unavailable
User:
Client: D7-089
The process is not running on my machine, and I only stepped through the method in question once or twice. However The messages just keep coming. The space of time between each message seems to vary, and I have received at least 15 now.
How is this possible? I feel that if the program is sending me emails, it must be executing somewhere, but I cannot see it in the Processes tab in Task Manager, and I tried ending all Visual Studio related processes without any joy.
I restarted the PC on which VS was running, but I am still receiving the emails.
Main()
public static void Main()
{
var eh = new EventLogHelper();
var eventFired = eh.CheckEvents();
}
EventLogHelper.cs
public readonly string PcName;
private readonly int Timespan;
private readonly string Filter;
private static EventLogSession Session;
/// <summary>
/// ctor
/// </summary>
public EventLogHelper()
{
Timespan = 30000; // 30 seconds
PcName = "D7-089"; // This is usually "Environment.MachineName", but specified it here for testing
Filter = $"*[System[(EventID='5061' or EventID='5058') and TimeCreated[timediff(#SystemTime) <= {Timespan}]]]";
}
CheckEvents
/// <summary>
/// Checks the event logs for remote pc and returns true if any of the events we are interested in fired
/// </summary>
/// <returns></returns>
public bool CheckEvents()
{
var query = BuildQuery(PcName, Filter);
for (var i = 0; i < 60; i++)
{
var logs = QueryEvents(query);
var events = ReadLogs(logs);
if (events > 0)
{
return true;
}
System.Threading.Thread.Sleep(1000);
}
return false;
}
BuildQuery
/// <summary>
/// Builds an EventLogQuery for the given pcname and filter. This should be set up with a user who has admin rights
/// </summary>bh
private static EventLogQuery BuildQuery(string pcName, string filter)
{
try
{
using (var pw = GetPassword())
{
Session = new EventLogSession(
pcName,
"DOMAIN",
"USER",
pw,
SessionAuthentication.Default);
}
return new EventLogQuery("Security", PathType.LogName, filter)
{ Session = Session };
}
catch (Exception ex)
{
Email.Send($"EventLogHelper error occurred in BuildQuery \n\n Exception: {ex.Message} \n\n User: {Program.UserName} \n\n Client: {pcName}");
Environment.Exit(Environment.ExitCode);
return null;
}
}
QueryEvents
This is where the error is occurring. I stepped through this method 2 times at most and as I type this question I am still getting error emails through.
/// <summary>
/// Execute the given EventLogQuery
/// </summary>
private EventLogReader QueryEvents(EventLogQuery query)
{
try
{
return new EventLogReader(query);
}
catch (Exception ex)
{
Email.Send($"EventLogHelper error occurred in QueryEvents \n\n Exception: {ex.Message} \n\n User: {Program.UserName} \n\n Client: {PcName}");
Environment.Exit(Environment.ExitCode);
return null;
}
}
ReadLogs
/// <summary>
/// Read the given EventLogReader and return the amount of events that match the IDs we are looking for
/// </summary>
/// <param name="logReader"></param>
/// <returns></returns>
private int ReadLogs(EventLogReader logReader)
{
var count5058 = 0;
var count5061 = 0;
EventRecord entry;
try
{
while ((entry = logReader.ReadEvent()) != null)
{
if (entry.Id == 5058)
{
count5058++;
}
else
{
count5061++;
}
}
}
catch (Exception ex)
{
Email.Send($"EventLogHelper error occurred in ReadLogs \n\n Exception: {ex.Message} \n\n User: {Program.UserName} \n\n Client: {PcName}");
Environment.Exit(Environment.ExitCode);
}
return count5058 + count5061;
}
It turns out that this was being caused by a stupid mistake on my part.
This program has a Post-Build Event which is called with:
if $(ConfigurationName) == Release ("$(ProjectDir)PostBuildRelease.bat" "$(TargetDir)" #(VersionNumber) "$(TargetFileName)" "$(TargetName)")
So it only runs when VS build configuration is set to Release.
PostBuildRelease.bat simply copies the resuling assembly to the live location, ready for users to have copied to their desktops at logon.
Whilst testing my app, I foolishly edited the source code to query a specific PC, and then stepped through the code.
However, the build configuration was set to Release, So once the assembly was built ready to be debugged, it was automatically copied into the live executable location and therefore also copied to user's desktops at logon.
If the code is run with a hard-coded PcName where that PC is not the current machine, the event query appears to fail with the above error message.
So all of the emails I receiving were being sent out because the program was actually being executed on user PCs. However because PcName was hard-coded in, it always looked like it was coming from my instance of the program!
The lesson here is to always be aware of which build configuration is currently selected, especially if a Post-Build event is specified.

Unable to get all queue names for your WebSphare MQ environment using IBM .Net API

How do you get all available queue names from client side, of your MQ environment using the IBM MQ lib for .Net (IBM.WMQ), Version 8.0?
I have written a fine .Net application for reading and sending data to MQ (similar founds at code project).
Do anyone know if it is possible/how to get all available queue names from the IBM.WMQ .NET lib dynamically as you do when using tool IBM test tool RfhUtil.exe or as you can do with runmqsc DISPLAY QUEUE command from IBM .Net lib?
I have tried to brows the API, Reference manual and IBM programming guide without success.
There is certain level of PCF support in MQ .NET but it is undocumented. Here is a sample code to display queue names in queue manager.
using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IBM.WMQ;
using IBM.WMQ.PCF;
namespace PCFNET
{
class Program
{
static void Main(string[] args)
{
InquireQueue();
}
/// <summary>
/// Display list of queue names and queue depth for each queue
/// </summary>
public static void InquireQueue()
{
PCFMessageAgent messageAgent = null;
try
{
// Create bindings connection to queue manager
messageAgent = new PCFMessageAgent("DEMOQMGR");
// Build Inquire command to query queue name
PCFMessage reqeuestMessage = new PCFMessage(MQC.MQCMD_INQUIRE_Q);
reqeuestMessage.AddParameter(MQC.MQCA_Q_NAME, "*");
// Send request and receive response
PCFMessage[] pcfResponse = messageAgent.Send(reqeuestMessage);
// Process and print response.
int pcfResponseLen = pcfResponse.Length;
for (int pcfResponseIdx = 0; pcfResponseIdx < pcfResponseLen; pcfResponseIdx++)
{
try
{
String qName = pcfResponse[pcfResponseIdx].GetStringParameterValue(MQC.MQCA_Q_NAME);
int qDepth = pcfResponse[pcfResponseIdx].GetIntParameterValue(MQC.MQIA_CURRENT_Q_DEPTH);
Console.WriteLine("QName: " + qName + " Depth: " + qDepth);
}
catch (PCFException pcfex)
{
//Ignore exception and get the next response
}
}
}
catch (PCFException pcfEx)
{
Console.Write(pcfEx);
}
catch (MQException ex)
{
Console.Write(ex);
}
catch (Exception ex)
{
Console.Write(ex);
}
finally
{
if (messageAgent != null)
messageAgent.Disconnect();
}
}
}
}
There are PCFMessageAgent classes in Java, and I can see some seem to refer to equivalent classes in the .NET API.
It's possible to construct the PCF message yourself, as long as you have rights to access SYSTEM.ADMIN.COMMAND.QUEUE.
You also need to create reply queues dynamically based on SYSTEM.COMMAND.REPLY.MODEL or SYSTEM.MQSC.REPLY.QUEUE.

while calling a webservice from the code,it gives a illegal characters in path error

I am calling a webservice function from a static class....
the code looks like below:
public static class ERPBOServiceHandler {
private static ERPBOService _service = new ERPBOService();
private static bool _connected = false;
/// <summary>
/// Connect to the ERPBO WebService to access all WebService methods
/// </summary>
/// <param name="url">The URL of the webservice to connect to.</param>
/// <returns>Returns true if the web service connection succeded, else false.</returns>
public static bool Connect(string url) {
try {
_service.Url = url;
_service.Discover();
_connected = true;
return true;
} catch (Exception exc) {
ERPLog.LogException("ERPBOServiceHandler.Connect", exc);
//discover failed, maening that we failed to contact the web service. So Web Service is not connected.
System.Windows.Forms.MessageBox.Show("Error while connecting to webservice\nTrying to connect to: " + url + "\n\n" + exc.ToString());
_connected = false;
ERPEngine.SetStatus(false);
return false;
}
}
}
I am trying to connect to the webservice using this static class....this works fine when i am opening the application with proper GUI....but if i try to call the application using commandline parameters and then use this webservice class it gives illegal charcters in path error.
I tried getting the url being passed in a messagebox and it seems path is fine.
Note: i am getting the path for webservice from a settings file written in xml.
and path is defined like this :
<ERPBOWebServicePath>http://localhost:4744/ERPBOService.asmx</ERPBOWebServicePath>
Is something wrong when i call this using commandline params..
solved the issue.problem was with me using nested static constructors.

Categories