quarta-feira, 21 de maio de 2014

Error occurred in deployment step 'Add Solution': Error: Cannot add the specified assembly to the global assembly cache: XXX.dll

Este erro ocorre no VS (Visual Studio) ao tentarmos fazer Deploy.

Error occurred in deployment step 'Add Solution': Error: Cannot add the specified assembly to the global assembly cache: XXX.dll

Como resolver:

1) Vá ao GAC (C:\windows\assembly) e remova a DLL manualmente. [remove DLL manually from GAC]
2) Realize deploy novamente [do deploy again!]

Problema: TimerJob habilitado e rodando para todos os Web App do Server

Olá Amigos,

Hoje venho compartilhar uma boa dica com vocês.

Possuo um Timer Job super pesado e lento, ao verificar o histórico de execução dos job no CA (Central Administration > Job History ) percebi que o mesmo estava sendo executado para cada um dos WebApps (Web Applications) do server e é óbvio que este não era o comportamento que eu desejava.

A solução é bastante simples, existe uma propriedade na Feature de Ativação do Timer Job que é responsável pela ativação/vinculação automática do Timer Job a todos os WebApp, basta desativa-la e após vincula-la manualmente ao WebApp Correto.

Na imagem abaixo é possível visualizar a propriedade que deve ser alterada. Por default seu valor é True, devemos passar para False para que a Ativação fique em Manual.



Após fazer o deploy do projeto, basta voltar ao CA e Naveguar até "Gerenciar o Aplicativo Web" (Central Administration -> Application Management -> Manage Web Application)

Selecione seu Web Application e vá em "Gerenciar Recursos" (Manage Features)

Localize a feature de ativação do Timer Job e clique em "Ativar" (Activate)


Era isso ;)

Abraço,
Leonardo

Fontes:
http://www.codeproject.com/Tips/634208/Create-and-Deploy-Custom-Timer-Job-Definition-in-S

http://www.splessons.com/2013/12/create-a-timer-job-in-sharepoint-2013/#SPLessonPhoto[myGallery]/13/


segunda-feira, 19 de maio de 2014

Questão sobre SPDailySchedule e sua propriedade BeginHour

Olá PessoALL,

Hoje foi questionado sobre como "setar" a hora inicial de um SPDailySchedule para as 22 horas.

Para quem não sabe, o SPDailySchedule é utilizado, principalmente, para "setarmos" o horário de agendamento de um Timer Job.

Normalmente temos no código algo como isto:

            //Configura o Timer Job para rodar todos os dias de 1 hora da manhã.
            SPDailySchedule dailySchedule = new SPDailySchedule();
            dailySchedule.BeginHour = 01;
            dailySchedule.EndHour = 01;
            dailySchedule.EndMinute = 30;

 Então surge a dúvida, é 01 am ou 01pm...

A resposta é bem simples na verdade, a propriedade BeginHour é 24 horas, portanto se quisermos rodar o job as 22, basta "setar" o número 22 ;)


            //Configura o Timer Job para rodar todos os dias de 22 horas
            SPDailySchedule dailySchedule = new SPDailySchedule();
            dailySchedule.BeginHour = 22;
            dailySchedule.EndHour = 22;
            dailySchedule.EndMinute = 30;

Bem simples e indolor ;)

Abraço,
Leonardo

quinta-feira, 15 de maio de 2014

Tratando problemas de performance e logs gigantes

A apresentação do Link abaixo é muito interessante. 

Ótimo recurso para quem está enfrentando lentidão em WP customizadas em seu ambiente SharePoint. 

Entender a relação SPRequest e SPSite/SPWeb é a chave para esta jornada de otimização de webparts. 

Muito útil para quem tem erros do tipo:

 Potentially excessive number of SPRequest objects (XX) currently unreleased on thread X

http://pt.slideshare.net/kcponce/sharepoint-underground-unmanaged-code-and-sharepoint-internals

Outro link interessante para o mesmo problema é:

http://blog.meligo.be/2013/10/sprequest-things-i-couldnt-find-about-it/

Existe uma centena de outras dicas que te auxiliarão a cuidar deste caso, mas isto é assunto para outro momento.

Por hoje é só pessoal =D

quinta-feira, 27 de setembro de 2012

BCS : There are no addresses available for this application

Olá :)

Tive esse erro logo após criar o serviço do BCS

"There are no addresses available for this application"

Ainda bem que é de fácil solução :)

Basta iniciar o serviço "“Business Data Connectivity Service" dentro de Application Management > Manage Services on Server

Após IISRESET

Agradecimentos ao site[1]  gringo abaixo :)

[1]
http://nkelkar.wordpress.com/2011/06/16/bcs-there-are-no-addresses-available-for-this-application/

Como renomear o nome de um WebApplication (WebApp) (SharePoint 2010)

Como renomear um WebApp?

Bastante simples ;)

Execute seguinte comando via Power Shell =]

$a=Get-SPWebApplication | where {$_.Name -match "Antigo nome do web application"}

$a.Name

$a.Name="Novo nome do web application"

$a.Update()

Get-SPWebApplication | where {$_.Name -match "Novo nome do web application"}

sexta-feira, 23 de setembro de 2011

XSL Data por extenso. (Sharepoint)

Olá Amigos,

Importante dizer que o código abaixo, funcionará somente no Sharepoint.
Tanto versão 2007 quanto 2010.

Problema:
Formatar data no seguinte formato: "28 de Janeiro de 2011"

Solução:

<xsl:value-of select="ddwrt:FormatDateTime(string(@DataPublicacao),1046,'dd')"/>
de
<xsl:value-of select="ddwrt:FormatDateTime(string(@DataPublicacao),1046,'MMMM')"/>
de
<xsl:value-of select="ddwrt:FormatDateTime(string(@DataPublicacao),1046,'yyyy')"/>

quarta-feira, 31 de agosto de 2011

Erro "List not found" (lista inexistente) ao tentar exibir um DataFormWebPart importado de outro site

Olá amigos,

Estou migrando funcionalidades de um site para outro site dentro do mesmo site collection.

Precisava exibir o conteudo de uma lista que estava em outro site.

Tarefa simples de ser realizada utilizando a DataFormWebPart com o parametro
webUrl no seu datasource.

O Grande problema, que mesmo a lista existindo. O Sharepoint retornava a seguinte mensagem "Lista Inexistente" (list not found)

Para solucionar o problema simplesmente troca-se o atributo ViewFlag para "0"

WebPartPages:DataFormWebPart runat="server" IsIncluded="True" AsyncRefresh="True" FrameType="None" NoDefaultStyle="TRUE" ViewFlag="0"

Não me perguntem o porque. Sei que funciona :)

Encontrei essa pérola no seguinte site:

http://www.codepoint.es/archive/2011/07/12/error-de-“list-not-found”-para-un-dataformwebpart-exportado-a-otro-sitio.aspx

Abraços,
Maca

quinta-feira, 11 de agosto de 2011

Erro "Um arquivo especificado na seção de módulos deste modelo já existe."

Olá,

Ao tentar ativar uma feature, recebi o seguinte erro:

"Um arquivo especificado na seção de módulos deste modelo já existe."

Após instalar e reinstalar feature várias vezes. (minutos perdidos da minha vida)

Encontrei no o segguinte POST
http://lawo.wordpress.com/2010/09/11/file-specified-in-the-modules-section-of-this-template-already-exists/

Que descreve a solução :)

Basicamente, é necessário ir no arquivo Elements do seu modulo e trocar a propriedade "IgnoreIfAlreadyExists" para "true"

Abraço,
Maca


sexta-feira, 15 de julho de 2011

Como fazer deploy WSP (moss 2007) em um Sharepoint 2010 server

Olá Amigos,

Depois de 150 anos distante do blog resolvi postar novamente :)

Hoje me deparei com o seguinte problema:

Fazer deploy de um wsp (moss 2007) em um Sharepoint 2010.
Fui em busca do conhecimento (by Et Bilú) e descobri que é uma operação bastante simples.

No Visual Studio 2010, sigam os seguintes passos:
1) Crie um Novo Projeto;
2) Selecione Import SharePoint Solution Package (dentro da aba Sharepoint)
3) Nomeie seu Projeto
4) Escolha a Farm Solution
5) Faça Upload do seu WSP
6) Troque o nome da Feature para o nome da antiga Feature (feature do wsp)
7) Build
8) Deploy
9) Teste

Facílimo!

Até a próxima.

quarta-feira, 25 de março de 2009

Fazer Download de documentos do Sharepoint 2003 usando WS nativos e sem usar OM

Olá Amigos,

Abaixo um pequeno código, que demotra como podemos baixar documentos de uma document library do SharePoint 2003.



public void DownloadFilesFromDocumentLibrary(string url, string documentLibraryName){
Lists.Lists proxy = new Lists.Lists();//set url and credentials on proxy
proxy.Url = url + "_vti_bin/lists.asmx";
proxy.Credentials = CredentialCache.DefaultCredentials;//call get list items to retrieve document library
XmlNode elm = proxy.GetListItems(documentLibraryName, null, null, null, null, null);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(elm.OwnerDocument.NameTable);
nsMgr.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
nsMgr.AddNamespace("z", "#RowsetSchema");
if (elm != null){
XmlNode dataNode = elm.SelectSingleNode("rs:data", nsMgr);
int itemCount = Convert.ToInt32(dataNode.Attributes.GetNamedItem("ItemCount").Value);
if (itemCount == 0){
Console.WriteLine("Nothing to download");
}else{
foreach (XmlNode row in dataNode.SelectNodes("z:row", nsMgr))
{
//Response.Write(row.Attributes.GetNamedItem("ows_LinkFilename").Value+"
");
DownLoadFile(url, documentLibraryName, row.Attributes.GetNamedItem("ows_LinkFilename").Value);
}
}
}
}



public void DownLoadFile(string url, string documentLibraryName, string fileName){
//string downloadPage = url + "/download.aspx";
HttpWebRequest request = null;
HttpWebResponse response = null;
Stream responseStream = null;
FileStream fs = null;
try{
//request = (HttpWebRequest) HttpWebRequest.Create(downloadPage + "?SourceUrl=" + documentLibraryName + "/" + fileName);
request = (HttpWebRequest)HttpWebRequest.Create(SharePointHost + documentLibraryName + "/" + fileName);
request.Credentials = CredentialCache.DefaultCredentials;
request.Timeout = 6000;
response = (HttpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();//write to filesystem
fs = new FileStream(fileName, FileMode.Create);
byte[] buffer = new byte[1024];
int count = responseStream.Read(buffer, 0, buffer.Length);
while (count > 0)
{
fs.Write(buffer, 0, buffer.Length);
count = responseStream.Read(buffer, 0, buffer.Length);
}
}
finally{
if(fs != null)
fs.Close();
if(responseStream != null)
responseStream.Close();
if(response!=null)
response.Close();
}
}

sexta-feira, 12 de dezembro de 2008

FormatDateTime - Mostrar hora no formato 24 horas

Olá Amigos,

Dica idiota, mas me custou alguns minutos da minha vida =]

Eu estava usando o código, para formatar a hora no formato 12 horas

<xsl:value-of select="ddwrt:FormatDateTime(string(@EventDate) ,1046,'hh:mm')" />

Precisava mostrar no formato 24 horas, para isso, foi só trocar a mascara de 'hh:mm' p/ 'HH:mm'

<xsl:value-of select="ddwrt:FormatDateTime(string(@EventDate) ,1046,'HH:mm')" />

Abraços,
Leonardo

sexta-feira, 22 de agosto de 2008

Lendo dados de uma View (SPView) (Exibição)

Olá PessoALL,

Faz tempão que não posto e ainda por cima vou aparecer hoje por aqui para dar uma dicazinha bem simples =]

Criar views (exibições) em listas do SharePoint é uma tarefa muito simples e bem poderosa. Conseguimos fazer diversas funcionalidades (agrupamento, ordenação, limitar itens) usando apenas o mouse.

Então por que ao criarmos uma WebPart precisamos fazer tudo de novo? Na verdade não precisamos ^^
Podemos ler itens diretamente de uma View (Exibição)

Bem, chega de chalálá e vamos ao código:

SPListItemCollection coll = spWeb.Lists["ListName"].GetItems(spWebInstance.Lists["ListName"].Views["ViewName"]);

Toda malandragem envolvida neste código, está em passar a view por parâmetro para o método GetItems, se não pudéssemos fazer isso, seria necessário escrever um baita CAML para alcançar as funcionalidades (agrupamento, ordenação, limitar itens) desejadas

Maca espera ter sido útil =]

Abraços,
Leonardo Macanudo

terça-feira, 27 de maio de 2008

Collection was modified; enumeration operation may not execute

Olá Amigos,

Tenho duas listas relacionadas (tópicos,respostas), preciso remover todas as respostas relacionadas a um determinado tópico.

O primeiro código que vem a cabeça é fazer um for each e deletar item por item.

Como no exemplo abaixo:

SPQuery q = new SPQuery();
q.Query = "<Where><Eq><FieldRef Name='Topico' /><Value Type='Lookup'>" + sTopico + "</Value></Eq></Where>";

SPList listRespostas = SPContext.Current.Web.Lists["Respostas"];
SPListItemCollection itensTopicos = listRespostas.GetItems(q);

foreach (SPListItem itemResposta in itensTopicosFake)
{
itemResposta.Delete();
}

Porém quando executamos este código, nos deparamos com o seguinte erro.

Collection was modified; enumeration operation may not execute

Este erro acontece porque a collection que eu estou usando no for each, está sendo modificada dentro dele mesmo.

Para resolver este problema substitui o for each pelo while abaixo.

while (itensTopicos.Count > 0)
itensTopicos[0].Delete();

Abraços,
Leonardo

sexta-feira, 23 de maio de 2008

SharePoint Data View Permissão de Usuários

Olá Amigos,

Para verificar o nível de permissão de um usuário quando estamos dentro de um XSL, devemos utilizar a função "ddwrt:IfHasRights(codigoDaPermissao)".

Exemplo (Exclusão de itens):

<xsl:if test="ddwrt:IfHasRights(8)">
...
</xsl:if>

Abaixo as permissões e seus respectivos "códigos"

ViewListItems - 1
AddListItems - 2
EditListItems - 4
DeleteListItems - 8
ApproveItems - 16
OpenItems - 32
ViewVersions - 64
DeleteVersions - 128
CancelCheckout - 256
PersonalViews - 512
ManageLists - 2048
ViewFormPages - 4096
Open - 65536
ViewPages - 131072
AddAndCustomizePages - 262144
ApplyThemeAndBorder - 524288
ApplyStyleSheets - 1048576
ViewUsageData - 2097152
CreateSSCSite - 4194314
ManageSubwebs - 8388608
CreateGroups - 16777216
ManagePermissions - 33554432
BrowseDirectories - 67108864
BrowseUserInfo - 134217728
AddDelPrivateWebParts - 268435456
UpdatePersonalWebParts - 536870912
ManageWeb - 1073741824
UseRemoteAPIs - 137438953472
ManageAlerts - 274877906944
CreateAlerts - 549755813888
EditMyUserInfo - 1099511627776
EnumeratePermissions - 4611686018427387904
FullMask - 9223372036854775807

É um script curto, porém esta função ainda vai salvar sua vida.

Abraços,
Leonardo

segunda-feira, 19 de maio de 2008

XSL formatar data no formato DD/MM

Olá Amigos,

Corrigindo este POST =]

Abaixo vocês vão ver toda uma choradeira de minha parte e uma baita gambiarra.
Porém existe um forma elegante sim de resolver este problema.

É essa:

<xsl:value-of select="ddwrt:FormatDateTime(string(@Data),1046,'dd/MM')"/>

Abaixo uma pequena gambiarra criada por mim para exibir a data no formato DD/MM, tive que fazer isto, pois a função nativa do SharePoint (ddwrt:FormatDate) não oferece este formato.

Abraços,
Leonardo

<xsl:choose>
<xsl:when test="number(substring-before(@_DCDateCreated,'/')) <= 9">0<xsl:value-of select="substring-before(@_DCDateCreated,'/')"/></xsl:when>
<xsl:otherwise><xsl:value-of select="substring-before(@_DCDateCreated,'/')"/></xsl:otherwise>
</xsl:choose>
/
<xsl:choose>
<xsl:when test="number(substring-before(substring-after(@_DCDateCreated,'/'),'/')) <= 9">0<xsl:value-of select="substring-before(substring-after(@_DCDateCreated,'/'),'/')"/></xsl:when>
<xsl:otherwise><xsl:value-of select="substring-before(substring-after(@_DCDateCreated,'/'),'/')"/></xsl:otherwise>
</xsl:choose>

quinta-feira, 15 de maio de 2008

Evitar os cabelos brancos gerados CAML

Olá Amigos,


No link abaixo vocês vão encontrar um aplicativo que torna visual a criação das querys caml.

http://www.u2u.info/SharePoint/U2U%20Community%20Tools/Forms/AllItems.aspx


Abraços,
Maca

quinta-feira, 10 de abril de 2008

Sharepoint User Profile

Quando vamos criar um projeto com autenticação forms no MOSS sempre nos vem a pergunta, Onde vamos guardar as informações dos usuários? Em lista, em Banco, no próprio membership onde?
A resposta para essa pergunta é n.d.a =]
O jeito correto de guardar usuários é o User Profile, com ele é possível administrar usuários em um lugar único, ou seja, várias web app podem compartilhar os mesmos usuários.
O User Profile já vem com diversos campos por default e também possibilita a criação de novos campos tanto via interface, quanto via Object Model. O namespace responsável por manipular o User Profile é Microsoft.Office.Server.UserProfiles.

Criando usuários:
try{
using (SPSite spSite = new SPSite(@"http://localhost")){
ServerContext siteContext = ServerContext.GetContext(spSite);
UserProfileManager pmManager = new UserProfileManager(siteContext);
Console.WriteLine("Number of users: " + pmManager.Count);
string strUserName = "macanudocorporation\\admin";
UserProfile newUser = null;
if (!pmManager.UserExists(strUserName))
{
newUser = pmManager.CreateUserProfile(strUserName);
}
}
}catch (Exception exp){
Console.WriteLine(exp.Message);
}

Editando Usuários

try{
using (SPSite spSite = new SPSite(@"http://localhost")){
ServerContext siteContext = ServerContext.GetContext(spSite);
UserProfileManager pmManager = new UserProfileManager(siteContext);
Console.WriteLine("Number of users: " + pmManager.Count);
string strUserName = "macanudocorporation\\admin";
UserProfile newUser = null;
if (!pmManager.UserExists(strUserName))
{
user = pmManager.GetUserProfile(strUserName);
}
}
}catch (Exception exp){
Console.WriteLine(exp.Message);
}


Deletando usuários

try{
using (SPSite spSite = new SPSite(@"http://localhost"))
{
ServerContext siteContext = ServerContext.GetContext(spSite);
UserProfileManager pmManager = new UserProfileManager(siteContext);
Console.WriteLine("Number of users: " + pmManager.Count);
string strUserName = "macanudocorporation\\admin";
if (pmManager.UserExists(strUserName))
{
pmManager.RemoveUserProfile(strUserName);
}
}
}catch (Exception exp){
Console.WriteLine(exp.Message);
}

Por hora é isso!


Abraços,
Maca

quinta-feira, 13 de março de 2008

CALLSTACK, CUSTOMERRORS & DEBUG MODE

Olá Amigos,

Hoje vou postar uma importante dica =]
Encontrei essa pérola no blog[1] do Hélio Sá Moreira.

As vezes (rs) obtemos mensagens de erro nada informativas ou claras durante a utilização (ou tentativa de utilização) de alguns recursos do Sharepoint. Um caso clássico, que obtive em um ambiente que trabalhei esta semana, foi: Unknown Error Occurred OU An unspecified error has occured.

Para desativa-las temos que executar o seguinte procedimento =]

São basicamente 3 itens de configuração - que podem ser utilizados em conjunto ou separadamente para um processo de troubleshoot detalhado.

01 - CUSTOMERRORS

Essa configuração - que por padrão apresenta o valor "ON" - redireciona o tratamento de erros para um módulo de tratamento de erros do Sharepoint. Este módulo é muito importante, mas quando o mesmo não consegue classificar o erro as mensagens 'genéricas' são apresentadas.

Para desabilitar este redirecionamento - retornando ao modelo padrão do ASP.Net 2.0 - podemos mudar o valor desta configuração para "OFF".

No Web.Config, essa configuração pode ser encontrada no seguinte path: Configuration \ System.web \ CustomErrors.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
...
<system.web>
...
<customerrors mode="On">
...

Com isso, voltamos as telas de erro do ASP.Net! Vale lembrar que esta configuração deve ser realizada somente no processo de verificação de um erro - e o seu valor padrão deve ser re-configurado para que mensagens informativas aos usuários possam ser apresentadas de uma forma gerenciável e "não-agressiva"!

Esta mudança já deve ajudar bastante na identificação das possíveis razões do problema ....


02 - CALLSTACK

Esta configuração é relacionada ao nível de informações e detalhes apresentados sob o erro quando o mesmo ocorre. Voltando ao cenário de troubleshoot, quando mais informações relacionadas ao problema melhor - incluindo inclusive todos os métodos envolvidos e a hierarquia de execução! ;-)

Por padrão esta configuração possui o valor "FALSE" - e pode ser encontrada na seguinte estrutura: Configuration \ SharePoint \ SafeMode. Para habilitar este modo, devemos configurar o CallStack com o valor "TRUE".


<configuration>
...
<sharepoint>
<safemode callstack="false">
...

Esta configuração é relacionada ao nível de informações e detalhes apresentados sob o erro quando o mesmo ocorre. Voltando ao cenário.


02 - DEBUG MODE

Este item esta relacionado ao modelo de compilação utilizado pelo .Net Framework 2.0 (JIT - Just-in-time compilation). O valor padrão para o DEBUG é false. Mas, em um cenário de Troubleshoot o DEBUG="TRUE" aumenta o nível de detalhamento das informações repassadas ao Stack Trace e consequentemente aumenta as informações repassadas às nossas telas de erro!

Este item pode ser encontrado na seguinte estrutura: Configuration \ System.Web \ Compilation.



<configuration>
...
<system.web>
...
<compilation debug="false" batch="false">
...

Abraços,
Maca

blog
[1] http://www.sharepointbrasil.net/default.aspx

sexta-feira, 22 de fevereiro de 2008

Listar Arquivos da Lixeira (AdminRecycleBin e RecycleBin)

Olá Amigos,

Nos últimos dias me reparei com o seguinte problema, como fazer um relatório de páginas excluída de uma biblioteca de páginas Wiki.
Após refletir um pouco sobre o assunto, me veio o estalo, Ler da Lixeira do site.

Como fazer isso?

Dentro do SPSite e SPWeb existe uma propriedade RecycleBin, esta propriedade retorna uma collection (SPRecycleBinItemCollection) com os itens (SPRecycleBinItem) da lixeira os itens.
Após saber disso, acabaram-se as dificuldades. Só precisei fazer um foreach e verificar a propriedade ” DirName” está prorpriedade do SPRecycleBinItem contém o nome do local original do arquivo excluído.

Importante:

O SPSite.RecycleBin guarda a lixeira do site collection, está lixeira tem todos os arquivos excluídos no site collection independente do usuário.

O SPWeb.RecycleBin guarda a lixeira do site atual e lista apenas os arquivos excluídos pelo usuário do contexto.

Code:

SPSite site = SPContext.Current.Site;
foreach (SPRecycleBinItem itemGarbage in site.RecycleBin)
{
if (itemGarbage.DirName == "Paginas Wiki")
{
Response.Write(itemGarbage.Title);
Response.Write(itemGarbage.DeletedDate.ToString("dd/MM/yyyy"));
Response.Write(itemGarbage.DeletedBy);
}
}

Abraços,
Maca