Does anybody have any advice regarding running PDFlib on a Windows Azure Worker Role? - azure

We have a requirement for PDF generation on the fly in our .NET Azure application, and have determined that PDFLib best meets our requirements.
Basic deployment is dll based, and so should be relatively straightforward. While researching the issue, I came across a case-study covering installation of another, similar component (AbcPdf, here), and this led me to wonder if anybody had any similar detailed experience to share regarding getting PDFLib up and running on a cloud service?
Specifically, I'm interested in whether there are any files other than the referenced .dlls which have to be copied with the package, whether I need to install PDFLib to the GAC using a startup command, and if there are any issues getting licensing working in a cloud environment.
We could of course use a VM for this if required, but initially I am looking to use a standard worker role. I am going to ask PDFLib support this question and will share any answer I get here, as I haven't found this topic covered anywhere else on Stackoverflow.

This is what I got back from PDF Lib support, which I think covers everything:
Does the .NET PDFLib require GAC deployment, or can the dlls simply be
copied to the server?
you can simple deploy the pdflib_dotnet dll.
Are there any files other than the referenced dlls which need to be
deployed for PDFLib to work?
no, PDFlib do not have any further dependencies.
How can we authenticate our product license in an environment where we
may not be able to run an installer, and where we may not have access
to the windows registry?
there are multiple ways to to this. The most simple way is to apply the license key in the code. You can also apply a licensefile. Please get in mind, you need for each serve, where PDFlib run in production usage a separate license. For example, when you run the application in a cluster system with 4 nodes (servers), you need 4 licenses.
And, do you have any general guidance on cloud deployments such as this?
we do not have any special comments on this. But I'm sure, you will find a lot of relevant information about the concepts of our PDFlib .NET implementation in the "PDFlib in .NET Howto", which is included in the PDFlib 8 package, and also available on our website:
http://www.pdflib.com/en/developer/technical-documentation/pdflib-in-net-howto/

Let me start with I've not deployed this compment into Azure; however, what follows should be accurate for just about any component you have.
If you can just xcopy deploy this component to a regular server it should just work with a normal deployment package to a Cloud Service; however, if there is an install that is required when you distribute to normal servers (read, NOT your development machine), then you may have some extra steps here. For example, if the install pushes the assembly into the GAC, then you'd have to follow suit.
I'd simply test an xcopy deployment rollout to a regular on premises box that hasn't had an installation of this component before and see if it works. If it does, you're likely just fine to ensure it gets referenced and deployed with your package. If you are concerned that it may need other assemblies to go with it, use something like Reflector, Just Decompile or ILDasm to check out the references the assembly has (careful, using a decompiler on the assembly may be against your EULA).

I know you're asking for actual experience, but I'd say the answer is that this should just work. From http://www.pdflib.com/fileadmin/pdflib/pdf/support/PDFlib-in-.NET-HowTo.pdf:
A process called xcopy deployment is also supported. You can simply
copy the PDFlib assembly (pdflib_dotnet.dll) to the server using the
xcopy command or FTP transfer

I downloaded and PDFLib x64 version and a give a quick try with Windows Azure Web Role. The Library contains only one DLL as PDFlib_dotnet.dll which you can add as reference and set its property "Copy Local As True". After that you can just reference it in your code and use it based on documentation.
Based on my quick test, you really need to modify the code to use Windows Azure Local Storage to create your PDF files and the sync to Windows Azure Blob storage to persist it properly. There may be way to create the PDF directly to Azure Blob storage but I just did not look further.
I created an ASP.NET based webrole with the following code:
PDFlib p;
int font;
p = new PDFlib();
try
{
// This means we must check return values of load_font() etc.
p.set_parameter("errorpolicy", "return");
// Added code to create PDF on Local Storage
LocalResource myStorage = RoleEnvironment.GetLocalResource("myLocalStorage");
string filePath = Path.Combine(myStorage.RootPath, "hello.pdf");
if (p.begin_document(filePath, "") == -1)
{
Console.WriteLine("Error: {0}\n", p.get_errmsg());
return;
}
p.set_info("Creator", "hello.cs");
p.set_info("Author", "Rainer Schaaf");
p.set_info("Title", "Hello, world (.NET/C#)!");
p.begin_page_ext(595, 842, "");
font = p.load_font("Helvetica-Bold", "unicode", "");
if (font == -1)
{
Console.WriteLine("Error: {0}\n", p.get_errmsg());
return;
}
p.setfont(font, 24);
p.set_text_pos(50, 700);
p.show("Hello, world!");
p.continue_text("(says .NET/C#)");
p.end_page_ext("");
p.end_document("");
}
catch (PDFlibException eX)
{
// caught exception thrown by PDFlib
Console.WriteLine("PDFlib exception occurred in hello sample:\n");
Console.WriteLine("[{0}] {1}: {2}\n", eX.get_errnum(),
eX.get_apiname(), eX.get_errmsg());
}
finally
{
if (p != null)
{
p.Dispose();
}
}
}

Related

How can I debug on Azure Devops VSO

I have made a task for Azure Devops Server pipeline.
On the local Azure Dev-Ops server, I can upload extensions from the local machine wrapped in VSIX file and examine the agent on the machine itself. The agent has the deployed DLL's from the extension and I always change specific DLL that has Logger inside and it prints to console on the pipeline itself.
How can I check if my task is compatible with the cloud version?
And off course if it is, how can I debug it?
The only possible way I found to insert my task in VSO is through the Microsoft DevOps marketplace, but I cannot upload the whole extension once per each change in code.
Also, didn't find a way to upload personal tasks to the marketplace. The private version is not helping because I can see it from within the server just like my clients.
Any advice or debug experience on that platform is appreciated.
Please follow this devblogs, it described how you can work and debug extension directly inside your IDE without publishing it to the marketplace.
Since this blog is very detailed, just mention the key steps.
Based on debugging purposes, you need create a special manifest, for sample I specify it as vss-extension-debug.json:
{
...
"id": "dev-extension",
"name": "Dev-Extension",
"baseUri": "https://localhost:44362",
...
}
You can customized the id and name by yourself. The most important and magic is baseUri, this will tell the VSTS server to load the extension from localhost where we can run and debug it in IISExpress from Visual Studio.
Note: Since our server need extension served from a secure source, please ensure enable SSL mode to run IISExpress

Object removed from assembly still referred to after deploy to Azure, local is fine

ASP.NET Core 2.1
We have a shared dll, that is used in a few projects (via project reference)
We have class in that was named Proofer, and is now named ProofReader.
This was done through mass find and replace.
Nowhere in our source files locally exists any files containing the text Proofer.
VSTS builds the application without issue, then we send it via a release pipeline to Azure. All succeed.
Despite this we attempt to run the web app and get the following:
An unhandled exception occurred while processing the request.
TypeLoadException: Could not load type
'MainShared.Models.Proofer' from assembly 'MainShared,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
System.Reflection.CustomAttribute._CreateCaObject(RuntimeModule
pModule, IRuntimeMethodInfo pCtor, Byte** ppBlob, Byte* pEndBlob,
Int32* pcNamedArgs)
We are having trouble determining if this is in the build, maybe something not being rebuilt when it should be, or something still cached on Azure that isn't being overwritten.
A few places I can suggest you look into -
If you are using app service web apps in azure , we can use the kudu (web app extension to remove/clean the files) to make sure you have a clean destination.
Check the VSTS Release logs if you have access to , it shows the files which are overwritten and the ones which could not be. Once i had a similar issue and found that the logs were already warning me that a few could not be overwritten.
If you are using VM's for your app deployment if has access to it , remove/backup the files under your site folder.
I had a similar problem after some redesign for a Web App using ASP.NET Core 2.2 (hosted on Azure), that some old not even anymore existing references causing the Load type exceptions to happen and the Web App simply refused to come up. I tried to clean everything up in Visual Studio, even deleted the bin and object directories, but the old reference was still looked for. In Kudu on the Azure portal I saw the *.PrecompiledViews.dll and *.PrecompiledViews.pdb files, which were very old. I simply removed them directly on the Azure server and could then simply start up my app and everything came up again. This fault should be fixed from the source. If I do a complete rebuild, I expect this old garbage to be taken care of during the publishing to the website. This is something that Microsoft should fix and as I can see this happened to others over half a year ago. Thanks Mark Johnson for your very useful hint about those files!

Deploy a windows service without Installshield

Is it possible to deploy a windows service without going through Installshield? I have a very basic service which simply probes a database, and wish to deploy it on a server.
I tried using Installsheild LE, but get error 1001 on install, which is hard to troubleshoot, and anyhow Installshield feels like overkill in this case... is there a way can just install the service direct by command line or other method?
Yes.
However, there are options, from best to worst:
There are other tools for writing installers out there. Eg. the full version of install Shield or WiX (which MS created, and is used for the Visual Studio installer).
You could use installUtil having included a type derived from ServiceInstaller in your assembly. (See How to: Install and Uninstall Service.)
You can manually edit the registry.
#3 Is seriously easy to mess up, and won't help you with the event logging and performance counters you should be including.1 #2 is best in development, and will set up event logs and performance counters as well (remember you'll need to elevate to install things, and to attach a debugger to the service when running as a service).
Using a real installer (#1) is best in test (staging) and production environments.
1 When you get asked why it isn't working, you'll want to be able to work out what's going on (or not).
Yes, if your service has an Installer class then, you can install it from command line with installutil.exe
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;
[RunInstaller(true)]
public class ServiceInstaller : Installer
{
public ServiceInstaller()
{
ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
ServiceInstaller serviceInstaller = new ServiceInstaller();
//# Service Account Information
serviceProcessInstaller.Account = ServiceAccount.User;
serviceProcessInstaller.Username = "";
serviceProcessInstaller.Password = "";
//# Service Information
serviceInstaller.DisplayName = "Service name"
serviceInstaller.Description = "Service description"
serviceInstaller.StartType = ServiceStartMode.Automatic;
//# This must be identical to the WindowsService.ServiceBase name
//# set in the constructor of WindowsService.cs
serviceInstaller.ServiceName = "Service Name";
this.Installers.Add(serviceProcessInstaller);
this.Installers.Add(serviceInstaller);
}
}
Building and Deploying a Windows Service using IsWiX
The above is a short video I made showing how to use WiX / IsWiX to generate a very clean MSI for installing a service. It's really easy, fast, elegant and free.
You can use the command line tool sc.exe to create and configure a windows service (basically insert the config into registry), assuming you have already deployed the built .exe to disk somewhere on your server.
http://support2.microsoft.com/kb/251192

Cant read configuration. RoleEnvironment may be inaccessible due to its protection level

This is my first azure project and I'm not sure if I'm doing something wrong.
I'm trying to get some configuration inside an MVC 3 webrole and for this I'm using:
RoleEnvironment.GetConfigurationSettingValue(KeyName)
When I run the application on the emulator i get his error:
BC30451: 'RoleEnvironment' is not declared. It may be inaccessible due to its protection level.
I tried to add the full namespace like this:
Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetConfigurationSettingValue(KeyName)
And I get this error:
BC30456: 'ServiceRuntime' is not a member of 'WindowsAzure'.
However, I can access the RoleEnvironment inside the "OnStart" event of the WebRole class.
So, is it the expected behavior? If yes, how am I supposed to read configuration through the whole project?
Thanks in advance;
Have you added a reference to the Microsoft.WindowsAzure.ServiceRuntime assembly in your MVC project?
http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.serviceruntime.roleenvironment.aspx
I started a new solution based on seanost suggestion and it worked well, so I figured the problem wasn't VS. After a few try and errors I finally found a solution, I just don't have an explanation for it :-)
Under my MVC project I have a folder called "App_Code".
Since i come from web forms development I'm use to the name so I created this folder to keep some classes. If I try to access "RoleEnviroment" from a class inside this folder the project compiles but won't even open, no matter what I try to access it will throw the same error.
If I rename the folder or move the files to another folder (let's say "Code"), it just works.
As I said before, I just don't know why it happens (and it doesn;t really matter now :-)
FYI, if you're using Visual Studio's Azure templates, references to the following namespaces are included by default, so it's not necessary to set Copy Local to true:
Microsoft.WindowsAzure.Diagnostics
Microsoft.WindowsAzure.ServiceRuntime
Microsoft.WindowsAzure.StorageClient
To make sure Visual Studio and the SDK is installed correctly, you should be able to do the following: Create a new MVC3 Azure project, add a using directive for the ServiceRuntime library in your Home controller, then add the following code in the Index action:
ViewBag.configValue = RoleEnvironment.GetConfigurationSettingValue("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString");
return View();
Then, add the following Razor syntax in the View:
<p>#ViewBag.configValue;</p>
And you should get the following result in your browser:
UseDevelopmentStorage=true

How to publish MSHTHML.dll and SHDOCVW.dll to Azure

I have a 3rd party web page screen capture DLL from http://websitesscreenshot.com/ that lets me target a URL and save the page to a image file. I've moved this code into my Azure-based project and when I run it on my local sandboxed dev box and save to the Azure blob, everything is fine. But when I push the bits to my live server on Azure, it's failing.
I think this is because either MSHTML.dll and/or SHDOCVW.dll are missing from my Azure configuration.
How can I get these libraries (plus any dependent binaries) up to Azure?
I found the following advice on an MSFT forum but haven't tried it yet. http://social.msdn.microsoft.com/Forums/en-US/windowsazuredevelopment/thread/0344dcff-6fdd-4479-a3b4-3e89750a92f4/
Hello, I haven't tried mshtml in the cloud. But generally speaking, to
use a native dll in a Web Role, you add the dll to the Web Role
project just like adding a picture (choose add existing items). Then
make sure the Build Action is set to Content. This tells Visual Studio
to copy the dll file to the output package.
Also check dependencies carefully. A lot of problems related to native
code are caused by missing dependencies, such as a particular VC++
runtime dll.
Thought I'd ask here first before I burn a day or two on an unproven solution.
EDIT #1:
it turns out that our problem was not related to MSHTML.dll or SHDOCVW.dll missing from the Azure server. They're there.
The issue is that by default new server instance have the IE security hardening feature enabled, and this was preventing our 3rd party dll from executing script. So we needed to turn off the enhanced IE security configuration settings. This is also a non-trivial exercise.
In the meantime, we just created a server-side version of the feature on our site we need to make screen captures from (e.g. we eliminated JSON-based rendering of UI on the client), and we were able to proceed.
I think the solution mentioned in the MSDN forum thread is correct. You should put them as part of your project files, so that the SDK will package and deploy them to the VM on the cloud.
But if they are COM and need to be registed you'd better call the register command via the Startup feature. Please check http://msdn.microsoft.com/en-us/hh351539
HTH

Resources