Solved

Call console app with xml-parameter file

Posted on 2009-05-13
20
876 Views
Last Modified: 2013-12-14
Hi
I have a website where I call a console .exe file with Process.Start
I have some arguments attached to the app.
One of the arguments is a xml-config file.
It works fine, the XML-configfile is called, the configfile points at some files on the server, or should do. But it dosn't work.
I have tried to run it on a local IIS, pointing the files out from the xml-file with local paths, and this works fine.
But on the webserver it dosn't work. ( I have tried to use local paths her too)
One more thing, I use Virtual mapping on the webserver.

Can someone help me out here ??
0
Comment
Question by:conceptdata
  • 12
  • 8
20 Comments
 
LVL 4

Expert Comment

by:Wardy_01
ID: 24372863
Ok ...

If it's not calling the console app try using Server.MapPath("~/YourApp.exe") or similar to translate the virtual path to a physical one.

If it is running the app but there's a problem it could be the config file or it could be permissions.

By default the web app will execute the app under the same account that it is running under which is likely to be the "NetworkService" account or something similar, this means that virtually any operation that the console app tries to perform that involves any writing to files / access outside of the web root scope will cause you major headaches.

You can use impersonation or just specify some account credentials on the process object you create to call the exe to get around that or you can run the web app pool account under another user (eg a domain user that has access to all resources that it may need across your dommain).

Unless you are running the app from the same location on both computers (eg C:\MyApp\MyApp.exe) and the files are all in that same folder you might find that your paths break so consider relative paths using something like ".\" + filename for a file in the Console apps root folder this may help resolve some path issues.

I would get the permissions right first (try hard coding a temp path in to the exe) then make it more dynamic.

Don't forget you have various layers of permissions to deal with ...

1. domain permissions (defined on dc)
2. computer / server permissions (defined in computer managers users / groups)
3. web service permissions (defined in iis manager)
4. ntfs permissions (defined on files and folders themselves)

Hope this helps.
any probs, let me know.
0
 

Author Comment

by:conceptdata
ID: 24373005
The Console app is in the same dir as my xml-configfile.
I have tried this : font metrics-file=".\arial.xml"  
And this E:\WWW\Checkpoint\WWW\pdfconvert\database\arial.xml
-- (Physocal server path : E:\WWW\Checkpoint\WWW\pdfconvert\)

One more thin, the exe-file is called and executed fine, It makes a PDF file from a xml and xsl file.
app called nFop.
But still the files from the config file is not "called"
normal command line : nfop.exe  -c userconfig.xml -xsl off.xsl -xml off.xml -pdf off.pdf

??
0
 
LVL 4

Expert Comment

by:Wardy_01
ID: 24373208
Whats the config file ?
typically if its a standard config file for a .NET app its named something like "YourApp.exe.config".

For custom config files you would have to write the code to pickup and read the config file manually maybe using an xmldocument object or something.

Sounds to me like the latter is your problem.
0
 

Author Comment

by:conceptdata
ID: 24373231
Config file attached.

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

	<fonts>

		<font metrics-file="arial.xml" embed-file="arial.ttf" kerning="yes">

			<font-triplet name="Arial" style="normal" weight="normal"/>

		</font>

		<font metrics-file="arial-bold.xml" embed-file="arialbd.ttf" kerning="yes">

			<font-triplet name="Arial" style="normal" weight="bold"/>

		</font>

		<font metrics-file="arial-italic.xml" embed-file="ariali.ttf" kerning="yes">

			<font-triplet name="Arial" style="italic" weight="normal"/>

		</font>

		<font metrics-file="arial-italic-bold.xml" embed-file="arialbi.ttf" kerning="yes">

			<font-triplet name="Arial" style="italic" weight="bold"/>

		</font>

	  <font metrics-file="IDAutomationHC39XL.xml" embed-file="IDAutomationHC39XL.ttf" kerning="yes">

			<font-triplet name="IDAutomationHC39XL" style="normal" weight="normal"/>

		</font>

	</fonts>

</configuration>

Open in new window

0
 
LVL 4

Expert Comment

by:Wardy_01
ID: 24373379
ok as you are specifying a name for the config file as a startup param you should also have a block of code in the "static void Main(object [] args)" method that handles this xml data ?

This would be in the program.cs file of your project source code.

sure thats not logically flawed somehow ?

0
 

Author Comment

by:conceptdata
ID: 24373447
Thats right

I have attached the project as a RAR-file renamed to .jpg
nfop-fw2.jpg
0
 
LVL 4

Expert Comment

by:Wardy_01
ID: 24373534
on this connection i'd be here all day downloading that mate, im using a mobile internet connection.
I could probably have a look later from home.

It sounds to me like you have a coding issue rather than a server / config issue and that the problem you have is the loading of this config file.

Just paste me the main method in the program.cs class file maybe that might shed some light on the subject :)
0
 

Author Comment

by:conceptdata
ID: 24373599
main method

        public static void Main(string[] args)

        {

            int ExitCode = 0;

  

            try

            {

                CommandLineArguments cmdLineArgs = new CommandLineArguments(args);
 

                if (CheckParameters(cmdLineArgs))

                {

                    switch (cmdLineArgs.Arguments.Count)

                    {

                        case 2:
 

                            if (cmdLineArgs.HasUSERCONFIG && cmdLineArgs.HasFO && cmdLineArgs.HasPDF)

                            {

                                Fop.Net.NFop.Create_PDF_from_FO_with_CONFIG(cmdLineArgs.FO, cmdLineArgs.PDF, cmdLineArgs.USERCONFIG);

                            }

                            else if (cmdLineArgs.HasUSERCONFIG == false && cmdLineArgs.HasFO && cmdLineArgs.HasPDF)

                            {

                                Fop.Net.NFop.Create_PDF_from_FO(cmdLineArgs.FO, cmdLineArgs.PDF);

                            }
 

                            break;

                        case 3:
 

                            if (cmdLineArgs.HasUSERCONFIG && cmdLineArgs.HasXML && cmdLineArgs.HasXSL && cmdLineArgs.HasPDF)

                            {

                                Fop.Net.NFop.Create_PDF_from_XML_XSL_with_CONFIG(cmdLineArgs.XML, cmdLineArgs.XSL, cmdLineArgs.PDF, cmdLineArgs.USERCONFIG);

                            }

                            else if (cmdLineArgs.HasUSERCONFIG == false && cmdLineArgs.HasXML && cmdLineArgs.HasXSL && cmdLineArgs.HasPDF)

                            {

                                Fop.Net.NFop.Create_PDF_from_XML_XSL(cmdLineArgs.XML, cmdLineArgs.XSL, cmdLineArgs.PDF);

                            }
 

                            break;

                        case 4:
 

                            if (cmdLineArgs.HasUSERCONFIG && cmdLineArgs.HasXML && cmdLineArgs.HasXSL && cmdLineArgs.HasFOOUT && cmdLineArgs.HasPDF)

                            {

                                Fop.Net.NFop.Create_PDF_and_FO_from_XML_XSL_with_CONFIG(cmdLineArgs.XML, cmdLineArgs.XSL, cmdLineArgs.FOOUT, cmdLineArgs.PDF, cmdLineArgs.USERCONFIG);

                            }

                            else if (cmdLineArgs.HasUSERCONFIG == false && cmdLineArgs.HasXML && cmdLineArgs.HasXSL && cmdLineArgs.HasFOOUT && cmdLineArgs.HasPDF)

                            {

                                Fop.Net.NFop.Create_PDF_and_FO_from_XML_XSL(cmdLineArgs.XML, cmdLineArgs.XSL, cmdLineArgs.FOOUT, cmdLineArgs.PDF);

                            }
 

                            break;

                    }

                }

                else

                {

                    PrintUsage();

                }

            }

            catch (System.IO.FileNotFoundException fileNotFoundException)

            {

                ExitCode = 1;

                Console.WriteLine(fileNotFoundException.Message);

            }

            catch (CommandLineArgumentException commandLineArgumentException)

            {

                ExitCode = 1;

                Console.WriteLine("{0}:\t{1}", commandLineArgumentException.Message, commandLineArgumentException.ParamName);

            }

            catch (Exception exception)

            {

                ExitCode = 1;

                Console.WriteLine("{0}{1}{2}", exception.Message, Environment.NewLine, exception.StackTrace);

            }
 

            Environment.Exit(ExitCode);

        }

Open in new window

0
 

Author Comment

by:conceptdata
ID: 24373616
Definition : Create_PDF_from_FO_with_CONFIG

        public static void Create_PDF_from_FO_with_CONFIG(string foFile, string pdfFile, string cfgFile)

        {

            string fo = Fop.Net.NFop.GetFo(foFile);

            byte[] bytes = Fop.Net.NFop.CreatePDF(fo, new org.apache.fop.apps.FileUrl(cfgFile));

            Fop.Net.NFop.CreateFile(bytes, pdfFile);

        }

Open in new window

0
 

Author Comment

by:conceptdata
ID: 24373622
definition : org.apache.fop.apps.FileUrl

using System;
 

namespace org.apache.fop.apps

{

    public class FileUrl

    {

        public FileUrl(string url);
 

        public override object MemberwiseClone();

        public override string ToString();

        public virtual java.net.URL toUrl();

    }

}

Open in new window

0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

Author Comment

by:conceptdata
ID: 24373662
I think this code is the code that "reads" the ttf and xml font files ...
    * @return the URL to the metrics file

     */

    public URL getMetricsFile() throws FOPException {

        try {

            return URLBuilder.buildURL(Configuration.getFontBaseURL(), metricsFile);

        } catch (Exception e) {

            throw new FOPException("Invalid font metrics file: " + metricsFile 

                    + " (" + e.getMessage() + ")");

        }

    }
 

    /**

     * @return the url to the font

     */

    public URL getEmbedFile() throws FOPException {

        // check if it's a URL and convert it to a filename

        if (embedFile == null) return null;

        try {

            return URLBuilder.buildURL(Configuration.getFontBaseURL(), embedFile);

        } catch (Exception e) {

            throw new FOPException("Invalid font file (embedFile): " + embedFile 

                    + " (" + e.getMessage() + ")");

        }

    }

Open in new window

0
 

Author Comment

by:conceptdata
ID: 24373689
Some more info
	private static URL buildBaseURL(String directory) throws java.net.MalformedURLException

	{

		if (directory == null) return null;

		File dir = new File(directory);

		if (dir.isDirectory())

		{

			return dir.toURL();

		}

		else

		{

			URL baseURL = new URL(directory);

			return baseURL;

		}

	}

Open in new window

0
 
LVL 4

Expert Comment

by:Wardy_01
ID: 24374190
erm .... I think its the logic in that switch statement in the main method.

// assuming cmdLineArgs.Arguments is a typical collection.
 switch (cmdLineArgs.Arguments.Count)
                    {
                        case 2: // if the collection has 2 args
                            // this condition will never be met
                            if (cmdLineArgs.HasUSERCONFIG && cmdLineArgs.HasFO && cmdLineArgs.HasPDF)
                            {

You appear to have replicated this problem right down the entire switch block.
cmdLineArgs.Arguments.Count will tell you how many args were specified, it's not a 0 based reply like in an indexor ...

cmdLineArgs.Arguments[0]   <--- returns first arg

//if you had only 1 arg in the collection
cmdLineArgs.Arguments[1]   <--- would not exist but ....

// should return 1 not 0 ....
int argsNum = cmdLineArgs.Arguments.Count


Hopefully this is your problem unless I misunderstand something, although I don't have your definition for the CommandLineArguments class.
0
 

Author Comment

by:conceptdata
ID: 24374234
I don't think it is my problem.
Because that the other parameter is used, and the PDF file as created, but the fonts I specify in the userconfig file as not embedded, as it should.

Attached the CommandLineArguments
using System;
 

namespace NFopApp

{

    public class CommandLineArguments

    {

        public const string USERCONFIG_KEY = "-c";

        public const string FO_KEY = "-fo";

        public const string XML_KEY = "-xml";

        public const string XSL_KEY = "-xsl";

        public const string PDF_KEY = "-pdf";

        public const string FOOUT_KEY = "-foout";

        protected string _USER_CONFIG_PARAM = null;
 

        protected System.Collections.Generic.Dictionary<string, string> _arguments = null;
 

        protected static System.Collections.Generic.Dictionary<string, string> validArguments = null;
 
 

        public CommandLineArguments(string[] args)

        {

            Parse(args);

        }
 

        public virtual System.Collections.Generic.Dictionary<string, string> GetValidArguments()

        {

            if (validArguments == null)

            {

                validArguments = new System.Collections.Generic.Dictionary<string, string>();

                validArguments.Add(USERCONFIG_KEY, USERCONFIG_KEY);

                validArguments.Add(FO_KEY        , FO_KEY);

                validArguments.Add(XML_KEY       , XML_KEY);

                validArguments.Add(XSL_KEY       , XSL_KEY);

                validArguments.Add(PDF_KEY       , PDF_KEY);

                validArguments.Add(FOOUT_KEY     , FOOUT_KEY);

            }
 

            return validArguments;

        }
 

        protected bool ParseShort(string[] tokens, System.Collections.Generic.Dictionary<string, string> arguments)

        {

            if (tokens.Length == 2)

            {

                string arg0 = PrepareToken(tokens[0]);

                string arg1 = PrepareToken(tokens[1]);
 

                if (IsEmptyToken(arg0) == false && IsEmptyToken(arg1) == false)

                {
 

                    if (arg0.ToLower().EndsWith(".fo")  && arg1.ToLower().EndsWith(".pdf"))

                    {

                        arguments.Add(FO_KEY, arg0);

                        arguments.Add(PDF_KEY, arg1);
 

                        return true;

                    }

                    else if (arg0.ToLower().EndsWith(".pdf") && arg1.ToLower().EndsWith(".fo"))

                    {

                        arguments.Add(PDF_KEY, arg0);

                        arguments.Add(FO_KEY, arg1);
 

                        return true;

                    }

                    else

                    {

                        arguments.Add(FO_KEY, arg0);

                        arguments.Add(PDF_KEY, arg1);
 

                        return true;

                    }

                }

            }
 

            return false;

        }
 

        protected void ParseFull(string[] tokens, System.Collections.Generic.Dictionary<string, string> arguments)

        {

            for (int token_index = 0; token_index < tokens.Length; token_index++)

            {

                string token = PrepareToken(tokens[token_index]);
 

                if (IsEmptyToken(token) == false)

                {

                    if (IsValidToken(token))

                    {

                        if (HasNextToken(token_index, tokens.Length))

                        {

                            token_index++;
 

                            string value = PrepareToken(tokens[token_index]);
 

                            if (IsEmptyToken(value) == false)

                            {

                                if (token == USERCONFIG_KEY)

                                {

                                    _USER_CONFIG_PARAM = value;

                                }

                                else

                                {

                                    arguments.Add(token, value);

                                }

                            }

                        }

                    }

                }

            }

        }
 

        public virtual void Parse(string[] tokens)

        {

            if (tokens != null)

            {

                if (tokens.Length > 0)

                {

                    int tokensLength = tokens.Length;
 

                    _arguments = new System.Collections.Generic.Dictionary<string, string>(tokensLength);
 

                    if (ParseShort(tokens, _arguments)==false)

                    {

                        ParseFull(tokens, _arguments);

                    }
 

                    if (HasArguments && HasUSERCONFIG==false)

                    { 

                      string NFOP_USER_CONFIG_PATH = PrepareToken(Environment.GetEnvironmentVariable("NFOP_USER_CONFIG_PATH"));
 

                      if (IsEmptyToken(NFOP_USER_CONFIG_PATH) == false)

                      {

                          this._USER_CONFIG_PARAM = NFOP_USER_CONFIG_PATH;

                      }
 

                    }

                }

            }
 

        }
 

        public virtual bool HasNextToken(int current_index, int tokensLength)

        {

            return current_index < tokensLength;

        }
 

        public virtual bool IsEmptyToken(string token)

        {

            return string.IsNullOrEmpty(token);

        }
 

        public virtual string PrepareToken(string token)

        {

            if (token != null)

            {

                return token.Trim().ToLower();

            }
 

            return token;

        }
 
 

        public System.Collections.Generic.Dictionary<string, string> Arguments

        {

            get { return _arguments; }

        }
 

        public virtual bool HasArguments

        {

            get

            {

                if (_arguments == null) return false;
 

                return _arguments.Count > 0;

            }

        }
 

        public bool IsValidToken(string key)

        {

            System.Collections.Generic.Dictionary<string, string> validArguments = GetValidArguments();
 

            return validArguments.ContainsKey(key);

        }
 

        protected virtual bool HasKeyAndValue(string key)

        {

            if (HasArguments)

            {

                if (_arguments.ContainsKey(key))

                {

                    return string.IsNullOrEmpty(_arguments[key]) == false;

                }

            }
 

            return false;

        }
 

        protected virtual string GetValue(string key)

        {

            if (HasKeyAndValue(key))

            {

                return _arguments[key];

            }
 

            throw new CommandLineArgumentException("error : command line argument", string.Format("command line parameter {0} is not set",key));

        }
 

        public bool HasUSERCONFIG

        {

            get

            {
 

                return string.IsNullOrEmpty(_USER_CONFIG_PARAM)==false;

            }

        }
 

        public bool HasFO

        {

            get

            {
 

                return HasKeyAndValue(FO_KEY);

            }

        }
 

        public bool HasXML

        {

            get

            {
 

                return HasKeyAndValue(XML_KEY);

            }

        }
 

        public bool HasXSL

        {

            get

            {
 

                return HasKeyAndValue(XSL_KEY);

            }

        }
 
 

        public bool HasPDF

        {

            get

            {
 

                return HasKeyAndValue(PDF_KEY);

            }

        }
 

        public bool HasFOOUT

        {

            get

            {
 

                return HasKeyAndValue(FOOUT_KEY);

            }

        }
 

        public string USERCONFIG

        {

            get

            {
 

                return _USER_CONFIG_PARAM;

            }

        }
 

        public string FO

        {

            get

            {
 

                return GetValue(FO_KEY);

            }

        }
 

        public string XML

        {

            get

            {
 

                return GetValue(XML_KEY);

            }

        }
 

        public string XSL

        {

            get

            {
 

                return GetValue(XSL_KEY);

            }

        }
 
 

        public string PDF

        {

            get

            {
 

                return GetValue(PDF_KEY);

            }

        }
 

        public string FOOUT

        {

            get

            {
 

                return GetValue(FOOUT_KEY);

            }

        }
 

        public override string ToString()

        {

            System.Text.StringBuilder output = new System.Text.StringBuilder();
 

            if (HasArguments)

            {

                if (this.HasUSERCONFIG)     output.AppendFormat("-c {0}{1}"     ,this.USERCONFIG, Environment.NewLine);

                if (this.HasFO)             output.AppendFormat("-fo {0}{1}"    ,this.FO        , Environment.NewLine);

                if (this.HasXML)            output.AppendFormat("-xml {0}{1}"   ,this.XML       , Environment.NewLine);

                if (this.HasXSL)            output.AppendFormat("-xsl {0}{1}"   ,this.XSL       , Environment.NewLine);

                if (this.HasFOOUT)          output.AppendFormat("-foout {0}{1}" ,this.FOOUT     , Environment.NewLine);

                if (this.HasPDF)            output.AppendFormat("-pdf {0}{1}"   ,this.PDF       , Environment.NewLine);

            }

            else

            {

                output.Append("no command line parameters.");

            }
 

            return output.ToString();

        }

    }

}

Open in new window

0
 
LVL 4

Expert Comment

by:Wardy_01
ID: 24374928
Ok ... Looking at that the logic in the switch is in fact wrong which won't help.
Dam dude ... this code is overkill on the wordyness.

its only a string of name value pairs, why not try something like this ...

NameValueCollection arguments = new NameValueCollection();

public void Parse(string cmdArgs)
{
        string [] tokens = cmdArgs.Split(' ');
       
        foreach(string token in tokens)
        {
               string [] tokenParts = token.Split('=');
               // remove the "-" on the argument name.
               arguments.Add(tokenParts[0].SubString(1), tokenParts[1]);
        }
}

.............

Instead of all this "HasThis" and "HasThat" try this ...

if( arguments["Config"] != null && GetArguments["pdf"] != null )
{
       // do stuff
}

......

Much less code and will probably compile to cleaner MSIL.
All that code can go in the class that calls up your current CommandLineArguments class and you'll have your args right there local so you can do your switch on "arguments.Count" in Program.cs

the whole switch statement relies on the UserConfig param so you should do this ...

if(arguments["UserConfig"] != null)
{
        switch(arguments.count)
            .... and so on
}

...........

No need for a custom collection class and I simplified your switch :)
I think you will find your apps less confusing if you use less wordy code and it might help you pin your problem down.
0
 
LVL 4

Accepted Solution

by:
Wardy_01 earned 500 total points
ID: 24374988
having looked at this some more it might be logically better if you nest a few if's instead of using the switch.

It seems to me that the switch isn't really a decision maker but more a way to group your if's.

I notice that half your ifs rely on "cmdLineArgs.HasXML" so you could do this to extend my previous example ...

if(arguments["UserConfig"] != null)
{
        // do stuff that only relies on userconfig param

        if(arguments["xml"] != null)
        {
                 // do stuff that uses both userconfig and xml params
        }
}
else
{
       // minimum param requirement not met
       throw new Exception("Not information provided to continue");
}
0
 

Author Comment

by:conceptdata
ID: 24376634
Okay I see what you mean.
But it dosn't solve my problem, that is the files arial.ttf / arial.xml don't have the right path, so the nfop.exe can't find them.

BUT in my visual studio, debugging the project, the files are found with normal paths
( example C:\database\arial.ttf and C:\database\arial.xml )
and the same if I publish the project to my Local IIS-server (Localhost), still with normal (Local) paths
0
 

Author Comment

by:conceptdata
ID: 24377887
I have tried a workaround :
UserConfig.xml :
               <font metrics-file="http://checkpoint.c5style.dk/Global_Fonts/code39.xml"
               embed-file="http://checkpoint.c5style.dk/Global_Fonts/code39.ttf" kerning="yes">
              <font-triplet name="code39" style="normal" weight="normal"/>
              </font>
--- This works at localhost. Result : PDF file with the right font
--- But at the webserver. Result : no pdf at all.

Then I changed userconfig.xml to :
               <font metrics-file="checkpoint.c5style.dk/Global_Fonts/code39.xml"
               embed-file="checkpoint.c5style.dk/Global_Fonts/code39.ttf" kerning="yes">
              <font-triplet name="code39" style="normal" weight="normal"/>
              </font>
--- This works at localhost. Result : PDF file withOUT the right font
--- But at the webserver. Result : PDF file withOUT the right font
0
 

Author Closing Comment

by:conceptdata
ID: 31580882
Hi again

I Found the error. Something about the font embedding.
You have helped med a lot Wardy_01, so the points is yours
0
 
LVL 4

Expert Comment

by:Wardy_01
ID: 24419491
Hmmm ... ok ....

Well at least you got there in the end that's the main thing.
I still think that code should be reshuffled a bit though, it looks heavy when it's really not that complex.

Good luck with it.
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Join & Write a Comment

When it comes to showing a 404 error page to your visitors, you do not want that generic page to show, and you especially do not want your hosting provider’s ad error page to show either. In this article, I will show you how to enable the custom 40…
When it comes to security, there are always trade-offs between security and convenience/ease of administration. This article examines some of the main pros and cons of using key authentication vs password authentication for hosting an SFTP server.
After creating this article (http://www.experts-exchange.com/articles/23699/Setup-Mikrotik-routers-with-OSPF.html), I decided to make a video (no audio) to show you how to configure the routers and run some trace routes and pings between the 7 sites…
After creating this article (http://www.experts-exchange.com/articles/23699/Setup-Mikrotik-routers-with-OSPF.html), I decided to make a video (no audio) to show you how to configure the routers and run some trace routes and pings between the 7 sites…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now