Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File System IO Issue? #55

Closed
timdooling opened this issue Dec 29, 2014 · 24 comments
Closed

File System IO Issue? #55

timdooling opened this issue Dec 29, 2014 · 24 comments

Comments

@timdooling
Copy link

I have been working with the latest version of this interface and am very pleased with the results!!!!!

However, I have been having one problem with generating output.

The output file is fine, but if I run the program a second time too soon after the first, the program accessing the pdf generator hangs, and no output results.

I am wondering if the output file system.IO interface is being completely closed and disposed. The hanging appears when I invoke the converter, so I believe it is an internal problem to the interface.

Any thoughts?

timothydooling@gmail.com

@tuespetre
Copy link
Owner

What kind of application is this (console, service, web app) and what does your code look like (how are you instantiating the converter)?

@timdooling
Copy link
Author

I am using it in both a direct application and a web service. The results are the same.

Eventually, in about 10 minutes or so, the program will generate a new file without hanging.

@tuespetre
Copy link
Owner

How are you instantiating the converter, or what does your code look like where you are using components from this library? Can you post a sample?

@timdooling
Copy link
Author

The problem I am having now is that the Win64EmbeddedDeployment class is not being recognized outside of the compilation.

I downloaded the source code and recompiled it in .Net 4.0, but I still can't seek to include a reference to the 64-bit version that recognizes this class.

The code I am using is from one of your examples.

It works with the Win32EmbeddedDeployment class, and works fine on localhost but will not compile when I try to merge it to our staging server (a 64-bit server).

The problem I am dealing with is a deployment issue.

Am I trying to use the wrong class?

@timdooling
Copy link
Author

I am getting the following error when trying to use the 64-bit version in a web service:

=== Pre-bind state information ===
LOG: DisplayName = TuesPechkin.Wkhtmltox.Win64
(Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: TuesPechkin.Wkhtmltox.Win64 | Domain ID: 2
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.

@timdooling
Copy link
Author

I get the following error when I try to stage the 32-bit version in a web service:

ASPNETCOMPILER: Could not load file or assembly 'TuesPechkin.Wkhtmltox.Win32' or one of its dependencies. An attempt was made to load a program with an incorrect format.

This is compiled under .Net 4.0.

@tuespetre
Copy link
Owner

You might have to set the application pool hosting your web service to allow 32-bit applications. Right click the app pool in IIS, go to advanced settings, and it's one of the first several settings.

@timdooling
Copy link
Author

I removed the Win32 assembly and was able to get the project to compile.

However, when I went to run the web service it crashed with a "could not find file" error on wkhtmltox.dll.

The code I am using is:
Dim converter As IConverter = New ThreadSafeConverter(New RemotingToolset(Of PdfToolset)(New StaticDeployment(Path.Combine(Path.GetTempPath(), "wkhtmltox.dll")))).

This works fine as a web service run on localhost, but bombs on a remote server.

I obviously need to know where the file is and it doesn't like that method.

@tuespetre
Copy link
Owner

That code is saying "load wkhtmltox.dll from a folder called %Temp%/wkhtmltox.dll/." Unless you have a copy of wkhtmltox.dll in that place, it will not work. That's what the EmbeddedDeployment implementations do -- they ensure that the wkhtmltox.dll file exists in the folder you have specified. An IDeployment instances represents a folder the wkhtmltox.dll file should exist in, not the wkhtmltox.dll file itself.

Here are some things to know about IIS, Visual Studio, 32 vs. 64 bit:

  • Visual Studio uses IIS Express by default, which is 32-bit by default
  • IIS (not Express) runs app pools in 64-bit by default on a 64-bit server
  • If you want to use a 32-bit specific assembly in IIS (not Express) you need to set your app pool that way
  • If you want to use a 64-bit specific assembly while developing from Visual Studio you need to tell Visual Studio to run IIS Express in 64-bit (or do what I do and don't use IIS Express at all, tell Visual Studio to use local IIS instead)

So here is what I would do in your situation:

  • Add the Win32 Nuget package again
  • Set your app pool on your remote server to allow 32-bit applications
  • Use code like the following (convert it to VB of course):
var converter = new ThreadSafeConverter(
    new RemotingToolset<PdfToolset>(
        new Win32EmbeddedDeployment(
            new StaticDeployment(
                Path.Combine(Path.GetTempPath(), "MyApplication_32")))));

This will deploy a 32-bit copy of wkhtmltox.dll into a folder called %Temp%/MyApplication_32/ and the second step above is imperative - you MUST set your application pool to allow 32-bit applications.

@timdooling
Copy link
Author

How do you tell visual studio to use local IIS?

I am guessing that because IIS Express in 32-bit is being used on my computer, that is why the Win64EmbeddedDeployment doesn't show up when I nu-get the package.

I tried switching it to 64-bit, but then the main Tuespechkin errors out and the 32-bit packages are not recognized.

Apparently, it is one or the other, not both.

@tuespetre
Copy link
Owner

Yes, you will only want to reference one or the other of those two packages.

To get Visual Studio to use local IIS for a project, right-click the project node in Solution Explorer and go to the 'web' settings.

@timdooling
Copy link
Author

I am using 2013 Premium and it doesn't have the web settings option for web services.

The problem exists with Tuespechkin and the global 64-bit option. When I turn on the global 64-bit IISExpress option, then Tuespechkin is not recognized as having the proper format.

@tuespetre
Copy link
Owner

I think maybe you deployed a 32-bit copy on your server, and then when you switched to the 64 bit package, it didn't deploy the 64-bit copy because a file named wkhtmltox.dll already existed in place. I think you need to update your deployment path like this:

var converter = new ThreadSafeConverter(
    new RemotingToolset<PdfToolset>(
        new Win32EmbeddedDeployment(
            new StaticDeployment(
                Path.Combine(Path.GetTempPath(), Guid.NewGuid())))));

Once you see that it is working this way, you can clear your temp files and specify an actual folder instead of always generating a new guid-named folder.

@timdooling
Copy link
Author

The problem with using the 64-bit version is that it won't load on my local computer, which is running in 32-bit mode in IIS Express. I do not know how to get it to run in IIS local and we may not have that option available.

When I check the global option to use 64-bit IIS Express in Visual Studio, then Tuespechkin won't load properly on the local machine and isn't recognized.

I have been looking at loading a 32-bit/64-bit version of wkhtmltox.dll into my project file at a known location, and then using context.Request to find it. I can locate my project on the server this way, and then add the necessary offset to the location of the codefile.

If I understand how the embedded system works, you are unzipping a resource file to a temporary location and that becomes the needed version of the code.

I am in the process of getting the application pool on the server switched to allow 32-bit so that may solve the problem. If I could test using a 64-bit copy of the code, I could try to use an unzipped copy of the code. I can't test it however, because the opposite conflict occurs when I try to do so on my local machine.

@timdooling
Copy link
Author

I tried having the application pool changed at the server level.

I got the same compilation error. It works fine on localhost.

I tried attaching the 64-bit one and it compiles, but hangs indefinitely.

This is the coding I use to create the converter:

converter = New ThreadSafeConverter(New RemotingToolset(Of PdfToolset)(New Win32EmbeddedDeployment(New StaticDeployment(tpath))))

tpath is a variable that is previously set to the same

Instead of Win32, I use Win64 for the 64-bit version.

Is there a way I can use a static deployment in the GAC or the program temp code for the 64-bit?

I am running out of options.

@tuespetre
Copy link
Owner

tpath is a variable that is previously set to the same

'The same' as what? Please be explicit.

Is there a way I can use a static deployment in the GAC or the program temp code for the 64-bit?
I am running out of options.

I don't believe you can deploy to the GAC because it's not signed, but that's beside the point.

Now let's cut to it and get you up and running.

You need to change the path you're passing in to this:

Dim tpath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())

This ensures that each time you start your application or recycle an application pool, it will target a fresh copy of wkhtmltox.dll in a brand new folder. Then you just need to pick with version you want to use -- 64-bit or 32-bit -- and set your Visual Studio and production application pool to be the same.

@timdooling
Copy link
Author

Actually, I got it running on the remote server finally.

I placed it in the root directory alongside of the .asmx file, and manually uploaded it to the tfs server.

I then replaced the above code with:

converter = New ThreadSafeConverter(New RemotingToolset(Of PdfToolset)(New StaticDeployment(physicalApplicationPath)))

where physicalApplicationPath is MyClass.Context.Request.PhysicalApplicationPath.

It worked! It found and loaded the file from the root directory of my web service.

The only problem is that it left the "wkhtmltox.dll" file open, which is really what this question was originally about.

I needed to upload another change to the web service, and got a access is denied error.

I noticed the problem on localhost, and was getting around it using the Task Manager.

The bottom line is I got it working on a remote server as a web service.

@tuespetre
Copy link
Owner

Alright. Now we need to check something else: are you storing the converter instance in a static field somewhere or are you creating a new one with each request?

@tuespetre
Copy link
Owner

Actually, is there any way you can provide a more detailed sample so I can give you better guidance? It would make this so much easier.

@timdooling
Copy link
Author

I am going to try wrapping the web service calls in a using block and see if that solves the problem.

@tuespetre
Copy link
Owner

I don't think that will do what you think it will do. You should be creating the thread safe converter one time and storing it in a static field or passing around the single instance of it. Are you doing that?

@timdooling
Copy link
Author

I can try to use a static field for the converter since it seems to behave as though it is static. I am using the thread safe converter as the code snippet from Wednesday shows. The problem is that the coding is locking the wrapped file in place and leaving it there after my application that uses the web service containing the pdf converter code terminates.

The file I/O system eventually releases the wkhtmltox file, but that doesn't work well in a production environment. It doesn't matter which way I attempt to use the code, it still does this.

@tuespetre
Copy link
Owner

Yes, you need to use a single, static instance. That is covered in the readme.

  • Derek Gray

On Jan 2, 2015, at 5:38 PM, timdooling notifications@github.com wrote:

I can try to use a static field for the converter since it seems to behave as though it is static. I am using the thread safe converter as the code snippet from Wednesday shows. The problem is that the coding is locking the wrapped file in place and leaving it there after my application that uses the web service containing the pdf converter code terminates.

The file I/O system eventually releases the wkhtmltox file, but that doesn't work well in a production environment. It doesn't matter which way I attempt to use the code, it still does this.


Reply to this email directly or view it on GitHub.

@tuespetre
Copy link
Owner

#56

See the above issue. A patch will be issued tonight

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants