怎样查看网站开发语言,衡阳关键词优化首选,崂山区城乡建设局网站,百度网站开发合同范本一. 应用场景开发一个课件在线学习功能#xff0c;要求将WORD, EXCEL, PPT类型课件可在线打开学习#xff1b;最初设想使用第三方office插件#xff0c;无奈价格太高放弃使用#xff1b;我们最终的方案是#xff1a;利用office自身的另存为功能#xff0c;在服务器将上传…一. 应用场景开发一个课件在线学习功能要求将WORD, EXCEL, PPT类型课件可在线打开学习最初设想使用第三方office插件无奈价格太高放弃使用我们最终的方案是利用office自身的另存为功能在服务器将上传的office文件转化为pdf格式然后网页打开pdf文件实现在线学习功能项目实现方案新建一个windows自启的service安装在服务器这个服务里面会建立一个HttpListener用于监听文件转换的请求请求来了后交给ServiceHandle处理ServiceHandle会调用ConvertHelper把指定目录下的office文件转化为pdf并放在相同目录下以供在线学习使用二. 工具及环境VS2019Office本地开发2016版服务器2010版开发环境 win10服务器环境 windows server 2012 R2VS开发使用到的nuget包NetOffice三. 创建windows server项目基本按照这个思路开发出一个基础service完全没问题这里需要提醒下的是项目的文件路径不要带有空格否则在执行bat批处理操作时会出现问题。四. 使用NetOffice实现文件转换上面只是创建一个服务 真正转换的核心功能还没开始这时我们需要利用NetOffice插件项目目录image.png利用nuget包管理器安装所需包这是项目的packages.config文件转换核心代码ConvertHelper.cspublic class ConvertHelper{public static void ConvetToPdf(string sourcePath, string targetPath){if (!File.Exists(sourcePath)){throw new Exception(string.Format(文件{0}不存在, sourcePath));}if (File.Exists(targetPath)){throw new Exception(string.Format(目标文件{0}已存在, targetPath));}LogHelper.Info(开始转换: Path.GetFileName(sourcePath));var targetDirectory Path.GetDirectoryName(targetPath);if (!Directory.Exists(targetDirectory)){Directory.CreateDirectory(targetDirectory);}var ext Path.GetExtension(sourcePath).ToLower();if (ext .ppt || ext .pptx){ConvertPptToPdf(sourcePath, targetPath);}else if (ext .doc || ext .docx){ConvertDocumentToPdf(sourcePath, targetPath);}else if (ext .xls || ext .xlsx){ConvertExcelToPdf(sourcePath, targetPath);}else{LogHelper.Info({0}不支持转换pdf, sourcePath);return;}if (File.Exists(targetPath)){LogHelper.Info(转换成功: Path.GetFileName(sourcePath));}else{LogHelper.Info(转换失败: Path.GetFileName(sourcePath));}}/// /// 转换ppt文件到pdf文件(不支持超时终止)/// /// /// private static void ConvertPptToPdf(string sourcePath, string targetPath){NetOffice.PowerPointApi.Application application null;NetOffice.PowerPointApi.Presentation presentation null;var cts new CancellationTokenSource();var thread new Thread(() {try{application new NetOffice.PowerPointApi.Application();presentation application.Presentations.Open(sourcePath, true, NetOffice.OfficeApi.Enums.MsoTriState.msoTrue, false);presentation.SaveCopyAs(targetPath, NetOffice.PowerPointApi.Enums.PpSaveAsFileType.ppSaveAsPDF);}catch (Exception ex){if (ex.InnerException ! null ex.InnerException is ThreadAbortException){LogHelper.Info(ConvertPptToPdf: {0}操作超时, Path.GetFileName(sourcePath));}else{LogHelper.Error(ex, ConvertPptToPdf: {0}出现异常, Path.GetFileName(sourcePath));}}finally{if (presentation ! null){presentation.Close();presentation null;}if (application ! null){application.Quit();application.Dispose();application null;}//killProccess(POWERPNT);}});cts.Token.Register(() {thread.Abort();});cts.CancelAfter(Program.MaxThreads * 1000);thread.Start();thread.Join();GC.Collect();GC.WaitForPendingFinalizers();}/// /// 转换word文件到pdf文件(支持超时终止)/// /// /// private static void ConvertDocumentToPdf(string sourcePath, string targetPath){NetOffice.WordApi.Application application null;NetOffice.WordApi.Document document null;var cts new CancellationTokenSource();var thread new Thread(() {try{application new NetOffice.WordApi.Application();document application.Documents.Open(sourcePath);document.ExportAsFixedFormat(targetPath, NetOffice.WordApi.Enums.WdExportFormat.wdExportFormatPDF);}catch (Exception ex){if (ex.InnerException ! null ex.InnerException is ThreadAbortException){LogHelper.Info(ConvertDocumentToPdf: {0}操作超时, Path.GetFileName(sourcePath));}else{LogHelper.Error(ex, ConvertDocumentToPdf: {0}出现异常, Path.GetFileName(sourcePath));}}finally{if (document ! null){document.Close();document null;}if (application ! null){application.Quit();application.Dispose();application null;}//killProccess(WINWORD);}});cts.Token.Register(() {thread.Abort();});cts.CancelAfter(Program.MaxThreads * 1000);thread.Start();thread.Join();GC.Collect();GC.WaitForPendingFinalizers();}private static void ConvertExcelToPdf(string sourcePath, string targetPath){NetOffice.ExcelApi.Application application null;NetOffice.ExcelApi.Workbook wookbook null;var cts new CancellationTokenSource();var thread new Thread(() {try{application new NetOffice.ExcelApi.Application();wookbook application.Workbooks.Open(sourcePath);wookbook.ExportAsFixedFormat(NetOffice.ExcelApi.Enums.XlFixedFormatType.xlTypePDF, targetPath);}catch (Exception ex){if (ex.InnerException ! null ex.InnerException is ThreadAbortException){LogHelper.Info(ConvertExcelToPdf: {0}操作超时, Path.GetFileName(sourcePath));}else{LogHelper.Error(ex, ConvertExcelToPdf: {0}出现异常, Path.GetFileName(sourcePath));}}finally{if (wookbook ! null){wookbook.Close();wookbook null;}if (application ! null){application.Quit();application.Dispose();application null;}//killProccess(EXCEL);}});cts.Token.Register(() {thread.Abort();});cts.CancelAfter(Program.MaxThreads * 1000);thread.Start();thread.Join();GC.Collect();GC.WaitForPendingFinalizers();}public static void CleanProccess(){LogHelper.Info(CleanProccess Start);killProccess(WINWORD);killProccess(EXCEL);LogHelper.Info(CleanProccess Finish);}private static void killProccess(string appName){// Store all running process in the systemProcess[] runingProcess Process.GetProcesses();for (int i 0; i runingProcess.Length; i){// compare equivalent process by their nameif (string.Equals(runingProcess[i].ProcessName, appName, StringComparison.OrdinalIgnoreCase)){try{// kill running processruningProcess[i].Kill();LogHelper.Info(Kill {0} [{1}], appName, runingProcess[i].Id);}catch (Exception ex){if (ex is System.InvalidOperationException){//进程已经关闭}else{LogHelper.Error(ex, Kill {0} [{1}] Error, appName, runingProcess[i].Id);}}}}}}ServiceListener监听http请求端口号默认8091public ServiceListener(){_stop new ManualResetEvent(false);_idle new ManualResetEvent(false);_busy new Semaphore(Program.MaxThreads, Program.MaxThreads);_listener new HttpListener();_listenerThread new Thread(HandleRequests);}public void Start(){var url String.Format(http://localhost:{0}/, Program.ListenerPort); // Port8091LogHelper.Info(Listenning Start: url);_listener.Prefixes.Add(url);_listener.Start();_listenerThread.Start();}五. 系统调用http服务转换文件public void ConvertToPdf(string serviceUrl, string sourcePath, string pdfPath){var url ${serviceUrl}?srcPath{sourcePath}tarPath{pdfPath};using (var webClient new WebClient()){var result webClient.DownloadString(url);}}至此开发完毕本地开发完成六. 本地测试功能注册服务执行注册服务.bat启动服务执行启动服务.bat查看服务运行情况image.png但是测试转换时遇到了问题日志错误为 Office 检测到该文件有问题。为帮助保护您的计算机此文件无法打开。2020-05-02 09:04:22:248 Info [Thread9] 开始转换:a10a54166224453abdd8d4b809f15449.ppt2020-05-02 09:04:25:379 Exception [Thread10] ConvertPptToPdf: a10a54166224453abdd8d4b809f15449.ppt出现异常 Exception:System.Runtime.InteropServices.COMException (0x80004005): See inner exception(s) for details. --- System.Reflection.TargetInvocationException: 调用的目标发生了异常。 --- System.Runtime.InteropServices.COMException: Presentations.Open : Office 检测到该文件有问题。为帮助保护您的计算机此文件无法打开。--- 内部异常堆栈跟踪的结尾 ---在 System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)在 System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)在 NetOffice.Invoker.MethodReturn(COMObject comObject, String name, Object[] paramsArray)在 NetOffice.Invoker.MethodReturn(COMObject comObject, String name, Object[] paramsArray)在 NetOffice.PowerPointApi.Presentations.Open(String fileName, Object readOnly, Object untitled, Object withWindow)在 LMS.DocumentConvertService.ConvertHelper.LMS.DocumentConvertService\Service\ConvertHelper.cs:行号 752020-05-02 09:04:33:477 Info [Thread9] 转换失败:a10a54166224453abdd8d4b809f15449.ppt我才用了其中2种较简单解决方案修改代码在ProjectInstaller.cs中ProjectInstaller类中重载OnAfterInstall[RunInstaller(true)]public partial class ProjectInstaller : System.Configuration.Install.Installer{public ProjectInstaller(){InitializeComponent();}protected override void OnAfterInstall(IDictionary savedState){try{base.OnAfterInstall(savedState);System.Management.ManagementObject myService new System.Management.ManagementObject(string.Format(Win32_Service.Name{0}, this.serviceInstaller1.ServiceName));System.Management.ManagementBaseObject changeMethod myService.GetMethodParameters(Change);changeMethod[DesktopInteract] true;System.Management.ManagementBaseObject OutParam myService.InvokeMethod(Change, changeMethod, null);}catch (Exception){}}}SC程序修改 允许与桌面进行交互用批处理的方式实现加入如下命令到启动服务.bat文件中sc config MonitorService typeinteract typeown至此本地开发环境转换服务成功运行。接下来准备上服务器